Repository: potassco/clinguin (language: python)

Issue:
Pt v4 clingraph
- Clingraph integration now working differently: Iterating trough graphs was not something we need, instead I added all arguments of clingraph in the command line and the image is now a path so is general 
- Chenged the log a little bit to show colors and nicer read
- I had to change the way things are imported otherwise it was not running on my computer
- I created a general temporal control and updated the elevator
- Unified everything to backed instead of solver
- Changed the argparse: We had an issue since multiple backends defined the same argument: now it shows only the names of the avaliable backends next to the `--backend` argument and only the help of the selected one
- The custom classes is now a single path for both server and client, we can allow multiple paths but there is no need to make the difference since it is also the same for us
- Added a clingraph integration example


Discussion / hints:

Fix patch:
diff --git a/Makefile b/Makefile
index 5baa5ca4..9fde8cc1 100644
--- a/Makefile
+++ b/Makefile
@@ -11,9 +11,6 @@ clean:
 	pip uninstall $(APPLICATION_NAME) -y
 
 format:
-	autopep8 start.py
-	autopep8 clinguin
-	pylint start.py
 	pylint clinguin
 
 
diff --git a/README.md b/README.md
index 65742362..d0629a0f 100644
--- a/README.md
+++ b/README.md
@@ -1,34 +1,46 @@
 # Clinguin :penguin: 
 
-Simple-Client-Server-Prototype
-
-As the name suggests, this program is a prototype for Clinguin (an interactive-user-interface for Clingo). The program basically works as follows (for a full description see the corresponding development diary (`/project-document`): 
-
-- Server:
-    - Architecture wise, the server has a pretty standard layered-architecture
-        - Presentation: Here the endpoints are located 
-        - Application: Here the solver(s) is/are located
-        - Data: Just the Data-Access-Objetcs (DAOs) for ClingoORM (CLORM)
-    - Presentation: The server is basically a REST-server with two endpoints:
-        - /health (GET) -> To check if the server is up and running
-        - / (POST) -> Is a ''solver-function-caller'', e.g. if there exists a function ''f:X->Y'', then one may call it with argument ''1'' by passing a json string: `{ ''function'' : ''f(1)'' }`.
+Clinguin is a graphical-user-interface for Clingo, where one can specify the user-interface entirely in a logic-program. One might wonder how one can do this by him-/herself - for this see the descriptions below and have fun :-)
 
 ## Install
 
+Preliminaries:
 - Python (version 3.8, 3.9, or 3.10)
 
+Now clone the repository, and move to the repository. In the repo you should see a `setup.py` file. Now execute the following command:
 
 ```
-pip install . -e
+python setup.py install
 ```
 
-## Syntax
+Now `STAY` in this directory, as currently (see issue #61 on GitHub) there is a bug, where one can only execute clinguin from this location.
+
+## The first example
+
+After the installation, executing the first example is quite straightforward, just copy-paste the following command into your commandprompt:
+
+`clinguin client-server examples/sudoku/instance.lp examples/sudoku/encoding.lp examples/sudoku/widgets.lp`
+
+After you hit enter, a Sudoku-game should open, which you can play - have fun :-)
 
-See the `/syntax_discussion/20220714_alex_syntax.lp` file.
+## Next Steps
 
-## Starting:
+Next steps - now it is time for you to try out some stuff yourself. In the folder(s) `exapmles` you find some smaller and some bigger example programs, which you can take as a first stepping stone for building your own Clingo-Gui.
 
-There are two start-possibilities:
+### Syntax
+
+For the development it is useful to know which elements, attribute-keys and -values are available. For this you can hit: `clinguin client --gui-syntax` for an overview and `clinguin client --gui-syntax-full` for a detailed list and description of the available widgets.
+
+### Help
+
+Clinguin is divided into three different sub-programs: Client, Server and Client-Server. One can access the help section of each one of those individually, i.e.:
+- `clinguin client -h`
+- `clinguin server -h`
+- `clinguin client-server -h`
+
+## Starting/Installation-2:
+
+The following section provides more details about installation and execution, in general there are two start-possibilities:
 1. Package-Version
 2. Development-Version
 
@@ -49,24 +61,33 @@ After the installation a package with the name `clinguin` should have been insta
 
 #### Standard-Start
 
-`$ clinguin client-server [--custom-classes=folder-path] [--solver=solver] logic-program [... logic-program]`
+See `$ clinguin client-server -h`
+
+`$ clinguin client-server [--custom-server-classes=folder-path] [--custom-client-classes=folder-path] [--solver=solver] [--client=client] logic-program [... logic-program]`
 
-- custom-classes: Specify the folder, where the solver(s) are located.
-- solver: Specify the solver, which must be in the folder where custom-classes points to.
+- custom-client/server-classes: Specify the folder, where the solver(s) are located.
+- solver/client: Specify the solver/client, which must be in the folder (or subfolder) where custom-classes points to - Pro-Tip: See which solvers/clients are available by typing: `clinguin client-server -h`
+- 
 
 E.g. for the sudoku example: `$ clinguin client-server examples/sudoku/instance.lp examples/sudoku/encoding.lp examples/sudoku/widgets.lp`
 
-Or to specify the solver: `$ clinguin client-server --custom-classes='./clinguin/server/application/default_solvers' --solver=ClingoBackend examples/sudoku/instance.lp examples/sudoku/encoding.lp examples/sudoku/widgets.lp`
+Or to specify the solver: `$ clinguin client-server --custom-server-classes='./clinguin/server/application/default_backends' --solver=ClingoBackend examples/sudoku/instance.lp examples/sudoku/encoding.lp examples/sudoku/widgets.lp`
 
 #### Only Server 
 
-`$ clinguin server [--solver=solver] logic-program [... logic-program]`
+See `$ clinguin server -h`
+
+`$ clinguin server  [--custom-server-classes=folder-path] [--solver=solver] logic-program [... logic-program]`
+
 
 E.g. for the sudoku example: `$ clinguin server examples/sudoku/instance.lp examples/sudoku/encoding.lp examples/sudoku/widgets.lp`
 
 #### Only Client
 
-`$ clinguin client`
+See `$ clinguin client -h`
+
+`$ clinguin client [--custom-client-classes=folder-path] [--client=client] `
+
 
 #### Shutting down
 
@@ -76,43 +97,48 @@ Even though it is not the most ellegant way (and it will throw errors at you, so
 
 #### Standard-Start
 
+See `$ python start.py client-server -h`
+
 `$ python start.py client-server [--custom-classes=folder-path] [--solver=solver] logic-program [... logic-program]`
 
 E.g. for the sudoku example: `$ python start.py examples/sudoku/instance.lp examples/sudoku/encoding.lp examples/sudoku/widgets.lp`
 
-Or to specify the solver: `$ python start.py client-server --custom-classes='./clinguin/server/application/default_solvers' --solver=ClingoBackend examples/sudoku/instance.lp examples/sudoku/encoding.lp examples/sudoku/widgets.lp`
+Or to specify the solver: `$ python start.py client-server --custom-classes='./clinguin/server/application/default_backends' --solver=ClingoBackend examples/sudoku/instance.lp examples/sudoku/encoding.lp examples/sudoku/widgets.lp`
 
 #### Only Server
 
+See `$ python start.py server -h`
+
 `$ python start.py server [--solver=solver] logic-program [... logic-program]`
 
 E.g. for the sudoku example: `$ python start_server.py examples/sudoku/instance.lp examples/sudoku/encoding.lp examples/sudoku/widgets.lp`
 
 #### Only Client
 
+See `$ python start.py client -h`
+
 `$ python start.py client`
 
 #### Shutting down
 
-Even though it is not the most ellegant way (and it will throw errors at you, so better hide), just `Ctr-C`.
+Do the following for:
+- `client` and `client-server`: Close at FIRST the GUI-Window and then press `Ctrl-C`
+- `server`: Just press `Ctrl-C`
 
 ## Dependencies:
 
 All dependencies can be installed via `python setup.py install` 
 
-
 ## Implementation of own Solver
 
 Preliminary 1: This section will be expanded in the future.
 
-Preliminary 2: Standard behavior: The standard behavior is to load the solver in the package `server.application.standard_solver.StandardSolver`. This solver will get instanciated by default, therefore when one wants to specify another solver, one needs to add the `--solver` argument-option and then specify the package where the solver is located.
+Preliminary 2: Standard/Default behavior: The standard behavior is to load the solver in the package `server.application.clingo_backend.StandardSolver`. This solver will get instanciated by default, therefore when one wants to specify another solver, one needs to add the `--solver` argument-option and then specify the package where the solver is located.
 
 Implementation: For the implementation of one's own solver, one basically has free hands in terms of syntactic definitions of the class, except two (or three) things:
-1. The `__init__()` method takes an argument `logic_programs` which is a list of string-paths to the logic programs (the existance of the files has been checked by now, but not the content).
+1. The `__init__()` method takes an argument `args` which are the command-line arguments (see `clinguin/server/application/default_backends/clingo_backend.py`) 
 2. When a method needs to return something to the client/User-Interface (UI) the method must return a **Json-convertible-class-hierarchy**. If one uses the standard-UI it is highly recommended to use the `ElementDto`, `AttributeDto` and `CallbackDto` classes to save the class hierarchy, otherwise one needs to at least implement the functionality of the `ElementDto` class and further provide a `root` element (initialized with the default `ElementDto` by `ElementDto('root', 'root', 'root')`). 
-3. If one uses the **standard-UI** then one needs to provide a `solve()` method in the solver. This method takes no argument and returns a json-convertible class hierarchy. This is needed, as the solve() method is initially invoked by the UI.
-
-
+3. One needs to provide a `get()` method in the solver. This method takes no argument and returns a json-convertible class hierarchy. This is needed, as this method is initially invoked by the UI.
 
 ## Implementation of own Client/User-Inteface (UI)
 
@@ -122,9 +148,17 @@ For this one needs to implement a class which is a subtype of the `AbstractGui`
 
 The next thing to do is to invoke the GUI, by changing a line in the class `client.application.client_base.ClientBase`. This line is the creation of the `TkinterGui()` object, so the line: `self.gui_generator = TkinterGui(self)`, with ones own fancy gui, like `self.gui_generator = FancyGui()`.
 
+## Other examples:
+
+### Elevator:
+
+Is located in: `examples/elevator` - can be executed by:
 
+`$ clinguin client-server --custom-server-classes='./examples/elevator' --solver=TemporalBackend --source-files=examples/elevator/encoding.lp --widget-files=examples/elevator/widgets.lp`
 
+# Linting:
 
+`<PATH>/clinguin$ pylint --disable=C0301,C0303,C0305,R1705,W0703,R0201,W0707,W0122,C0116,W0622,C0103,R0903,W0401,W0614 clinguin`
 
 
 
diff --git a/clinguin/__init__.py b/clinguin/__init__.py
index 6a5c6fd2..8b9ac762 100644
--- a/clinguin/__init__.py
+++ b/clinguin/__init__.py
@@ -9,18 +9,19 @@
 import sys
 from datetime import datetime
 
+from clinguin.utils import Logger
+
 from .parse_input import ArgumentParser
 
 from .server_helper import start as server_start
 from .client_helper import start as client_start
 
-
 def argsToDictConvert(args_dict, timestamp, name_prefix=""):
     """
     Converts the ''external-logger-config'' representation into an internal one
     """
     log_dict = {}
-    log_dict['file_disabled'] = args_dict[name_prefix + 'log_disable_file']
+    log_dict['file_enabled'] = args_dict[name_prefix + 'log_enable_file']
     log_dict['shell_disabled'] = args_dict[name_prefix + 'log_disable_shell']
     log_dict['name'] = args_dict[name_prefix + 'logger_name']
     log_dict['level'] = args_dict[name_prefix + 'log_level']
@@ -37,18 +38,18 @@ def main():
     """
 
     parser = ArgumentParser()
+
     args = parser.parse()
     args_dict = vars(args)
 
     timestamp = datetime.now().strftime("%Y-%m-%d::%H:%M:%S")
-
+    
 
     if args.process == 'server':
         log_dict = argsToDictConvert(args_dict, timestamp)
 
         args_copy = copy.deepcopy(args)
         args_copy.log_args = log_dict
-
         server = threading.Thread(
             target=server_start, args=[args_copy])
         server.start()
@@ -64,7 +65,6 @@ def main():
     elif args.process == 'client-server':
 
         server_log_dict = argsToDictConvert(args_dict, timestamp, name_prefix="server_")
-
         args_copy = copy.deepcopy(args)
         args_copy.log_args = server_log_dict
 
diff --git a/clinguin/client/__init__.py b/clinguin/client/__init__.py
index e69de29b..3de30982 100644
--- a/clinguin/client/__init__.py
+++ b/clinguin/client/__init__.py
@@ -0,0 +1,12 @@
+"""
+Program base of client.
+"""
+from .api.api import Api
+from .api.frontend_policy_dto import FrontendPolicyDto
+from .presentation.abstract_gui import AbstractGui
+from .application.client_base import ClientBase
+
+__all__ = [AbstractGui.__name__, ClientBase.__name__, Api.__name__, FrontendPolicyDto.__name__]
+
+
+
diff --git a/clinguin/client/api/api.py b/clinguin/client/api/api.py
index 1ec47abd..9fc20c13 100644
--- a/clinguin/client/api/api.py
+++ b/clinguin/client/api/api.py
@@ -1,35 +1,60 @@
-import json
-import httpx
+"""
+Module that contains the API-Class
+"""
 import logging
+import traceback
+
+import httpx
 
-from clinguin.client.api.call_dto import CallDto
+from clinguin.utils import Logger
 
+from .frontend_policy_dto import FrontendPolicyDto
 
-class Api:
+class Api:  
+    """
+    The API class is responsible for handling API calls, i.e. sending requests and receiving the responses. 
+    For this two methods exists - GET and POST.
+    This Api sends by default requests to the url:http://127.0.0.1:8000/
+    """
 
-    def __init__(self, args, base_url="http://127.0.0.1:8000/"):
+    def __init__(self, base_url="http://127.0.0.1:8000/"):
 
-        self._logger = logging.getLogger(args.log_args['name'])
+        self._logger = logging.getLogger(Logger.client_logger_name)
 
         self.base_url = base_url
 
     def get(self, endpoint):
         try:
-            self._logger.debug("Sending GET to " +
-                               str(self.base_url) + str(endpoint))
+            self._logger.info("<-- GET to %s%s", str(self.base_url), str(endpoint))
             r = httpx.get(self.base_url + endpoint, timeout=10000)
             return (r.status_code, r.json())
         except httpx.ConnectError:
             return (-1, "")
+        except Exception:
+            self._logger.error("Some other connection-error occured.")
+            self._logger.error("<<<BEGIN-STACKTRACE>>>")
+            traceback.print_exc()
+            self._logger.error("<<<END-STACKTRACE>>>")
+            return (-2, "")
+
 
-    def post(self, endpoint, body: CallDto):
+
+    def post(self, endpoint, body: FrontendPolicyDto):
         try:
-            self._logger.debug("Sending POST to " +
-                               str(self.base_url) +
-                               str(endpoint) +
-                               " with content:" +
-                               str(body.function))
-            r = httpx.post(self.base_url + endpoint, data=body.toJSON(), timeout=10000)
+            self._logger.info("<-- POST to %s%s   %s", str(self.base_url), str(endpoint), str(body.function))
+            
+            data = body.toJSON()
+            r = httpx.post(self.base_url + endpoint, data=data, timeout=10000)
             return (r.status_code, r.json())
         except httpx.ConnectError:
+            self._logger.warning("Https-connect-error occured.")
             return (-1, "")
+        except Exception:
+            self._logger.error("Some other connection-error occured.")
+            self._logger.error("<<<BEGIN-STACKTRACE>>>")
+            traceback.print_exc()
+            self._logger.error("<<<END-STACKTRACE>>>")
+            return (-2, "")
+
+
+            
diff --git a/clinguin/client/api/call_dto.py b/clinguin/client/api/call_dto.py
deleted file mode 100644
index 446c0952..00000000
--- a/clinguin/client/api/call_dto.py
+++ /dev/null
@@ -1,10 +0,0 @@
-import json
-
-
-class CallDto:
-
-    def __init__(self, function):
-        self.function = function
-
-    def toJSON(self):
-        return json.dumps(self, default=lambda o: o.__dict__)
diff --git a/clinguin/client/api/frontend_policy_dto.py b/clinguin/client/api/frontend_policy_dto.py
new file mode 100644
index 00000000..5b1b4df6
--- /dev/null
+++ b/clinguin/client/api/frontend_policy_dto.py
@@ -0,0 +1,15 @@
+"""
+Module contains the FrontendPolicyDto class
+"""
+import json
+
+class FrontendPolicyDto:
+    """
+    Dto class for encapsulating the json that shall be sent to the backend that handles the callbacks.
+    """
+
+    def __init__(self, function):
+        self.function = function
+
+    def toJSON(self):
+        return json.dumps(self, default=lambda o: o.__dict__)
diff --git a/clinguin/client/application/__init__.py b/clinguin/client/application/__init__.py
index e69de29b..a7787e8b 100644
--- a/clinguin/client/application/__init__.py
+++ b/clinguin/client/application/__init__.py
@@ -0,0 +1,3 @@
+"""
+Module for the connection issues of the client.
+"""
diff --git a/clinguin/client/application/client_base.py b/clinguin/client/application/client_base.py
index 89aa32a2..c485673e 100644
--- a/clinguin/client/application/client_base.py
+++ b/clinguin/client/application/client_base.py
@@ -1,22 +1,27 @@
+"""
+Module that contains the ClientBase class
+"""
 import time
 import logging
 
+from clinguin.utils import CaseConverter, Logger
 from clinguin.client.api.api import Api
-from clinguin.client.api.call_dto import CallDto
+from clinguin.client.api.frontend_policy_dto import FrontendPolicyDto
 
-from clinguin.client.presentation.abstract_gui import AbstractGui
-
-class ClientBase:
+class ClientBase:   
+    """
+    ClientBase is the ''base'' of the client. It contains the logic which is responsible for connecting to the server, what to do in case of errors, forward the Json to the correct GUI, etc.
+    """
 
     endpoint_health = "health"
 
     def __init__(self, args):
-        self._logger = logging.getLogger(args.log_args['name'])
+        self._logger = logging.getLogger(Logger.client_logger_name)
 
-        self.api = Api(args)
+        self.api = Api()
         self.connected = False
 
-        self.solve_dto = CallDto("solve")
+        self.solve_dto = FrontendPolicyDto("solve")
 
         self.gui_generator = args.client(self, args)
 
@@ -27,54 +32,64 @@ def startUp(self):
             self.draw(response)
             self.gui_generator.draw(response['children'][0]['id'])
         else:
-            logging.getLogger("client").error(
-                "Connection error, status code: " + str(status_code))
+            self._logger.error(
+                "Connection error, status code: %s", str(status_code))
 
             self.connected = False
             self.connect()
 
     def connect(self):
-        while (self.connected == False):
-            (status_code, json) = self.api.get(self.endpoint_health)
+        while not self.connected:
+            (status_code, _) = self.api.get(self.endpoint_health)
 
             if status_code == 200:
                 self.connected = True
             else:
-                logging.getLogger("client").info("Waiting for connection")
+                self._logger.info("Waiting for connection")
                 time.sleep(1)
 
     def draw(self, response):
-        start = time.time()
         self.baseEngine(response)
-        end = time.time()
-        self._logger.debug("Generation of GUI needed about " + str(end - start) + " seconds.")
 
     def baseEngine(self, response):
+        """
+        Handles the response of the server to draw the GUI. For this it iterates through the received Json/Dict in a top-down preorder fashion.
+
+        Parameters:
+            response (dict): Json from which one can draw the GUI.
+        """
+
         children = response['children']
 
         for child in children:
+            snake_case_name = child['type']
+            camel_case_name = CaseConverter.snakeCaseToCamelCase(snake_case_name)
 
-            if hasattr(self.gui_generator, child['type']):
-                method = getattr(self.gui_generator, child['type'])
+            method = None
 
+            if hasattr(self.gui_generator, camel_case_name):
+                method = getattr(self.gui_generator, camel_case_name)
+            elif hasattr(self.gui_generator, snake_case_name):
+                method = getattr(self.gui_generator, snake_case_name)
+
+            if method and callable(method):
                 method(
                     child['id'],
                     child['parent'],
                     child['attributes'],
                     child['callbacks'])
-
                 self.baseEngine(child)
             else:
-                logging.getLogger("client").error(
-                    "Could not find element type: " + child['type'])
+                self._logger.error(
+                    "Could not find element type: %s", child['type'])
 
-    def assume(self, click_policy):
-        (status_code, json) = self.api.post("solver", CallDto(click_policy))
+    def postWithPolicy(self, click_policy):
+        (status_code, json) = self.api.post("backend", FrontendPolicyDto(click_policy))
         if status_code == 200:
             self.draw(json)
         else:
-            logging.getLogger("client").error(
-                "Connection error, status code: " + str(status_code))
+            self._logger.error(
+                "Connection error, status code: %s", str(status_code))
 
             self.connected = False
             self.connect()
diff --git a/clinguin/client/presentation/abstract_gui.py b/clinguin/client/presentation/abstract_gui.py
index 27f7db94..d485c9df 100644
--- a/clinguin/client/presentation/abstract_gui.py
+++ b/clinguin/client/presentation/abstract_gui.py
@@ -1,43 +1,58 @@
+"""
+Module that contains the class AbstractGui.
+"""
 import logging
 
-from clinguin.utils.custom_args import CustomArgs
+from clinguin.utils import CustomArgs, Logger
 
 class AbstractGui(CustomArgs):
+    """
+    Superclass from where every specialized gui class inherits from (e.g. TkinterGui). Defines the available widgets.
+    """
 
     def __init__(self, base_engine, args):
         self._args = args
-        self._logger = logging.getLogger(args.log_args['name'])
+        self._logger = logging.getLogger(Logger.client_logger_name)
         self._base_engine = base_engine
 
-        print("Abstract Solver")
+
+    @classmethod
+    def availableSyntax(cls, show_level):
+        print(show_level)
+        return ""
 
     def window(self, id, parent, attributes, callbacks):
-        print("WINDOW: " + str(id) + "::" + str(parent))
+        print("WINDOW: " + str(id) + "::" + str(parent) + "::" + str(attributes) + "::" + str(callbacks))
 
     def container(self, id, parent, attributes, callbacks):
-        print("CONTAINER: " + str(id) + "::" + str(parent))
+        print("CONTAINER: " + str(id) + "::" + str(parent) + "::" + str(attributes) + "::" + str(callbacks))
 
-    def dropdownmenu(self, id, parent, attributes, callbacks):
-        print("DROPDOWNMENU: " + str(id) + "::" + str(parent))
+    def dropdownMenu(self, id, parent, attributes, callbacks):
+        print("DROPDOWNMENU: " + str(id) + "::" + str(parent) + "::" + str(attributes) + "::" + str(callbacks))
 
-    def dropdownmenuitem(self, id, parent, attributes, callbacks):
-        print("DROPDOWNMENUITEM: " + str(id) + "::" + str(parent))
+    def dropdownMenuItem(self, id, parent, attributes, callbacks):
+        print("DROPDOWNMENUITEM: " + str(id) + "::" + str(parent) + "::" + str(attributes) + "::" + str(callbacks))
 
     def label(self, id, parent, attributes, callbacks):
-        print("LABEL: " + str(id) + "::" + str(parent))
+        print("LABEL: " + str(id) + "::" + str(parent) + "::" + str(attributes) + "::" + str(callbacks))
 
     def button(self, id, parent, attributes, callbacks):
-        print("BUTTON: " + str(id) + "::" + str(parent))
+        print("BUTTON: " + str(id) + "::" + str(parent) + "::" + str(attributes) + "::" + str(callbacks))
+
+    def menuBar(self, id, parent, attributes, callbacks):
+        print("MENUBAR: " + str(id) + "::" + str(parent) + "::" + str(attributes) + "::" + str(callbacks))
 
-    def menubar(self, id, parent, attributes, callbacks):
-        print("MENUBAR: " + str(id) + "::" + str(parent))
+    def menuBarSection(self, id, parent, attributes, callbacks):
+        print("MENUBARSECTION: " + str(id) + "::" + str(parent) + "::" + str(attributes) + "::" + str(callbacks))
 
-    def menubarsection(self, id, parent, attributes, callbacks):
-        print("MENUBARSECTION: " + str(id) + "::" + str(parent))
+    def menuBarSectionItem(self, id, parent, attributes, callbacks):
+        print("MENUBARSECTIONITEM: " + str(id) + "::" + str(parent) + "::" + str(attributes) + "::" + str(callbacks))
 
-    def menubarsectionitem(self, id, parent, attributes, callbacks):
-        print("MENUBARSECTIONITEM: " + str(id) + "::" + str(parent))
+    def message(self, id, parent, attributes, callbacks):
+        print("MESSAGE: " + str(id) + "::" + str(parent) + "::" + str(attributes) + "::" + str(callbacks))
 
+    def canvas(self, id, parent, attributes, callbacks):
+        print("CANVAS: " + str(id) + "::" + str(parent) + "::" + str(attributes) + "::" + str(callbacks))
 
     def draw(self, id):
-        print("DRAW")
+        print("DRAW" + "::" + str(id))
diff --git a/clinguin/client/presentation/guis/__init__.py b/clinguin/client/presentation/guis/__init__.py
new file mode 100644
index 00000000..54c4a7d8
--- /dev/null
+++ b/clinguin/client/presentation/guis/__init__.py
@@ -0,0 +1,7 @@
+"""
+module that contains all guis
+"""
+from .tkinter_gui.tkinter_gui import TkinterGui
+from .ipython_gui.ipython_gui import IPythonGui
+
+__all__ = [TkinterGui.__name__, IPythonGui.__name__]
diff --git a/clinguin/client/presentation/tkinter/__init__.py b/clinguin/client/presentation/guis/ipython_gui/__init__.py
similarity index 100%
rename from clinguin/client/presentation/tkinter/__init__.py
rename to clinguin/client/presentation/guis/ipython_gui/__init__.py
diff --git a/clinguin/client/presentation/ipython/ipython_gui.py b/clinguin/client/presentation/guis/ipython_gui/ipython_gui.py
similarity index 68%
rename from clinguin/client/presentation/ipython/ipython_gui.py
rename to clinguin/client/presentation/guis/ipython_gui/ipython_gui.py
index 8d8f564d..dd8bad37 100644
--- a/clinguin/client/presentation/ipython/ipython_gui.py
+++ b/clinguin/client/presentation/guis/ipython_gui/ipython_gui.py
@@ -1,21 +1,31 @@
+"""
+Module that contains the IPythonGuiClass
+"""
 from clinguin.client.presentation.abstract_gui import AbstractGui
 
 class IPythonGui(AbstractGui):
+    """
+    Not yet implemented!
+    """
 
     def __init__(self, base_engine, args):
         super().__init__(base_engine, args)
         print("IPython - __init__")
 
+    @classmethod
+    def registerOptions(cls, parser):
+        parser.description = "This GUI is based on the ipython library."
+
     def window(self, id, parent, attributes, callbacks):
         print("IPython - WINDOW: " + str(id) + "::" + str(parent))
 
     def container(self, id, parent, attributes, callbacks):
         print("IPython - CONTAINER: " + str(id) + "::" + str(parent))
 
-    def dropdownmenu(self, id, parent, attributes, callbacks):
+    def dropdownMenu(self, id, parent, attributes, callbacks):
         print("IPython - DROPDOWNMENU: " + str(id) + "::" + str(parent))
 
-    def dropdownmenuitem(self, id, parent, attributes, callbacks):
+    def dropdownMenuItem(self, id, parent, attributes, callbacks):
         print("IPython - DROPDOWNMENUITEM: " + str(id) + "::" + str(parent))
 
     def label(self, id, parent, attributes, callbacks):
@@ -24,13 +34,13 @@ def label(self, id, parent, attributes, callbacks):
     def button(self, id, parent, attributes, callbacks):
         print("IPython - BUTTON: " + str(id) + "::" + str(parent))
 
-    def menubar(self, id, parent, attributes, callbacks):
+    def menuBar(self, id, parent, attributes, callbacks):
         print("IPython - MENUBAR: " + str(id) + "::" + str(parent))
 
-    def menubarsection(self, id, parent, attributes, callbacks):
+    def menuBarSection(self, id, parent, attributes, callbacks):
         print("IPython - MENUBARSECTION: " + str(id) + "::" + str(parent))
 
-    def menubarsectionitem(self, id, parent, attributes, callbacks):
+    def menuBarSectionItem(self, id, parent, attributes, callbacks):
         print("IPython - MENUBARSECTIONITEM: " + str(id) + "::" + str(parent))
 
     def draw(self, id):
diff --git a/clinguin/server/application/default_solvers/__init__.py b/clinguin/client/presentation/guis/tkinter_gui/__init__.py
similarity index 100%
rename from clinguin/server/application/default_solvers/__init__.py
rename to clinguin/client/presentation/guis/tkinter_gui/__init__.py
diff --git a/clinguin/client/presentation/tkinter/tkinter_gui.py b/clinguin/client/presentation/guis/tkinter_gui/tkinter_gui.py
similarity index 56%
rename from clinguin/client/presentation/tkinter/tkinter_gui.py
rename to clinguin/client/presentation/guis/tkinter_gui/tkinter_gui.py
index 66a2f49c..8d186b1f 100644
--- a/clinguin/client/presentation/tkinter/tkinter_gui.py
+++ b/clinguin/client/presentation/guis/tkinter_gui/tkinter_gui.py
@@ -1,23 +1,17 @@
-import tkinter as tk
-import logging
+"""
+Contains the tkinter-gui class.
+"""
+from clinguin.show_gui_syntax_enum import ShowGuiSyntaxEnum
+from clinguin.client import AbstractGui
 
-from clinguin.client.presentation.tkinter.window import Window
-from clinguin.client.presentation.tkinter.container import Container
-from clinguin.client.presentation.tkinter.dropdownmenu import Dropdownmenu
-from clinguin.client.presentation.tkinter.dropdownmenu_item import DropdownmenuItem
-from clinguin.client.presentation.tkinter.label import Label
-from clinguin.client.presentation.tkinter.button import Button
+from .tkinter_widgets import *
+from .tkinter_utils import *
 
-from clinguin.client.presentation.tkinter.menu_bar import MenuBar
-from clinguin.client.presentation.tkinter.menu_bar_section import MenuBarSection
-from clinguin.client.presentation.tkinter.menu_bar_section_item import MenuBarSectionItem
-
-from clinguin.client.presentation.abstract_gui import AbstractGui
-
-from clinguin.client.presentation.tkinter.attribute_names import AttributeNames
-from clinguin.client.presentation.tkinter.callback_names import CallbackNames
 
 class TkinterGui(AbstractGui):
+    """
+    Class that inherits from AbstractGui and is therefore a dynamically loaded class, if it shall be used to render the Gui. It defines what to do for each widget.
+    """
 
     def __init__(self, base_engine, args):
         super().__init__(base_engine, args)
@@ -27,18 +21,33 @@ def __init__(self, base_engine, args):
 
     @classmethod
     def registerOptions(cls, parser):   
-        def appendDict(description, _dict):
+        parser.description = "This GUI is based on the Python-Tkinter package and uses tkinter widgets."
+
+    @classmethod
+    def availableSyntax(cls, show_level):
+        def appendDict(description, _dict, type_name):
+
             for key in _dict.keys():
-                description = description + "    |- " + key
-                if "description" in _dict[key]:
-                    # Specific has higher priority
-                    description = description + ": " + _dict[key]["description"]
-                elif key in AttributeNames.descriptions:
-                    # General lesser priority
-                    description = description + ": " + AttributeNames.descriptions[key]
-                elif key in CallbackNames.descriptions:
-                    description = description + ": " + CallbackNames.descriptions[key]
-                description = description + "\n"
+                description = description + "    |- " + key + "\n"
+                if show_level == ShowGuiSyntaxEnum.FULL:
+                    if "description" in _dict[key]:
+                        # Specific has higher priority
+                        description = description + "      |- Description: "
+                        description = description + ": " + _dict[key]["description"]
+                        description = description + "\n"
+                    elif key in AttributeNames.descriptions:
+                        # General lesser priority
+                        description = description + "      |- Description: "
+                        description = description + ": " + AttributeNames.descriptions[key]
+                        description = description + "\n"
+                    elif key in CallbackNames.descriptions:
+                        description = description + "      |- Description: "
+                        description = description + ": " + CallbackNames.descriptions[key]
+                        description = description + "\n"
+
+                    if type_name in _dict[key]:
+                        description = description + "      |- Possible-Values: "
+                        description = description + _dict[key][type_name].description() + "\n"
 
             return description
 
@@ -49,7 +58,7 @@ def appendDict(description, _dict):
             "callback(<ID>, <ACTION>, <POLICY>) : To define a callback for an element (the ID is the ID of the corresponding element)\n\n" +\
             "The following list shows for each <TYPE> the possible attributes and callbacks:\n" 
 
-        class_list = [Window, Container, Label, Button, Dropdownmenu, DropdownmenuItem, MenuBar, MenuBarSection, MenuBarSectionItem]
+        class_list = RootCmp.__subclasses__()
 
         description = description + "|--------------------------------\n"
         for c in class_list:
@@ -58,15 +67,16 @@ def appendDict(description, _dict):
             attributes = c.getAttributes()
             if len(attributes.keys()) > 0:
                 description = description + "  |- attributes\n"
-                description = appendDict(description, attributes)
+                description = appendDict(description, attributes, "value_type")
             
             callbacks = c.getCallbacks()
             if len(callbacks.keys()) > 0:               
                 description = description + "  |- callbacks\n"
-                description = appendDict(description, callbacks)
+                description = appendDict(description, callbacks, "policy_type")
             description = description + "|--------------------------------\n"
 
-        parser.description = description
+        return description
+
 
     def window(self, id, parent, attributes, callbacks):
 
@@ -88,11 +98,11 @@ def container(self, id, parent, attributes, callbacks):
         container.addComponent(self.elements)
 
 
-    def dropdownmenu(self, id, parent, attributes, callbacks):
+    def dropdownMenu(self, id, parent, attributes, callbacks):
         menu = Dropdownmenu(self._args, id, parent, attributes, callbacks, self._base_engine)
         menu.addComponent(self.elements)
 
-    def dropdownmenuitem(self, id, parent, attributes, callbacks):
+    def dropdownMenuItem(self, id, parent, attributes, callbacks):
         menu = DropdownmenuItem(self._args, id, parent, attributes, callbacks, self._base_engine)
         menu.addComponent(self.elements)
 
@@ -104,18 +114,26 @@ def button(self, id, parent, attributes, callbacks):
         button = Button(self._args, id, parent, attributes, callbacks, self._base_engine)
         button.addComponent(self.elements)
 
-    def menubar(self, id, parent, attributes, callbacks):
+    def menuBar(self, id, parent, attributes, callbacks):
         menubar = MenuBar(self._args, id, parent, attributes, callbacks, self._base_engine)
         menubar.addComponent(self.elements)
 
-    def menubarsection(self, id, parent, attributes, callbacks):
+    def menuBarSection(self, id, parent, attributes, callbacks):
         menubar = MenuBarSection(self._args, id, parent, attributes, callbacks, self._base_engine)
         menubar.addComponent(self.elements)
 
-    def menubarsectionitem(self, id, parent, attributes, callbacks):
+    def menuBarSectionItem(self, id, parent, attributes, callbacks):
         menubar = MenuBarSectionItem(self._args, id, parent, attributes, callbacks, self._base_engine)
         menubar.addComponent(self.elements)
 
+    def message(self, id, parent, attributes, callbacks):
+        message = Message(self._args, id, parent, attributes, callbacks, self._base_engine)
+        message.addComponent(self.elements)
+
+    def canvas(self, id, parent, attributes, callbacks):
+        canvas = Canvas(self._args, id, parent, attributes, callbacks, self._base_engine)
+        canvas.addComponent(self.elements)
+
     def draw(self, id):
         self.first = False
         self.elements[id].getWidget().mainloop()
diff --git a/clinguin/client/presentation/guis/tkinter_gui/tkinter_utils/__init__.py b/clinguin/client/presentation/guis/tkinter_gui/tkinter_utils/__init__.py
new file mode 100644
index 00000000..36c16e92
--- /dev/null
+++ b/clinguin/client/presentation/guis/tkinter_gui/tkinter_utils/__init__.py
@@ -0,0 +1,15 @@
+"""
+This module contains various utils for tkinter-widgets, which reduce code size, etc.
+"""
+from .attribute_names import AttributeNames
+from .callback_names import CallbackNames
+from .call_back_definition import CallBackDefinition
+
+from .extension_class import ExtensionClass
+from .layout_follower import LayoutFollower
+from .layout_controller import LayoutController
+from .configure_size import ConfigureSize
+from .configure_border import ConfigureBorder
+from .configure_font import ConfigureFont
+
+__all__ = [AttributeNames.__name__, CallbackNames.__name__, CallBackDefinition.__name__, LayoutFollower.__name__, ExtensionClass.__name__, LayoutController.__name__, ConfigureSize.__name__, ConfigureBorder.__name__, ConfigureFont.__name__]
diff --git a/clinguin/client/presentation/guis/tkinter_gui/tkinter_utils/attribute_names.py b/clinguin/client/presentation/guis/tkinter_gui/tkinter_utils/attribute_names.py
new file mode 100644
index 00000000..556f0a24
--- /dev/null
+++ b/clinguin/client/presentation/guis/tkinter_gui/tkinter_utils/attribute_names.py
@@ -0,0 +1,86 @@
+"""
+Module that contains the AttributeNames class.
+"""
+
+class AttributeNames:
+    """
+    This class contains all the names for all the attributes that are used for the Gui and also contains some standard descriptions of the attributes.
+    """
+
+    
+    title = "title"
+    message = "message"
+    type = "type"
+    
+    label = "label"
+    backgroundcolor = "background_color"
+    foregroundcolor = "foreground_color"
+    width = "width"
+    height = "height"
+
+    onhover = "on_hover"
+    onhover_background_color = "on_hover_background_color"
+    onhover_foreground_color = "on_hover_foreground_color"
+    onhover_border_color = "on_hover_border_color"
+
+    font_family = "font_family"
+    font_size = "font_size"
+    font_weight = "font_weight"
+
+    resizable_x = "resizable_x"
+    resizable_y = "resizable_y"
+
+    child_layout = "child_layout"
+
+    grid_column = "grid_column"
+    grid_row = "grid_row"
+    grid_column_span = "grid_column_span"
+    grid_row_span = "grid_row_span"
+    pos_x = "pos_x"
+    pos_y = "pos_y"
+
+    border_width = "border_width"
+    border_color = "border_color"
+
+    selected = "selected"
+    fit_children_size = "fit"
+
+    image = "image"
+    image_path = "image_path"
+    resize = "resize"
+
+
+    descriptions = {
+        title : "With this attribute one can set the title of a pop-up.",
+        message : "With this attribute one can set the message of a pop-up.",
+        type : "With this attribute one can set the look and feel of the pop-up.",
+        label : "With this attribute one can set the label-text of the widget.",
+        backgroundcolor : "With this attribute one can define the background-color of the widget.",
+        foregroundcolor : "With this attribute one can set the foreground-color of the widget.",
+        width : "With this attribute one can set the width in pixels of the widget.",
+        height : "With this attribute one can set the height in pixels of the widget.",
+        onhover : "With this attribute one can enable or disable on-hover features for the widget.",
+        onhover_background_color : "With this attribute one can set the background color the widget shall have, when on_hover is enabled.",
+        onhover_foreground_color : "With this attribute one can set the forground color the widget shall have, when on_hover is eneabled.",
+        onhover_border_color : "With this attribute one can set the color the border of the widget shall have, when on_hover is enabled.",
+        font_family : "With this attribute one can set the font-family of the widget.",
+        font_size : "With this attribute one can set the font size in pixels.",
+        font_weight : "With this attribute one can set the font weight.",
+        resizable_x : "With this attribute one can define if the widget shall be resizable in x direction.",
+        resizable_y : "With this attribute one can define if the widget shall be resizable in y direction.",
+        child_layout : "With this attribute one can define the layout of the children, i.e. how they are positioned.",
+        grid_column : "With this attribute one can define in which column the widget shall be positioned.",
+        grid_row : "With this attribute one can define in which row the widget shall be positioned.",
+        grid_column_span : "With this attribute one can define, that the widgets stretches over several columns.",
+        grid_row_span : "With this attribute one can define, that the widgets stretches over several rows.",
+        pos_x : "With this attribute one sets the x-position of the widget - it depends on the parent-child-layout how this is defined (either pixels, relative as a percentage, ...).",
+        pos_y : "With this attribute one sets the y-position of the widget - it depends on the parent-child-layout how this is defined (either pixels, relative as a percentage, ...).",
+        border_width : "With this attribute one defines the width of the border in pixels.",
+        border_color : "With this attribute one may set the border color.",
+        selected : "With this attribute one may define the text that shall be displayed if something is selected.",
+        fit_children_size : "[DEPRECATED] - With this attribute one can define that the widget fits the children.",
+        image : "Some backends define special values one can use, that e.g. a graph is shown (see corresponding backend description).",
+        image_path : "Include an image from a path.",
+        resize : "With this attribute one can define if an image shall be resized."
+        }
+
diff --git a/clinguin/client/presentation/tkinter/call_back_definition.py b/clinguin/client/presentation/guis/tkinter_gui/tkinter_utils/call_back_definition.py
similarity index 65%
rename from clinguin/client/presentation/tkinter/call_back_definition.py
rename to clinguin/client/presentation/guis/tkinter_gui/tkinter_utils/call_back_definition.py
index 87882490..ca535ca0 100644
--- a/clinguin/client/presentation/tkinter/call_back_definition.py
+++ b/clinguin/client/presentation/guis/tkinter_gui/tkinter_utils/call_back_definition.py
@@ -1,5 +1,11 @@
+"""
+This module contains the CallBackDefinition class.
+"""
 
 class CallBackDefinition:
+    """
+    Some widgets use this class to define their callbacks (others just do it locally, which is the preferred method).
+    """
     def __init__(self, id, parent, click_policy, elements, callback):
         self._id = id
         self._parent = parent
diff --git a/clinguin/client/presentation/guis/tkinter_gui/tkinter_utils/callback_names.py b/clinguin/client/presentation/guis/tkinter_gui/tkinter_utils/callback_names.py
new file mode 100644
index 00000000..d3c76c01
--- /dev/null
+++ b/clinguin/client/presentation/guis/tkinter_gui/tkinter_utils/callback_names.py
@@ -0,0 +1,14 @@
+"""
+This module contains the CallbackNames class.
+"""
+
+class CallbackNames:
+    """
+    This class contains all possible names for actions for callbacks and their descriptions.
+    """
+    click = "click"
+
+    descriptions = {
+        click : "The click action, is the action that is executed if one clicks with the left-mouse button on a widget."
+    }
+
diff --git a/clinguin/client/presentation/guis/tkinter_gui/tkinter_utils/configure_border.py b/clinguin/client/presentation/guis/tkinter_gui/tkinter_utils/configure_border.py
new file mode 100644
index 00000000..22c96d2f
--- /dev/null
+++ b/clinguin/client/presentation/guis/tkinter_gui/tkinter_utils/configure_border.py
@@ -0,0 +1,51 @@
+"""
+This module contains the ConfigureBorder class.
+"""
+
+from .extension_class import *
+
+class ConfigureBorder(ExtensionClass):
+    """
+    If a widget shall have a border (e.g. container), it must be a subtype of this class.
+    """
+
+    @classmethod
+    def getAttributes(cls, attributes = None):
+        if attributes is None:
+            attributes = {}
+
+        attributes[AttributeNames.border_width] = {"value":0, "value_type" : IntegerType}
+        attributes[AttributeNames.border_color] = {"value":"black", "value_type" : ColorType}
+
+        return attributes
+
+    def _setBorderWidth(self, elements, key = AttributeNames.border_width):
+        value = self._attributes[key]["value"]
+        if value > 0:
+            # Not using borderwidth as one cannot set the color of the default border
+            self._widget.configure(highlightthickness = int(value))
+        elif value == 0:
+            # Zero is perfectly fine, but it shouldn't be configured then
+            pass
+        else:
+            self._logger.warning("For element " + self._id + " ,setBorderwidth for " + key + " is lesser than 0: " + str(value))
+
+    def _setBorderBackgroundColor(self, elements, key = AttributeNames.border_color):
+        # Not using borderwidth as one cannot set the color of the default border
+        value = self._attributes[key]["value"]
+        self._widget.configure(highlightbackground = value, highlightcolor = value)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/clinguin/client/presentation/guis/tkinter_gui/tkinter_utils/configure_font.py b/clinguin/client/presentation/guis/tkinter_gui/tkinter_utils/configure_font.py
new file mode 100644
index 00000000..61ebd798
--- /dev/null
+++ b/clinguin/client/presentation/guis/tkinter_gui/tkinter_utils/configure_font.py
@@ -0,0 +1,46 @@
+"""
+This module contains the ConfigureSize class.
+"""
+from .extension_class import *
+from tkinter import font
+
+class ConfigureFont(ExtensionClass):
+    """
+    If a widget is a subtype of the configure-size class the size of the widget can be adjusted.
+    """
+
+    def __init__(self):
+        self._configure_font_widget = None
+
+    @classmethod
+    def getAttributes(cls, attributes = None):
+        if attributes is None:
+            attributes = {}
+
+        attributes[AttributeNames.font_family] = {"value":"", "value_type" : FontFamiliesType}
+        attributes[AttributeNames.font_size] = {"value":12, "value_type" : IntegerType}
+        attributes[AttributeNames.font_weight] = {"value":"normal", "value_type" : FontWeightType}
+
+        return attributes
+
+    def _setFont(self, elements):
+    
+        family = family=self._attributes[AttributeNames.font_family]["value"]
+        size = int(self._attributes[AttributeNames.font_size]["value"])
+        weight = self._attributes[AttributeNames.font_weight]["value"]
+
+        kwargs = {}
+        if family != "":
+            kwargs["family"] = family
+        if size > 0:
+            kwargs["size"] = size
+        
+        if weight in [FontWeightType.BOLD, FontWeightType.ITALIC_BOLD]:
+            kwargs["weight"] = "bold"
+        if weight in [FontWeightType.ITALIC, FontWeightType.ITALIC_BOLD]:
+            kwargs["slant"] = "italic"
+        
+        if family != "" or size != "" or weight != FontWeightType.NORMAL:
+            afont = font.Font(**kwargs)
+            self._configure_font_widget.configure(font=afont)
+
diff --git a/clinguin/client/presentation/guis/tkinter_gui/tkinter_utils/configure_size.py b/clinguin/client/presentation/guis/tkinter_gui/tkinter_utils/configure_size.py
new file mode 100644
index 00000000..fbcbc0af
--- /dev/null
+++ b/clinguin/client/presentation/guis/tkinter_gui/tkinter_utils/configure_size.py
@@ -0,0 +1,48 @@
+"""
+This module contains the ConfigureSize class.
+"""
+from .extension_class import *
+
+class ConfigureSize(ExtensionClass):
+    """
+    If a widget is a subtype of the configure-size class the size of the widget can be adjusted.
+    """
+
+    @classmethod
+    def getAttributes(cls, attributes = None):
+        if attributes is None:
+            attributes = {}
+
+        attributes[AttributeNames.height] = {"value":0, "value_type" : IntegerType}
+        attributes[AttributeNames.width] = {"value":0, "value_type" : IntegerType}
+
+        return attributes
+
+    def _setSize(self, elements):
+        height = self._attributes[AttributeNames.height]["value"]
+        width = self._attributes[AttributeNames.width]["value"]
+
+        if height > 0 and width > 0:
+            # If height is set, 
+            if AttributeNames.child_layout in self._attributes:
+                child_layout_value = self._attributes[AttributeNames.child_layout]["value"]
+
+                if child_layout_value in (ChildLayoutType.FLEX, ChildLayoutType.RELSTATIC, ChildLayoutType.ABSSTATIC):
+                    self._widget.pack_propagate(0)
+                elif child_layout_value == ChildLayoutType.GRID:
+                    self._widget.grid_propagate(0)
+            else:
+                self._widget.pack_propagate(0)
+
+        if height > 0:
+            self._widget.configure(height = int(height))
+
+        if width > 0:
+            self._widget.configure(width = int(width))
+    
+        if height < 0:
+            self._logger.warning("Height of " + self._id + " has illegal value (" + str(height) + ")")
+
+        if width < 0:
+            self._logger.warning("Width of " + self._id + " has illegal value (" + str(height) + ")")
+
diff --git a/clinguin/client/presentation/guis/tkinter_gui/tkinter_utils/extension_class.py b/clinguin/client/presentation/guis/tkinter_gui/tkinter_utils/extension_class.py
new file mode 100644
index 00000000..c03c5477
--- /dev/null
+++ b/clinguin/client/presentation/guis/tkinter_gui/tkinter_utils/extension_class.py
@@ -0,0 +1,20 @@
+"""
+This module contains the ExtensionClass
+"""
+from clinguin.utils.attribute_types import *
+from .attribute_names import AttributeNames
+from .callback_names import CallbackNames
+
+class ExtensionClass:
+    """
+    If a class is a subtype of the ExtensionClass it resembles a set of attributes/callbacks that can be applied to widgets.
+    """
+
+    @classmethod
+    def getAttributes(cls, attributes = None):
+        return {}
+
+    @classmethod
+    def getCallbacks(cls, attributes = None):
+        return {}
+
diff --git a/clinguin/client/presentation/guis/tkinter_gui/tkinter_utils/layout_controller.py b/clinguin/client/presentation/guis/tkinter_gui/tkinter_utils/layout_controller.py
new file mode 100644
index 00000000..6764b79c
--- /dev/null
+++ b/clinguin/client/presentation/guis/tkinter_gui/tkinter_utils/layout_controller.py
@@ -0,0 +1,30 @@
+"""
+This module contains the LayoutController class.
+"""
+from .extension_class import *
+
+class LayoutController(ExtensionClass):
+    """
+    If a widget is a subtype of this class, then it can steer the layouting behavior of children.
+    """
+
+    @classmethod
+    def getAttributes(cls, attributes = None):
+        if attributes is None:
+            attributes = {}
+
+        attributes[AttributeNames.child_layout] = {"value": ChildLayoutType.FLEX, "value_type" : ChildLayoutType}
+
+        return attributes
+ 
+    def _setChildOrg(self, elements):
+        value = self._attributes[AttributeNames.child_layout]["value"]
+        self._child_layout = value
+
+    def getChildOrg(self):
+        return self._child_layout
+
+    def getFitChildrenSize(self):
+        return self._fit_children_size
+
+
diff --git a/clinguin/client/presentation/guis/tkinter_gui/tkinter_utils/layout_follower.py b/clinguin/client/presentation/guis/tkinter_gui/tkinter_utils/layout_follower.py
new file mode 100644
index 00000000..8fa3fd3f
--- /dev/null
+++ b/clinguin/client/presentation/guis/tkinter_gui/tkinter_utils/layout_follower.py
@@ -0,0 +1,84 @@
+"""
+This module contains the LayoutFollower class.
+"""
+import logging
+from clinguin.utils import Logger
+
+from .extension_class import *
+
+class LayoutFollower(ExtensionClass):
+    """
+    If a widget is a subtype of this class then one can be sure, that one can use it in layouts.
+    """
+
+    def __init__(self):
+        self._logger = logging.getLogger(Logger.client_logger_name)
+
+    @classmethod
+    def getAttributes(cls, attributes = None):
+        if attributes is None:
+            attributes = {}
+
+        # Layout-Control
+        attributes[AttributeNames.grid_column] = {"value":0, "value_type" : IntegerType}
+        attributes[AttributeNames.grid_row] = {"value":0, "value_type" : IntegerType}
+        attributes[AttributeNames.grid_column_span] = {"value":1, "value_type" : IntegerType}
+        attributes[AttributeNames.grid_row_span] = {"value":1, "value_type" : IntegerType}
+
+        attributes[AttributeNames.pos_x] = {"value":0, "value_type" : IntegerType}
+        attributes[AttributeNames.pos_y] = {"value":0, "value_type" : IntegerType}
+
+        return attributes
+
+
+    def _setLayout(self, elements):
+        parent = elements[self._parent]
+        if hasattr(parent, "getChildOrg"):
+            parent_org = getattr(parent, "getChildOrg")()
+        else:
+            self._logger.warning("Could not find necessary attribute childOrg() in id: %s", str(self._parent))
+            return
+
+        if parent_org == ChildLayoutType.FLEX:
+            self._widget.pack(expand=True, fill='both')
+
+        elif parent_org == ChildLayoutType.GRID:
+            grid_pos_column = self._attributes[AttributeNames.grid_column]['value']
+            grid_pos_row = self._attributes[AttributeNames.grid_row]['value']
+
+            grid_span_column = self._attributes[AttributeNames.grid_column_span]['value']
+            grid_span_row = self._attributes[AttributeNames.grid_row_span]['value']
+
+            if int(grid_pos_column) >= 0 and int(grid_pos_row) >= 0 and int(grid_span_column) >= 1 and int(grid_span_row) >= 1:
+                self._widget.grid(
+                    column=grid_pos_column, 
+                    row=grid_pos_row,
+                    columnspan=int(grid_span_column),
+                    rowspan = int(grid_span_row))
+            else:
+                self._logger.warning("Could not set grid-layout due to illegal values for element: %s", str(self._id)) 
+
+        elif parent_org in (ChildLayoutType.ABSSTATIC, ChildLayoutType.RELSTATIC):
+            self._widget.pack(expand=True, fill='both')
+
+            x = self._attributes[AttributeNames.pos_x]["value"]
+            y = self._attributes[AttributeNames.pos_y]["value"]
+
+            if int(x) >= 0 and int(y) >= 0:
+                if parent_org == ChildLayoutType.ABSSTATIC:
+                    self._widget.place(
+                        x=int(x), 
+                        y=int(y))
+                elif parent_org == ChildLayoutType.RELSTATIC:
+                    self._widget.place(
+                        relx=int(x)/100, 
+                        rely=int(y)/100)
+                else:
+                    error_string = "For element " + self._id + " ,either posx or posy are not non-negative-numbers. "
+                    self._logger.error(error_string)
+                    raise Exception(error_string)
+            else:
+                self._logger.warning("For element %s invalid positioning supplied.", self._id)
+        else:
+            self._logger.warning("For element %s no child layout was defined.", self._id)
+
diff --git a/clinguin/client/presentation/guis/tkinter_gui/tkinter_widgets/__init__.py b/clinguin/client/presentation/guis/tkinter_gui/tkinter_widgets/__init__.py
new file mode 100644
index 00000000..3abaa09d
--- /dev/null
+++ b/clinguin/client/presentation/guis/tkinter_gui/tkinter_widgets/__init__.py
@@ -0,0 +1,18 @@
+"""
+This package contains all tkinter_widgets that are provided in clinguin.
+"""
+from .root_cmp import RootCmp
+from .window import Window
+from .container import Container
+from .dropdownmenu import Dropdownmenu
+from .dropdownmenu_item import DropdownmenuItem
+from .label import Label
+from .button import Button
+from .menu_bar import MenuBar
+from .menu_bar_section import MenuBarSection
+from .menu_bar_section_item import MenuBarSectionItem
+from .message import Message
+from .canvas import Canvas
+
+__all__ = [RootCmp.__name__, Window.__name__, Container.__name__, Dropdownmenu.__name__, DropdownmenuItem.__name__, Label.__name__, Button.__name__, MenuBar.__name__, MenuBarSection.__name__, MenuBarSectionItem.__name__, Message.__name__, Canvas.__name__]
+
diff --git a/clinguin/client/presentation/guis/tkinter_gui/tkinter_widgets/button.py b/clinguin/client/presentation/guis/tkinter_gui/tkinter_widgets/button.py
new file mode 100644
index 00000000..31f122a9
--- /dev/null
+++ b/clinguin/client/presentation/guis/tkinter_gui/tkinter_widgets/button.py
@@ -0,0 +1,109 @@
+"""
+This module contains the button class.
+"""
+import tkinter as tk
+
+from .root_cmp import *
+
+class Button(RootCmp, LayoutFollower, ConfigureSize, ConfigureFont):
+    """
+    A button is a widget, which is generally regarded as an active element, so actions are executed. For available attributes see syntax definition. Implementation wise it is similarly implemented as the Label and Dropdownmenu - to make it work for layouting, the actual button is hidden the the widget is actually a tkinter frame (therefore self._widget is a frame, whereas self._button is the button).
+    """
+    def __init__(self, args, id, parent, attributes, callbacks, base_engine):
+        super().__init__(args, id, parent, attributes, callbacks, base_engine)
+        
+        self._button = None
+
+    def _initWidget(self, elements):
+
+        button_frame = tk.Frame(elements[str(self._parent)].getWidget())
+        
+        self._button = tk.Button(button_frame)
+        self._configure_font_widget = self._button
+
+        return button_frame
+
+    @classmethod
+    def _getAttributes(cls, attributes = None):
+        if attributes is None:
+            attributes = {}
+
+        # Label/Text
+        attributes[AttributeNames.label] = {"value":"", "value_type" : StringType}
+        # Color
+        attributes[AttributeNames.backgroundcolor] = {"value":"white", "value_type" : ColorType}
+        attributes[AttributeNames.foregroundcolor] = {"value":"black", "value_type" : ColorType}
+        # Interactive-Attributes
+        attributes[AttributeNames.onhover] = {"value":False, "value_type" : BooleanType}
+        attributes[AttributeNames.onhover_background_color] = {"value":"white", "value_type" : ColorType}
+        attributes[AttributeNames.onhover_foreground_color] = {"value":"black", "value_type" : ColorType}
+
+        return attributes
+
+    @classmethod
+    def _getCallbacks(cls, callbacks = None):
+        if callbacks is None:
+            callbacks = {}
+
+        callbacks[CallbackNames.click] = {"policy":None, "policy_type" : SymbolType}
+
+        return callbacks
+
+    #----------------------------------------------------------------------------------------------
+    #-----Attributes----
+    #----------------------------------------------------------------------------------------------
+
+    def _setLabelText(self, elements):
+        text = self._attributes[AttributeNames.label]["value"]
+        self._button.configure(text = text)
+
+    def _setBackgroundColor(self, elements, key = AttributeNames.backgroundcolor):
+        value = self._attributes[key]["value"]
+        self._button.configure(background = value)
+
+    def _setForegroundColor(self, elements, key = AttributeNames.foregroundcolor):
+        value = self._attributes[key]["value"]
+        self._button.configure(foreground = value)
+
+    def _setOnHover(self, elements): 
+        on_hover = self._attributes[AttributeNames.onhover]["value"]
+        on_hover_background_color = self._attributes[AttributeNames.onhover_background_color]["value"]
+
+        on_hover_foreground_color = self._attributes[AttributeNames.onhover_foreground_color]["value"]
+
+        if on_hover:
+            def enter(event):
+                if on_hover_background_color != "":
+                    self._setBackgroundColor(elements, key = AttributeNames.onhover_background_color)
+                if on_hover_foreground_color != "":
+                    self._setForegroundColor(elements, key = AttributeNames.onhover_foreground_color)
+
+            def leave(event):
+                self._setBackgroundColor(elements)
+                self._setForegroundColor(elements)
+    
+            self._button.bind('<Enter>', enter)
+            self._button.bind('<Leave>', leave)
+
+    #----------------------------------------------------------------------------------------------
+    #-----Actions----
+    #----------------------------------------------------------------------------------------------
+       
+    def _defineClickEvent(self, elements):
+        key = CallbackNames.click
+        if self._callbacks[key] and self._callbacks[key]["policy"]:
+            def clickEvent(event):
+                self._base_engine.postWithPolicy(self._callbacks[key]["policy"])
+
+            self._button.bind('<Button-1>', clickEvent)
+
+    def _addComponentToElements(self, elements):
+        self._button.pack(expand=True, fill='both')
+
+        elements[str(self._id)] = self
+
+
+
+
+
+
diff --git a/clinguin/client/presentation/guis/tkinter_gui/tkinter_widgets/canvas.py b/clinguin/client/presentation/guis/tkinter_gui/tkinter_widgets/canvas.py
new file mode 100644
index 00000000..f9bfc38b
--- /dev/null
+++ b/clinguin/client/presentation/guis/tkinter_gui/tkinter_widgets/canvas.py
@@ -0,0 +1,98 @@
+"""
+Contains the canvas class.
+"""
+import io
+import base64
+
+import tkinter as tk
+from PIL import ImageTk
+import PIL.Image as TImage
+
+from .root_cmp import *
+
+class Canvas(RootCmp, LayoutFollower, ConfigureSize):
+    """
+    The canvas class resembles a widget, which is generally regarded as an ''empty sheet of paper'', so there is an area, where one can display images, draw something or does something similar. One can look up what actual options are available through the syntax-definition. Implementation wise it is similarly implemented to the label, button and dropdownmenu.
+    """
+
+    def __init__(self, args, id, parent, attributes, callbacks, base_engine):
+        super().__init__(args, id, parent, attributes, callbacks, base_engine)
+
+        self._canvas = None
+        self._image = None
+        
+
+    def _initWidget(self, elements):
+        canvas_frame = tk.Frame(elements[str(self._parent)].getWidget())
+
+        self._canvas = tk.Canvas(canvas_frame)
+
+        return canvas_frame
+
+    @classmethod
+    def _getAttributes(cls, attributes = None):
+        if attributes is None:
+            attributes = {}
+
+        attributes[AttributeNames.image] = {"value":"", "value_type" : ImageType}
+        attributes[AttributeNames.image_path] = {"value":"", "value_type" : PathType}
+        attributes[AttributeNames.resize] = {"value": True, "value_type" : BooleanType}
+        return attributes
+
+    def _setImage(self, elements):
+
+        image_base64 = self._attributes[AttributeNames.image]["value"]
+        image_file = self._attributes[AttributeNames.image_path]["value"]
+
+        if image_base64 != "" and image_file != "":
+            self._logger.error("One cannot set both attributes %s and %s for the same canvas with id %s", AttributeNames.image, AttributeNames.image_path, str(self._id))
+
+        elif image_base64 == "" and image_file != "":
+            try:
+                
+                image_open = TImage.open(image_file)
+
+                height = self._attributes[AttributeNames.height]["value"]
+                width = self._attributes[AttributeNames.width]["value"]
+                resize_flag = self._attributes[AttributeNames.resize]["value"]
+                
+                should_resize = resize_flag and height > 0 and width > 0
+                
+                if should_resize:
+                    image_open = image_open.resize((width, height))
+
+                tkinter_image = ImageTk.PhotoImage(image_open, master=self._canvas)
+
+                self._canvas.create_image(0,0,anchor=tk.NW, image=tkinter_image)
+
+                # DO NOT DELETE THIS SEEMINGLY UNECESSARY LINE (this is due to a tkinter bug)
+                self._image = tkinter_image
+            except Exception as e:
+                self._logger.error(e)
+                self._logger.error("Could not render image (likely the provided file <%s>is not a valid image).", image_file)
+
+        elif image_base64 != "" and image_file == "":
+            try:
+                image_initial_bytes = image_base64.encode('utf-8')
+                image_decoded = base64.b64decode(image_initial_bytes)
+
+                image_bytes = io.BytesIO(image_decoded)
+                image_open = TImage.open(image_bytes)
+
+                image_open = image_open.resize((self._attributes[AttributeNames.width]["value"], self._attributes[AttributeNames.width]["value"]))
+                tkinter_image = ImageTk.PhotoImage(image_open, master=self._canvas)
+
+
+                self._canvas.create_image(0,0,anchor=tk.NW, image=tkinter_image)
+
+                # DO NOT DELETE THIS SEEMINGLY UNECESSARY LINE
+                self._image = tkinter_image
+            except Exception:
+                self._logger.error("Could not render image (likely Base64 encoding is wrong).")
+            
+
+    def _addComponentToElements(self, elements):
+        self._canvas.pack(expand=True, fill='both')
+
+        elements[str(self._id)] = self
+
diff --git a/clinguin/client/presentation/guis/tkinter_gui/tkinter_widgets/container.py b/clinguin/client/presentation/guis/tkinter_gui/tkinter_widgets/container.py
new file mode 100644
index 00000000..89e936a0
--- /dev/null
+++ b/clinguin/client/presentation/guis/tkinter_gui/tkinter_widgets/container.py
@@ -0,0 +1,79 @@
+"""
+Module contains the Container class.
+"""
+import tkinter as tk
+
+from .root_cmp import *
+
+class Container(RootCmp, LayoutFollower, LayoutController, ConfigureSize, ConfigureBorder):
+    """
+    The container is a generic widget which can be used for layouting, hovering effects or even callbacks. Generally it is recommended to use it as a ''container'' for multiple other widgets, e.g. labels, buttons, etc.
+    """
+
+    def _initWidget(self, elements):
+        container = tk.Frame(elements[str(self._parent)].getWidget())
+        return container
+
+    @classmethod
+    def _getAttributes(cls, attributes = None):
+        if attributes is None:
+            attributes = {}
+
+        attributes[AttributeNames.backgroundcolor] = {"value":"white", "value_type" : ColorType, "description": "CUSTOM-BACKGROUND-COLOR-DESCRIPTION <- Now normal:" + AttributeNames.descriptions[AttributeNames.backgroundcolor]}
+        # Interactive-Attributes
+        attributes[AttributeNames.onhover] = {"value":False, "value_type" : BooleanType}
+        attributes[AttributeNames.onhover_background_color] = {"value":"", "value_type" : ColorType}
+        attributes[AttributeNames.onhover_border_color] = {"value":"", "value_type" : ColorType}
+
+        return attributes
+
+    @classmethod
+    def _getCallbacks(cls, callbacks = None):
+        if callbacks is None:
+            callbacks = {}
+
+        callbacks["click"] = {"policy":None, "policy_type" : SymbolType}
+
+        return callbacks
+
+    #----------------------------------------------------------------------------------------------
+    #-----Attributes----
+    #----------------------------------------------------------------------------------------------
+
+    def _setBackgroundColor(self, elements, key = AttributeNames.backgroundcolor):
+        value = self._attributes[key]["value"]
+        self._widget.configure(background = value)
+    def _setOnHover(self, elements): 
+        on_hover = self._attributes[AttributeNames.onhover]["value"]
+        on_hover_color = self._attributes[AttributeNames.onhover_background_color]["value"]
+        on_hover_border_color = self._attributes[AttributeNames.onhover_border_color]["value"]
+
+        if on_hover:
+            def enter(event):
+                if on_hover_color != "":
+                    self._setBackgroundColor(elements, key = AttributeNames.onhover_background_color)
+                if on_hover_border_color != "":
+                    self._setBorderBackgroundColor(elements, key = AttributeNames.onhover_border_color)
+
+            def leave(event):
+                self._setBackgroundColor(elements, key = AttributeNames.backgroundcolor)
+                self._setBorderBackgroundColor(elements, key = AttributeNames.border_color)
+            
+            self._widget.bind('<Enter>', enter)
+            self._widget.bind('<Leave>', leave)
+ 
+    #----------------------------------------------------------------------------------------------
+    #-----Actions----
+    #----------------------------------------------------------------------------------------------
+       
+    def _defineClickEvent(self, elements, key = CallbackNames.click):
+        if self._callbacks[key] and self._callbacks[key]["policy"]:
+            def dropdownmenuitemClick(event):
+                self._base_engine.assume(self._callbacks[key]["policy"])
+
+            self._widget.bind('<Button-1>', dropdownmenuitemClick)
+
+
+
+
+
diff --git a/clinguin/client/presentation/guis/tkinter_gui/tkinter_widgets/dropdownmenu.py b/clinguin/client/presentation/guis/tkinter_gui/tkinter_widgets/dropdownmenu.py
new file mode 100644
index 00000000..84bbda67
--- /dev/null
+++ b/clinguin/client/presentation/guis/tkinter_gui/tkinter_widgets/dropdownmenu.py
@@ -0,0 +1,88 @@
+"""
+This module contains the Dropdownmenu class.
+"""
+import tkinter as tk
+
+from .root_cmp import *
+
+class Dropdownmenu(RootCmp, LayoutFollower, ConfigureSize):
+    """
+    The dropdownmenu is the master component for a dropdownmenu, i.e. dropdownmenu-items must be children of it. For available attributes see syntax definition. Implementation wise it is similarly implemented as the Label and Button - to make it work for layouting, the actual dropdownmenu is hidden and the widget is actually a tkinter frame (therefore self._widget is a frame, whereas self._menu is the dropdownmenu).
+    """
+    def __init__(self, args, id, parent, attributes, callbacks, base_engine):
+        super().__init__(args, id, parent, attributes, callbacks, base_engine)
+        
+        self._menu = None
+        self._variable = None
+
+
+    def _initWidget(self, elements):
+
+        option_menu_frame = tk.Frame(elements[str(self._parent)].getWidget())
+
+        self._variable = tk.StringVar()
+        items = []
+        menu = tk.OptionMenu(option_menu_frame, self._variable, "", *items)
+
+        self._menu = menu
+
+        return option_menu_frame
+
+    def getVariable(self):
+        return self._variable
+
+    @classmethod
+    def _getAttributes(cls, attributes = None):
+        if attributes is None:
+            attributes = {}
+
+        attributes[AttributeNames.backgroundcolor] = {"value":"white", "value_type" : ColorType}
+        attributes[AttributeNames.foregroundcolor] = {"value":"black", "value_type" : ColorType}
+        # Interactive-Attributes
+        attributes[AttributeNames.onhover] = {"value":False, "value_type": BooleanType}
+        attributes[AttributeNames.onhover_background_color] = {"value":"white", "value_type" : ColorType}
+        attributes[AttributeNames.onhover_foreground_color] = {"value":"black", "value_type" : ColorType}
+        
+        attributes[AttributeNames.selected] = {"value":"", "value_type" : StringType}
+ 
+        return attributes
+
+    def _setBackgroundColor(self, elements, key = AttributeNames.backgroundcolor):
+        value = self._attributes[key]["value"]
+        
+        self._menu.config(bg= value, activebackground=value)
+        self._menu["menu"].config(bg=value, activebackground=value)
+
+    def _setForegroundColor(self, elements, key = AttributeNames.foregroundcolor):
+        value = self._attributes[key]["value"]
+
+        self._menu.config(fg=value, activeforeground=value)
+        self._menu["menu"].config(fg=value, activeforeground=value)
+
+    def _setOnHover(self, elements): 
+        on_hover = self._attributes[AttributeNames.onhover]["value"]
+
+        on_hover_background_color = self._attributes[AttributeNames.onhover_background_color]["value"]
+
+        on_hover_foreground_color = self._attributes[AttributeNames.onhover_foreground_color]["value"]
+
+        if on_hover == "true":
+            self._menu.config(activebackground=on_hover_background_color, activeforeground=on_hover_foreground_color)
+            self._menu["menu"].config(activebackground=on_hover_background_color, activeforeground=on_hover_foreground_color)
+
+    def _setSelected(self, elements):
+        if self._attributes[AttributeNames.selected]['value'] != "":
+            self._variable.set(self._attributes[AttributeNames.selected]['value'])
+
+    def getMenu(self):
+        return self._menu
+
+    def _addComponentToElements(self, elements):
+        self._menu.pack(expand=True, fill='both')
+
+        elements[str(self._id)] = self
+
+
+
+
+
diff --git a/clinguin/client/presentation/guis/tkinter_gui/tkinter_widgets/dropdownmenu_item.py b/clinguin/client/presentation/guis/tkinter_gui/tkinter_widgets/dropdownmenu_item.py
new file mode 100644
index 00000000..6d20b44d
--- /dev/null
+++ b/clinguin/client/presentation/guis/tkinter_gui/tkinter_widgets/dropdownmenu_item.py
@@ -0,0 +1,76 @@
+"""
+Contains the DropdownmenuItem class.
+"""
+import tkinter as tk
+
+from .root_cmp import *
+
+class DropdownmenuItem(RootCmp):
+    """
+    Is an item of a dropdown, e.g. for the dropdownmenu countries, germany would be a dropdownmenu-item.
+    """
+
+    def _initWidget(self, elements):
+        parent = elements[str(self._parent)]
+        if hasattr(parent, "getMenu"):
+            menu = parent.getMenu()
+            return menu
+        else:
+            error_string = "Parent of dropdown menu item " + self._id + " is not a dropdown menu."
+            self._logger.error(error_string)
+            raise Exception(error_string)
+
+    @classmethod
+    def _getAttributes(cls, attributes = None):
+        if attributes is None:
+            attributes = {}
+
+        attributes[AttributeNames.label] = {"value":"", "value_type":StringType}
+
+        return attributes
+
+    @classmethod
+    def _getCallbacks(cls, callbacks = None):
+        if callbacks is None:
+            callbacks =  {}
+
+        callbacks[CallbackNames.click] = {"policy":None, "policy_type" : SymbolType}
+
+        return callbacks
+
+    def _defineClickEvent(self, elements, key = CallbackNames.click):
+        if self._callbacks[key]:
+            self._widget['menu'].add_command(
+                label=self._attributes[AttributeNames.label]["value"],
+                command=CallBackDefinition(
+                    self._id,
+                    self._parent,
+                    self._callbacks[key]['policy'],
+                    elements,
+                    self._dropdownmenuitemClick))
+
+    def _dropdownmenuitemClick(self, id, parent_id, click_policy, elements):
+        parent = elements[str(parent_id)]
+        if hasattr(parent, "getVariable"):
+            variable = getattr(parent, "getVariable")()
+            variable.set(id)
+            if click_policy is not None:
+                self._base_engine.postWithPolicy(click_policy)
+        else:
+            self._logger.warning("Could not set variable for dropdownmenu. Item id: %s, dropdown-menu-id: %s", str(id), str(parent_id))
+
+    def forgetChildren(self, elements):
+        pass
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/clinguin/client/presentation/guis/tkinter_gui/tkinter_widgets/label.py b/clinguin/client/presentation/guis/tkinter_gui/tkinter_widgets/label.py
new file mode 100644
index 00000000..e55cb6d5
--- /dev/null
+++ b/clinguin/client/presentation/guis/tkinter_gui/tkinter_widgets/label.py
@@ -0,0 +1,110 @@
+"""
+This module contains the Label class.
+"""
+import tkinter as tk
+
+from .root_cmp import *
+
+class Label(RootCmp, LayoutFollower, ConfigureSize, ConfigureFont):
+    """
+    The label can be used for positiion text. For available attributes see syntax definition. Implementation wise it is similarly implemented as the Dropdowmenu and Button - to make it work for layouting, the actual label is hidden and the widget is actually a tkinter frame (therefore self._widget is a frame, whereas self._label is the label).
+    """
+    def __init__(self, args, id, parent, attributes, callbacks, base_engine):
+        super().__init__(args, id, parent, attributes, callbacks, base_engine)
+        self._configure_font_widget = None
+        self._label = None
+
+    def _initWidget(self, elements):
+        label_frame = tk.Frame(elements[str(self._parent)].getWidget())
+
+        self._label = tk.Label(label_frame)
+        self._configure_font_widget = self._label
+
+        return label_frame
+
+    @classmethod
+    def _getAttributes(cls, attributes = None):
+        if attributes is None:
+            attributes = {}
+
+        attributes[AttributeNames.label] = {"value":"", "value_type" : StringType}
+        attributes[AttributeNames.backgroundcolor] = {"value":"white", "value_type" : ColorType}
+        attributes[AttributeNames.foregroundcolor] = {"value":"black", "value_type" : ColorType}
+        # Interactive-Attributes
+        attributes[AttributeNames.onhover] = {"value":False, "value_type" : BooleanType}
+        attributes[AttributeNames.onhover_background_color] = {"value":"white", "value_type" : ColorType}
+        attributes[AttributeNames.onhover_foreground_color] = {"value":"black", "value_type" : ColorType}
+        return attributes
+
+    @classmethod
+    def _getCallbacks(cls, callbacks = None):
+        if callbacks is None:
+            callbacks = {}
+
+        callbacks[CallbackNames.click] = {"policy":None, "policy_type": SymbolType}
+
+        return callbacks
+
+    #----------------------------------------------------------------------------------------------
+    #-----Standard-Attributes----
+    #----------------------------------------------------------------------------------------------
+
+    def _setLabelText(self, elements, key = AttributeNames.label):
+        text = self._attributes[key]["value"]
+        self._label.configure(text = text)
+
+    def _setBackgroundColor(self, elements, key = AttributeNames.backgroundcolor):
+        value = self._attributes[key]["value"]
+        self._label.configure(background = value)
+
+    def _setForegroundColor(self, elements, key = AttributeNames.foregroundcolor):
+        value = self._attributes[key]["value"]
+        self._label.configure(foreground = value)
+
+    #----------------------------------------------------------------------------------------------
+    #-----Special-Attributes----
+    #----------------------------------------------------------------------------------------------
+
+    def _setOnHover(self, elements): 
+        on_hover = self._attributes[AttributeNames.onhover]["value"]
+        on_hover_background_color = self._attributes[AttributeNames.onhover_background_color]["value"]
+
+        on_hover_foreground_color = self._attributes[AttributeNames.onhover_foreground_color]["value"]
+
+        if on_hover:
+            def enter(event):
+                if on_hover_background_color != "":
+                    self._setBackgroundColor(elements, key = AttributeNames.onhover_background_color)
+                if on_hover_foreground_color != "":
+                    self._setForegroundColor(elements, key = AttributeNames.onhover_foreground_color)
+
+            def leave(event):
+                self._setBackgroundColor(elements, key = AttributeNames.backgroundcolor)
+                self._setForegroundColor(elements, key= AttributeNames.foregroundcolor)
+    
+            self._label.bind('<Enter>', enter)
+            self._label.bind('<Leave>', leave)
+
+ 
+    #----------------------------------------------------------------------------------------------
+    #-----Actions----
+    #----------------------------------------------------------------------------------------------
+       
+    def _defineClickEvent(self, elements):
+        key = CallbackNames.click
+        if self._callbacks[key] and self._callbacks[key]["policy"]:
+            def clickEvent(event):
+                self._base_engine.postWithPolicy(self._callbacks[key]["policy"])
+
+            self._label.bind('<Button-1>', clickEvent)
+
+    def _addComponentToElements(self, elements):
+        self._label.pack(expand=True, fill='both')
+
+        elements[str(self._id)] = self
+
+
+
+
+
+
diff --git a/clinguin/client/presentation/tkinter/menu_bar.py b/clinguin/client/presentation/guis/tkinter_gui/tkinter_widgets/menu_bar.py
similarity index 60%
rename from clinguin/client/presentation/tkinter/menu_bar.py
rename to clinguin/client/presentation/guis/tkinter_gui/tkinter_widgets/menu_bar.py
index 60ac47e2..de0033ea 100644
--- a/clinguin/client/presentation/tkinter/menu_bar.py
+++ b/clinguin/client/presentation/guis/tkinter_gui/tkinter_widgets/menu_bar.py
@@ -1,11 +1,14 @@
+"""
+This module features the MenuBar class.
+"""
 import tkinter as tk
 
-from clinguin.client.presentation.tkinter.root_cmp import RootCmp
-
-from clinguin.client.presentation.tkinter.attribute_names import AttributeNames
-from clinguin.client.presentation.tkinter.callback_names import CallbackNames
+from .root_cmp import *
 
 class MenuBar(RootCmp):
+    """
+    The MenuBar is the class which resembles the menu-bar in tkinter. There must only be one in a clinguin ui file.
+    """
 
     def _initWidget(self, elements):
         parent_widget = elements[self._parent].getWidget()
diff --git a/clinguin/client/presentation/tkinter/menu_bar_section.py b/clinguin/client/presentation/guis/tkinter_gui/tkinter_widgets/menu_bar_section.py
similarity index 52%
rename from clinguin/client/presentation/tkinter/menu_bar_section.py
rename to clinguin/client/presentation/guis/tkinter_gui/tkinter_widgets/menu_bar_section.py
index 5bff4d17..51ce1fae 100644
--- a/clinguin/client/presentation/tkinter/menu_bar_section.py
+++ b/clinguin/client/presentation/guis/tkinter_gui/tkinter_widgets/menu_bar_section.py
@@ -1,12 +1,14 @@
+"""
+Module contains the menu bar section class.
+"""
 import tkinter as tk
 
-from clinguin.client.presentation.tkinter.root_cmp import RootCmp
-from clinguin.client.presentation.tkinter.standard_text_processing import StandardTextProcessing
-
-from clinguin.client.presentation.tkinter.attribute_names import AttributeNames
-from clinguin.client.presentation.tkinter.callback_names import CallbackNames
+from .root_cmp import *
 
 class MenuBarSection(RootCmp):
+    """
+    The menu bar section is a section of a menu bar (e.g. in the menu \|main\|contact\|, where if one clicks on \|contact\| further the options \|location\|team\| appear, a menu-bar-section would be \|contact\|, whereas \|location\| and \|team\| would be menu-bar-section-items.
+    """
 
     def _initWidget(self, elements):
         menubar_widget = elements[self._parent].getWidget()
@@ -16,18 +18,17 @@ def _initWidget(self, elements):
         return menubar_section
 
     @classmethod
-    def getAttributes(cls):
-        attributes = {}
+    def _getAttributes(cls, attributes = None):
+        if attributes is None:
+            attributes = {}
 
-        attributes[AttributeNames.label] = {"value":"default_label"}
+        attributes[AttributeNames.label] = {"value":"default_label", "value_type" : StringType}
 
         return attributes
 
 
     def _setSubMenu(self, elements):
-        value = self._attributes[AttributeNames.label]["value"]
-
-        text = StandardTextProcessing.parseStringWithQuotes(value)
+        text = self._attributes[AttributeNames.label]["value"]
 
         menubar_widget = elements[self._parent].getWidget()
         menubar_widget.add_cascade(label=text, menu=self._widget)
diff --git a/clinguin/client/presentation/tkinter/menu_bar_section_item.py b/clinguin/client/presentation/guis/tkinter_gui/tkinter_widgets/menu_bar_section_item.py
similarity index 55%
rename from clinguin/client/presentation/tkinter/menu_bar_section_item.py
rename to clinguin/client/presentation/guis/tkinter_gui/tkinter_widgets/menu_bar_section_item.py
index e2cbb5d9..8b361a91 100644
--- a/clinguin/client/presentation/tkinter/menu_bar_section_item.py
+++ b/clinguin/client/presentation/guis/tkinter_gui/tkinter_widgets/menu_bar_section_item.py
@@ -1,14 +1,12 @@
-import tkinter as tk
-
-from clinguin.client.presentation.tkinter.root_cmp import RootCmp
-from clinguin.client.presentation.tkinter.call_back_definition import CallBackDefinition
-from clinguin.client.presentation.tkinter.standard_text_processing import StandardTextProcessing
-
-from clinguin.client.presentation.tkinter.attribute_names import AttributeNames
-from clinguin.client.presentation.tkinter.callback_names import CallbackNames
-
+"""
+Contains the menu bar section item class.
+"""
+from .root_cmp import *
 
 class MenuBarSectionItem(RootCmp):
+    """
+    The menu bar section is a section of a menu bar (e.g. in the menu \|main\|contact\|, where if one clicks on \|contact\| further the options \|location\|team\| appear, a menu-bar-section would be \|contact\|, whereas \|location\| and \|team\| would be menu-bar-section-items.
+    """
 
     def _initWidget(self, elements):
         menubar_section = elements[self._parent].getWidget()
@@ -16,26 +14,27 @@ def _initWidget(self, elements):
         return menubar_section
 
     @classmethod
-    def getAttributes(cls):
-        attributes = {}
+    def _getAttributes(cls, attributes = None):
+        if attributes is None:
+            attributes = {}
 
-        attributes[AttributeNames.label] = {"value":"standard_label"}
+        attributes[AttributeNames.label] = {"value":"standard_label", "value_type" : StringType}
 
         return attributes
 
 
     @classmethod
-    def getCallbacks(cls):
-        callbacks = {}
+    def _getCallbacks(cls, callbacks = None):
+        if callbacks is None:
+            callbacks = {}
 
-        callbacks[CallbackNames.click] = {"policy":None}
+        callbacks[CallbackNames.click] = {"policy":None, "policy_type" : SymbolType}
 
         return callbacks
 
     def _defineClickEvent(self, elements):
         key = CallbackNames.click
-        value = self._attributes[AttributeNames.label]["value"]
-        text = StandardTextProcessing.parseStringWithQuotes(value)
+        text = self._attributes[AttributeNames.label]["value"]
 
         if self._callbacks[key] and self._callbacks[key]["policy"]:
             self._widget.add_command(
@@ -52,8 +51,8 @@ def _defineClickEvent(self, elements):
 
 
     def _menubarItemClick(self, id, parent, click_policy, elements):
-        if (click_policy is not None):
-            self._base_engine.assume(click_policy)
+        if click_policy is not None:
+            self._base_engine.postWithPolicy(click_policy)
  
     def _addComponentToElements(self, elements):
         elements[str(self._id)] = self
diff --git a/clinguin/client/presentation/guis/tkinter_gui/tkinter_widgets/message.py b/clinguin/client/presentation/guis/tkinter_gui/tkinter_widgets/message.py
new file mode 100644
index 00000000..dc687445
--- /dev/null
+++ b/clinguin/client/presentation/guis/tkinter_gui/tkinter_widgets/message.py
@@ -0,0 +1,45 @@
+"""
+Contains the Message class.
+"""
+import tkinter as tk
+# This import is used implicitly
+import tkinter.messagebox
+
+from .root_cmp import *
+
+class Message(RootCmp):
+    """
+    A message is a pop up, which has a type a title and a message.
+    """
+
+
+    def _initWidget(self, elements):
+        message = tk.Message(elements[str(self._parent)].getWidget())
+        return message
+
+    @classmethod
+    def _getAttributes(cls, attributes = None):
+        if attributes is None:
+            attributes = {}
+
+        attributes[AttributeNames.type] = {"value":PopupTypesType.INFO, "value_type" : PopupTypesType}
+        attributes[AttributeNames.title] = {"value":"", "value_type" : StringType}
+        attributes[AttributeNames.message] = {"value":"", "value_type" : StringType}
+
+        return attributes
+
+    def _setValues(self, elements):
+
+        type = self._attributes[AttributeNames.type]["value"]
+        title = self._attributes[AttributeNames.title]["value"]
+        message = self._attributes[AttributeNames.message]["value"]
+
+        if PopupTypesType.INFO == type:
+            tk.messagebox.showinfo(title=title, message=message)
+        elif PopupTypesType.WARNING == type:
+            tk.messagebox.showwarning(title=title, message=message)
+        elif PopupTypesType.ERROR == type:
+            tk.messagebox.showerror(title=title, message=message)
+        else:
+            self._logger.warning("Cannot display popup-type %s", type)
+
diff --git a/clinguin/client/presentation/tkinter/root_cmp.py b/clinguin/client/presentation/guis/tkinter_gui/tkinter_widgets/root_cmp.py
similarity index 53%
rename from clinguin/client/presentation/tkinter/root_cmp.py
rename to clinguin/client/presentation/guis/tkinter_gui/tkinter_widgets/root_cmp.py
index bf3caa87..33bdad28 100644
--- a/clinguin/client/presentation/tkinter/root_cmp.py
+++ b/clinguin/client/presentation/guis/tkinter_gui/tkinter_widgets/root_cmp.py
@@ -1,6 +1,18 @@
+"""
+Contains the RootCmp class.
+"""
 import logging
+from clinguin.utils.attribute_types import *
+from ..tkinter_utils import *
 
 class RootCmp:
+    """
+    Every tkinter widget must be a subtype of the RootCmp. It further features standard implementations of various methods, therefore one must just implement a handful of methods if one implements a new widget, these are (see e.g. the button.py for a sample implementation):
+    - _getAttributes(attributes = None)
+    - _getCallbacks(callbacks = None)
+    - Every method, which name starts with ''_set'' will be executed and are designed to be used for setting the attributes.
+    - Every method, which name starts with ''_define'' will be executed and are designet to specify callbacks.
+    """
 
     def __init__(self, args, id, parent, attributes, callbacks, base_engine):
         self._logger = logging.getLogger(args.log_args['name'])
@@ -11,14 +23,38 @@ def __init__(self, args, id, parent, attributes, callbacks, base_engine):
         self._base_engine = base_engine
         self._widget = None
 
+        self._attributes = None
+        self._callbacks = None
+
     @classmethod
     def getAttributes(cls):
+
+        attributes = {} 
+        for base in cls.__bases__:
+            if issubclass(base, ExtensionClass):
+                base.getAttributes(attributes)
+        
+        return cls._getAttributes(attributes)
+
+    @classmethod
+    def _getAttributes(cls, attributes = None):
         return {}
 
+
     @classmethod
     def getCallbacks(cls):
+        callbacks = {} 
+        for base in cls.__bases__:
+            if issubclass(base, ExtensionClass):
+                base.getCallbacks(callbacks)
+        
+        return cls._getCallbacks(callbacks)
+    
+    @classmethod
+    def _getCallbacks(cls, callbacks = None):
         return {}
 
+
     def getWidget(self):
         return self._widget
 
@@ -40,24 +76,32 @@ def _initWidget(self, elements):
         return None
 
     def _fillAttributes(self):
-         for attribute in self._json_attributes:
+        for attribute in self._json_attributes:
             key = attribute['key']
             value = attribute['value']
+            if key in self._attributes and 'value_type' in self._attributes[key]:
+                value_type = self._attributes[key]['value_type']
+            else:
+                value_type = StringType
 
             if key in self._attributes and "value" in self._attributes[key]:
-                self._attributes[key]["value"] = value
+                self._attributes[key]["value"] = value_type.parse(value, self._logger)
             else:
-                self._logger.warn('Undefined Command: ' + key + ' for element: ' + attribute['id'])
+                self._logger.warning('Undefined Command: ' + key + ' for element: ' + attribute['id'])
 
     def _fillCallbacks(self):
         for callback in self._json_callbacks:
             key = callback['action']
             value = callback['policy']
+            if key in self._callbacks and 'policy_type' in self._callbacks[key]:
+                value_type = self._callbacks[key]['policy_type']
+            else:
+                value_type = SymbolType
 
             if key in self._callbacks and "policy" in self._callbacks[key]:
-                self._callbacks[key]["policy"] = value
+                self._callbacks[key]["policy"] = value_type.parse(value, self._logger)
             else:
-                self._logger.warn('Undefined Command: ' + key + ", or policy item missing in command.")
+                self._logger.warning('Undefined Command: %s, or policy item missing in command.', key)
 
     def _getMethods(self, start_string):
 
@@ -87,9 +131,9 @@ def forgetChildren(self, elements):
         if str(self._parent) in elements:
             if hasattr(elements[self._parent], "getChildOrg"):
                 parent_org = getattr(elements[self._parent], "getChildOrg")()
-                if parent_org == "flex" or parent_org == "absstatic" or parent_org =="relstatic":
+                if parent_org in (ChildLayoutType.FLEX, ChildLayoutType.RELSTATIC, ChildLayoutType.ABSSTATIC):
                     self._widget.pack_forget()
-                elif parent == "grid":
+                elif parent_org == ChildLayoutType.GRID:
                     self._widget.grid_forget()
                 else:
                     self._widget.forget()
diff --git a/clinguin/client/presentation/guis/tkinter_gui/tkinter_widgets/window.py b/clinguin/client/presentation/guis/tkinter_gui/tkinter_widgets/window.py
new file mode 100644
index 00000000..146d9d45
--- /dev/null
+++ b/clinguin/client/presentation/guis/tkinter_gui/tkinter_widgets/window.py
@@ -0,0 +1,71 @@
+"""
+Contains the window class.
+"""
+import tkinter as tk
+
+from .root_cmp import *
+
+class Window(RootCmp, LayoutController):
+    """
+    The window class is the top-lvl. component, therefore it MUST be used in every clinguin application! For available attributes see syntax definition.
+    """
+
+    def _initWidget(self, elements):
+        window = tk.Tk()
+        window.title("Clinguin")
+
+        return window
+
+    @classmethod
+    def _getAttributes(cls, attributes = None):
+        if attributes is None:
+            attributes = {}
+
+        attributes[AttributeNames.backgroundcolor] = {"value":"white", "value_type" : ColorType}
+        attributes[AttributeNames.width] = {"value":0, "value_type" : IntegerType}
+        attributes[AttributeNames.height] = {"value":0, "value_type" : IntegerType}
+        attributes[AttributeNames.pos_x] = {"value":-1, "value_type": IntegerType}
+        attributes[AttributeNames.pos_y] = {"value":-1, "value_type": IntegerType}
+        attributes[AttributeNames.resizable_x] = {"value":1, "value_type" : IntegerType}
+        attributes[AttributeNames.resizable_y] = {"value":1, "value_type" : IntegerType}
+
+        return attributes
+
+    def _setBackgroundColor(self, elements, key = AttributeNames.backgroundcolor):
+        value = self._attributes[key]["value"]
+        self._widget.configure(background = value)
+
+    def _setDimensions(self, elements):
+        width = self._attributes[AttributeNames.width]["value"]
+        height = self._attributes[AttributeNames.height]["value"]
+
+        pos_x = self._attributes[AttributeNames.pos_x]["value"]
+        pos_y = self._attributes[AttributeNames.pos_y]["value"]
+
+        if height > 0 and width > 0:
+            child_layout_value = self._attributes[AttributeNames.child_layout]["value"]
+
+            if child_layout_value in (ChildLayoutType.FLEX, ChildLayoutType.RELSTATIC, ChildLayoutType.ABSSTATIC):
+                self._widget.pack_propagate(0)
+            elif child_layout_value == ChildLayoutType.GRID:
+                self._widget.grid_propagate(0)
+        
+            if pos_x < 0:
+                pos_x = int((int(self._widget.winfo_screenwidth()) - int(width)) / 2)
+            if pos_y < 0:
+                pos_y = int((int(self._widget.winfo_screenheight()) - int(height))/2)
+            
+            self._widget.geometry(str(width) + 'x' +
+                str(height) + '+' +
+                str(pos_x) + '+' +
+                str(pos_y))
+
+        elif (height > 0 and width <= 0) or (height <= 0 and width > 0):
+            self._logger.warning("For the tkinter window one must set both height and width to positive values (not just one).")
+
+    def _setResizable(self, elements):
+        self._widget.resizable(self._attributes[AttributeNames.resizable_x]['value'],self._attributes[AttributeNames.resizable_y]['value'])
+    def _addComponentToElements(self, elements):
+        elements[str(self._id)] = self
+
+
diff --git a/clinguin/client/presentation/tkinter/attribute_names.py b/clinguin/client/presentation/tkinter/attribute_names.py
deleted file mode 100644
index 964661a1..00000000
--- a/clinguin/client/presentation/tkinter/attribute_names.py
+++ /dev/null
@@ -1,38 +0,0 @@
-
-class AttributeNames:
-
-    label = "label"
-    backgroundcolor = "backgroundcolor"
-    foregroundcolor = "foregroundcolor"
-    width = "width"
-    height = "height"
-
-    onhover = "onhover"
-    onhover_background_color = "onhoverbackgroundcolor"
-    onhover_foreground_color = "onhoverforegroundcolor"
-    onhover_border_color = "onhoverbordercolor"
-
-    font_family = "fontfamily"
-    font_size = "fontsize"
-    font_weight = "fontweight"
-
-    resizable_x = "resizablex"
-    resizable_y = "resizabley"
-    child_org = "childorg"
-    grid_column = "gridcolumn"
-    grid_row = "gridrow"
-    grid_column_span = "gridcolumnspan"
-    grid_row_span = "gridrowspan"
-    pos_x = "posx"
-    pos_y = "posy"
-
-    border_width = "borderwidth"
-    border_color = "bordercolor"
-
-    selected = "selected"
-
-
-    descriptions = {
-        backgroundcolor : "Define the background color of the container, simple colors can be set by a string-specifying the color (like white), complex ones can be set by \"#RRRGGGBBB\", where each R, G and B is a Hex number (e.g. black: \"#000000000\", red: \"#fff000000\", green: \"#000fff000\", blue: \"#000000fff\")."
-        }
-
diff --git a/clinguin/client/presentation/tkinter/button.py b/clinguin/client/presentation/tkinter/button.py
deleted file mode 100644
index 792c39e3..00000000
--- a/clinguin/client/presentation/tkinter/button.py
+++ /dev/null
@@ -1,127 +0,0 @@
-from tkinter import font
-import tkinter as tk
-
-from clinguin.client.presentation.tkinter.root_cmp import RootCmp
-from clinguin.client.presentation.tkinter.standard_text_processing import StandardTextProcessing
-
-from clinguin.client.presentation.tkinter.attribute_names import AttributeNames
-from clinguin.client.presentation.tkinter.callback_names import CallbackNames
-
-
-class Button(RootCmp):
-
-
-    def _initWidget(self, elements):
-        button = tk.Button(elements[str(self._parent)].getWidget())
-        return button
-
-    @classmethod
-    def getAttributes(cls):
-        attributes = {}
-        # Label/Text
-        attributes[AttributeNames.label] = {"value":""}
-        # Color
-        attributes[AttributeNames.backgroundcolor] = {"value":"white"}
-        attributes[AttributeNames.foregroundcolor] = {"value":"black"}
-        # Geom
-        attributes[AttributeNames.width] = {"value":str(50)}
-        attributes[AttributeNames.height] = {"value":str(50)}
-        # Interactive-Attributes
-        attributes[AttributeNames.onhover] = {"value":"false"}
-        attributes[AttributeNames.onhover_background_color] = {"value":"white"}
-        attributes[AttributeNames.onhover_foreground_color] = {"value":"black"}
-        # Font
-        attributes[AttributeNames.font_family] = {"value":"Helvetica"}
-        attributes[AttributeNames.font_size] = {"value":str(12)}
-        attributes[AttributeNames.font_weight] = {"value":"normal"}
-
-        return attributes
-
-    @classmethod
-    def getCallbacks(cls):
-        callbacks = {}
-
-        callbacks[CallbackNames.click] = {"policy":None}
-
-        return callbacks
-
-    #----------------------------------------------------------------------------------------------
-    #-----Attributes----
-    #----------------------------------------------------------------------------------------------
-
-    def _setLabelText(self, elements):
-        text = self._attributes[AttributeNames.label]["value"]
-        text = StandardTextProcessing.parseStringWithQuotes(text)
-        self._widget.configure(text = text)
-
-    def _setBackgroundColor(self, elements, key = AttributeNames.backgroundcolor):
-        value = StandardTextProcessing.parseStringWithQuotes(self._attributes[key]["value"])
-        self._widget.configure(background = value)
-
-    def _setForegroundColor(self, elements, key = AttributeNames.foregroundcolor):
-        value = StandardTextProcessing.parseStringWithQuotes(self._attributes[key]["value"])
-        self._widget.configure(foreground = value)
-
-    def _setWidth(self, elements):
-        value = self._attributes[AttributeNames.width]["value"]
-        if value.isdigit():
-            self._widget.configure(width = int(value))
-        else:
-            self._logger.warn("For element " + self._id + " ,setWidth for width is not a digit: " + value)
-
-    def _setHeight(self, elements):
-        value = self._attributes[AttributeNames.height]["value"]
-        if value.isdigit():
-            self._widget.configure(height = int(value))
-        else:
-            self._logger.warn("For element " + self._id + " ,setHeight for height  is not a digit: " + value)
-  
-    def _setOnHover(self, elements): 
-        on_hover = self._attributes[AttributeNames.onhover]["value"]
-        on_hover_background_color = self._attributes[AttributeNames.onhover_background_color]["value"]
-        on_hover_background_color = StandardTextProcessing.parseStringWithQuotes(on_hover_background_color)
-
-        on_hover_foreground_color = self._attributes[AttributeNames.onhover_foreground_color]["value"]
-        on_hover_foreground_color = StandardTextProcessing.parseStringWithQuotes(on_hover_foreground_color)
-
-        if on_hover == "true":
-            def enter(event):
-                if on_hover_background_color != "":
-                    self._setBackgroundColor(elements, key = AttributeNames.onhover_background_color)
-                if on_hover_foreground_color != "":
-                    self._setForegroundColor(elements, key = AttributeNames.onhover_foreground_color)
-
-            def leave(event):
-                self._setBackgroundColor(elements)
-                self._setForegroundColor(elements)
-    
-            self._widget.bind('<Enter>', enter)
-            self._widget.bind('<Leave>', leave)
-
-    def _setFont(self, elements):
-
-        afont = font.Font(family=self._attributes[AttributeNames.font_family]["value"],
-            size = int(self._attributes[AttributeNames.font_size]["value"]), weight = self._attributes[AttributeNames.font_weight]["value"])
-        self._widget.configure(font=afont)
- 
-    #----------------------------------------------------------------------------------------------
-    #-----Actions----
-    #----------------------------------------------------------------------------------------------
-       
-    def _defineClickEvent(self, elements):
-        key = CallbackNames.click
-        if self._callbacks[key] and self._callbacks[key]["policy"]:
-            def clickEvent(event):
-                self._base_engine.assume(self._callbacks[key]["policy"])
-
-            self._widget.bind('<Button-1>', clickEvent)
-
-    def _addComponentToElements(self, elements):
-        self._widget.pack(expand=True)
-        elements[str(self._id)] = self
-
-
-
-
-
-
diff --git a/clinguin/client/presentation/tkinter/callback_names.py b/clinguin/client/presentation/tkinter/callback_names.py
deleted file mode 100644
index c2cef176..00000000
--- a/clinguin/client/presentation/tkinter/callback_names.py
+++ /dev/null
@@ -1,7 +0,0 @@
-
-class CallbackNames:
-
-    click = "click"
-
-    descriptions = {}
-
diff --git a/clinguin/client/presentation/tkinter/container.py b/clinguin/client/presentation/tkinter/container.py
deleted file mode 100644
index 2bca98f4..00000000
--- a/clinguin/client/presentation/tkinter/container.py
+++ /dev/null
@@ -1,190 +0,0 @@
-import tkinter as tk
-
-from clinguin.client.presentation.tkinter.root_cmp import RootCmp
-from clinguin.client.presentation.tkinter.standard_text_processing import StandardTextProcessing
-
-from clinguin.client.presentation.tkinter.attribute_names import AttributeNames
-from clinguin.client.presentation.tkinter.callback_names import CallbackNames
-
-class Container(RootCmp):
-
-    def _initWidget(self, elements):
-        container = tk.Frame(elements[str(self._parent)].getWidget())
-        return container
-
-    @classmethod
-    def getAttributes(cls):
-        attributes = {}
-        attributes[AttributeNames.backgroundcolor] = {"value":"white", "description": "CUSTOM-BACKGROUND-COLOR-DESCRIPTION <- Now normal:" + AttributeNames.descriptions[AttributeNames.backgroundcolor]}
-        attributes[AttributeNames.width] = {"value":str(-1)}
-        attributes[AttributeNames.height] = {"value":str(-1)}
-        attributes[AttributeNames.child_org] = {"value":"flex"}
-        attributes[AttributeNames.border_width] = {"value":str(0)}
-        attributes[AttributeNames.border_color] = {"value":"black"}
-
-        # Layout-Control
-        attributes[AttributeNames.grid_column] = {"value":str(0)}
-        attributes[AttributeNames.grid_row] = {"value":str(0)}
-        attributes[AttributeNames.grid_column_span] = {"value":str(1)}
-        attributes[AttributeNames.grid_row_span] = {"value":str(1)}
-
-        attributes[AttributeNames.pos_x] = {"value":str(0)}
-        attributes[AttributeNames.pos_y] = {"value":str(0)}
-
-        # Interactive-Attributes
-        attributes[AttributeNames.onhover] = {"value":"false"}
-        attributes[AttributeNames.onhover_background_color] = {"value":""}
-        attributes[AttributeNames.onhover_border_color] = {"value":""}
-
-        return attributes
-
-    @classmethod
-    def getCallbacks(cls):
-        callbacks = {}
-
-        callbacks["click"] = {"policy":None}
-
-        return callbacks
-
-    #----------------------------------------------------------------------------------------------
-    #-----Attributes----
-    #----------------------------------------------------------------------------------------------
-
-    def _setBackgroundColor(self, elements, key = AttributeNames.backgroundcolor):
-        value = self._attributes[key]["value"]
-        value = StandardTextProcessing.parseStringWithQuotes(value)
-        self._widget.configure(background = value)
-
-    def _setWidth(self, elements, key = AttributeNames.width):
-        value = self._attributes[key]["value"]
-        if value.isdigit() and int(value) >= -1:
-            if int(value) >= 0:
-                self._widget.configure(width = int(value))
-        else:
-            self._logger.warn("For element " + self._id + " ,setWidth for " + key + " is not a digit: " + value)
-
-
-    def _setHeight(self, elements, key = AttributeNames.height):
-        value = self._attributes[key]["value"]
-        if value.isdigit() and int(value) >= -1:
-            if int(value) >= 0:
-                self._widget.configure(height = int(value))
-        else:
-            self._logger.warn("For element " + self._id + " ,setHeight for " + key + " is not a digit: " + value)
-
-    def _setChildOrg(self, elements, key = AttributeNames.child_org):
-        value = self._attributes[key]["value"]
-        self._child_org = value
-
-        if value == "flex" or value == "relstatic" or value == "absstatic":
-            self._widget.pack_propagate(0)
-        elif value == "grid":
-            self._widget.grid_propagate(0)
-        else:
-            self._logger.warn("For element " + self._id + " ,for the children-organisation (arg:  " + key + "), the value " + value + " is not a valid option")
-    
-    def getChildOrg(self):
-        return self._child_org
-        
-
-    def _setBorderWidth(self, elements, key = AttributeNames.border_width):
-        value = self._attributes[key]["value"]
-        if value.isdigit():
-            if int(value) > 0:
-                # Not using borderwidth as one cannot set the color of the default border
-                self._widget.configure(highlightthickness = int(value))
-        else:
-            self._logger.warn("For element " + self._id + " ,setBorderwidth for " + key + " is not a digit: " + value)
-
-
-    def _setBorderBackgroundColor(self, elements, key = AttributeNames.border_color):
-        # Not using borderwidth as one cannot set the color of the default border
-        value = self._attributes[key]["value"]
-        value = StandardTextProcessing.parseStringWithQuotes(value)
-        self._widget.configure(highlightbackground = value, highlightcolor = value)
-
-    def _setLayout(self, elements):
-        parent = elements[self._parent]
-        if hasattr(parent, "getChildOrg"):
-            parent_org = getattr(parent, "getChildOrg")()
-        else:
-            self._logger.warn("Could not find necessary attribute childOrg() in id: " + str(self._parent))
-            return
-
-        if parent_org == "flex":
-            self._widget.pack(fill='both')
-            self._widget.pack_propagate(0)               
-
-        elif parent_org == "grid":
-            grid_pos_column = self._attributes[AttributeNames.grid_column]['value']
-            grid_pos_row = self._attributes[AttributeNames.grid_row]['value']
-
-            grid_span_column = self._attributes[AttributeNames.grid_column_span]['value']
-            grid_span_row = self._attributes[AttributeNames.grid_row_span]['value']
-
-            if int(grid_pos_column) >= 0 and int(grid_pos_row) >= 0 and int(grid_span_column) >= 1 and int(grid_span_row) >= 1:
-                self._widget.grid(
-                    column=int(grid_pos_column), 
-                    row=int(grid_pos_row),
-                    columnspan=int(grid_span_column),
-                    rowspan = int(grid_span_row))
-                self._widget.grid_propagate(0)
-            else:
-                self._logger.warn("Could not set grid-layout due to illegal values for element: " + str(self._id)) 
-
-        elif parent_org == "absstatic" or parent_org =="relstatic":
-            x = self._attributes[AttributeNames.pos_x]["value"]
-            y = self._attributes[AttributeNames.pos_y]["value"]
-
-            if x.isdigit() and y.isdigit():
-                if int(x) >= 0 and int(y) >= 0:
-                    if parent_org == "absstatic":
-                        self._widget.place(
-                            x=int(x), 
-                            y=int(y))
-                        self._widget.pack_propagate(0)               
-                    elif parent_org == "relstatic":
-                        self._widget.place(
-                            relx=int(x)/100, 
-                            rely=int(y)/100)
-                        self._widget.pack_propagate(0)               
-                else:
-                    self._logger.warn("For element " + self._id + " ,either posx or posy are not non-negative-numbers.")
-                
-            else:
-                self._logger.warn("For element " + self._id + " ,either posx or posy are not numbers.")
-
-    def _setOnHover(self, elements): 
-        on_hover = self._attributes[AttributeNames.onhover]["value"]
-        on_hover_color = self._attributes[AttributeNames.onhover_background_color]["value"]
-        on_hover_border_color = self._attributes[AttributeNames.onhover_border_color]["value"]
-
-        if on_hover == "true":
-            def enter(event):
-                if on_hover_color != "":
-                    self._setBackgroundColor(elements, key = AttributeNames.onhover_background_color)
-                if on_hover_border_color != "":
-                    self._setBorderBackgroundColor(elements, key = AttributeNames.onhover_border_color)
-
-            def leave(event):
-                self._setBackgroundColor(elements, key = AttributeNames.backgroundcolor)
-                self._setBorderBackgroundColor(elements, key = AttributeNames.border_color)
-            
-            self._widget.bind('<Enter>', enter)
-            self._widget.bind('<Leave>', leave)
- 
-    #----------------------------------------------------------------------------------------------
-    #-----Actions----
-    #----------------------------------------------------------------------------------------------
-       
-    def _defineClickEvent(self, elements, key = CallbackNames.click):
-        if self._callbacks[key] and self._callbacks[key]["policy"]:
-            def dropdownmenuitemClick(event):
-                self._base_engine.assume(self._callbacks[key]["policy"])
-
-            self._widget.bind('<Button-1>', dropdownmenuitemClick)
-
-
-
-
-
diff --git a/clinguin/client/presentation/tkinter/dropdownmenu.py b/clinguin/client/presentation/tkinter/dropdownmenu.py
deleted file mode 100644
index 5c282235..00000000
--- a/clinguin/client/presentation/tkinter/dropdownmenu.py
+++ /dev/null
@@ -1,76 +0,0 @@
-
-import tkinter as tk
-
-from clinguin.client.presentation.tkinter.root_cmp import RootCmp
-from clinguin.client.presentation.tkinter.standard_text_processing import StandardTextProcessing
-
-from clinguin.client.presentation.tkinter.attribute_names import AttributeNames
-from clinguin.client.presentation.tkinter.callback_names import CallbackNames
-
-
-class Dropdownmenu(RootCmp):
-
-    def _initWidget(self, elements):
-        self._variable = tk.StringVar()
-        items = []
-        menu = tk.OptionMenu(elements[self._parent].getWidget(), self._variable, "", *items)
-
-        return menu
-
-    def getVariable(self):
-        return self._variable
-
-    @classmethod
-    def getAttributes(cls):
-        attributes = {}
-
-        attributes[AttributeNames.backgroundcolor] = {"value":"white"}
-        attributes[AttributeNames.foregroundcolor] = {"value":"black"}
-        # Interactive-Attributes
-        attributes[AttributeNames.onhover] = {"value":"false"}
-        attributes[AttributeNames.onhover_background_color] = {"value":"white"}
-        attributes[AttributeNames.onhover_foreground_color] = {"value":"black"}
-        
-        attributes[AttributeNames.selected] = {"value":""}
- 
-        return attributes
-
-    def _setBackgroundColor(self, elements, key = AttributeNames.backgroundcolor):
-        value = self._attributes[key]["value"]
-        value = StandardTextProcessing.parseStringWithQuotes(value)
-        
-        self._widget.config(bg= value, activebackground=value)
-        self._widget["menu"].config(bg=value, activebackground=value)
-
-    def _setForegroundColor(self, elements, key = AttributeNames.foregroundcolor):
-        value = self._attributes[key]["value"]
-        value = StandardTextProcessing.parseStringWithQuotes(value)
-
-        self._widget.config(fg=value, activeforeground=value)
-        self._widget["menu"].config(fg=value, activeforeground=value)
-
-    def _setOnHover(self, elements): 
-        on_hover = self._attributes[AttributeNames.onhover]["value"]
-
-        on_hover_background_color = self._attributes[AttributeNames.onhover_background_color]["value"]
-        on_hover_background_color = StandardTextProcessing.parseStringWithQuotes(on_hover_background_color)
-
-        on_hover_foreground_color = self._attributes[AttributeNames.onhover_foreground_color]["value"]
-        on_hover_foreground_color = StandardTextProcessing.parseStringWithQuotes(on_hover_foreground_color)
-
-        if on_hover == "true":
-            self._widget.config(activebackground=on_hover_background_color, activeforeground=on_hover_foreground_color)
-            self._widget["menu"].config(activebackground=on_hover_background_color, activeforeground=on_hover_foreground_color)
-
-    def _setSelected(self, elements):
-        if self._attributes[AttributeNames.selected]['value'] != "":
-            self._variable.set(self._attributes[AttributeNames.selected]['value'])
-
-    def _addComponentToElements(self, elements):
-        self._widget.pack(expand=True)
-        elements[str(self._id)] = self
-
-
-
-
-
diff --git a/clinguin/client/presentation/tkinter/dropdownmenu_item.py b/clinguin/client/presentation/tkinter/dropdownmenu_item.py
deleted file mode 100644
index 5b7d5741..00000000
--- a/clinguin/client/presentation/tkinter/dropdownmenu_item.py
+++ /dev/null
@@ -1,66 +0,0 @@
-import tkinter as tk
-
-from clinguin.client.presentation.tkinter.root_cmp import RootCmp
-from clinguin.client.presentation.tkinter.call_back_definition import CallBackDefinition
-
-from clinguin.client.presentation.tkinter.attribute_names import AttributeNames
-from clinguin.client.presentation.tkinter.callback_names import CallbackNames
-
-class DropdownmenuItem(RootCmp):
-
-    def _initWidget(self, elements):
-        menu = elements[str(self._parent)].getWidget()
-        return menu
-
-    @classmethod
-    def getAttributes(cls):
-        attributes = {}
-
-        attributes[AttributeNames.label] = {"value":""}
-
-        return attributes
-
-    @classmethod
-    def getCallbacks(cls):
-        callbacks =  {}
-
-        callbacks[CallbackNames.click] = {"policy":None}
-
-        return callbacks
-
-    def _defineClickEvent(self, elements, key = CallbackNames.click):
-        if self._callbacks[key]:
-            self._widget['menu'].add_command(
-                label=self._attributes[AttributeNames.label]["value"],
-                command=CallBackDefinition(
-                    self._id,
-                    self._parent,
-                    self._callbacks[key]['policy'],
-                    elements,
-                    self._dropdownmenuitemClick))
-
-    def _dropdownmenuitemClick(self, id, parent_id, click_policy, elements):
-        parent = elements[str(parent_id)]
-        if hasattr(parent, "getVariable"):
-            variable = getattr(parent, "getVariable")()
-            variable.set(id)
-            if (click_policy is not None):
-                self._base_engine.assume(click_policy)
-        else:
-            self._logger.warn("Could not set variable for dropdownmenu. Item id: " + str(id) + ", dropdown-menu-id: " + str(parent_id))
-
-    def forgetChildren(self, elements):
-        pass
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/clinguin/client/presentation/tkinter/label.py b/clinguin/client/presentation/tkinter/label.py
deleted file mode 100644
index 0fe777ad..00000000
--- a/clinguin/client/presentation/tkinter/label.py
+++ /dev/null
@@ -1,128 +0,0 @@
-from tkinter import font
-import tkinter as tk
-
-from clinguin.client.presentation.tkinter.root_cmp import RootCmp
-from clinguin.client.presentation.tkinter.standard_text_processing import StandardTextProcessing
-
-from clinguin.client.presentation.tkinter.attribute_names import AttributeNames
-from clinguin.client.presentation.tkinter.callback_names import CallbackNames
-
-class Label(RootCmp):
-
-    def _initWidget(self, elements):
-        label = tk.Label(elements[str(self._parent)].getWidget())
-        return label
-
-    @classmethod
-    def getAttributes(cls):
-        attributes = {}
-
-        attributes[AttributeNames.label] = {"value":""}
-        attributes[AttributeNames.backgroundcolor] = {"value":"white"}
-        attributes[AttributeNames.foregroundcolor] = {"value":"black"}
-        attributes[AttributeNames.width] = {"value":str(50)}
-        attributes[AttributeNames.height] = {"value":str(50)}
-        # Interactive-Attributes
-        attributes[AttributeNames.onhover] = {"value":"false"}
-        attributes[AttributeNames.onhover_background_color] = {"value":"white"}
-        attributes[AttributeNames.onhover_foreground_color] = {"value":"black"}
-
-        attributes[AttributeNames.font_family] = {"value":"Helvetica"}
-        attributes[AttributeNames.font_size] = {"value":str(12)}
-        attributes[AttributeNames.font_weight] = {"value":"normal"}
-
-        return attributes
-
-    @classmethod
-    def getCallbacks(cls):
-        callbacks = {}
-
-        callbacks[CallbackNames.click] = {"policy":None}
-
-        return callbacks
-
-    #----------------------------------------------------------------------------------------------
-    #-----Standard-Attributes----
-    #----------------------------------------------------------------------------------------------
-
-    def _setLabelText(self, elements, key = AttributeNames.label):
-        text = StandardTextProcessing.parseStringWithQuotes(self._attributes[key]["value"])
-        self._widget.configure(text = text)
-
-    def _setBackgroundColor(self, elements, key = AttributeNames.backgroundcolor):
-        value = StandardTextProcessing.parseStringWithQuotes(self._attributes[key]["value"])
-        self._widget.configure(background = value)
-
-    def _setForegroundColor(self, elements, key = AttributeNames.foregroundcolor):
-        value = StandardTextProcessing.parseStringWithQuotes(self._attributes[key]["value"])
-        self._widget.configure(foreground = value)
-
-    def _setWidth(self, elements, key = AttributeNames.width):
-        value = self._attributes[key]["value"]
-        if value.isdigit():
-            self._widget.configure(width = int(value))
-        else:
-            self._logger.warn("For element " + self._id + " ,setWidth for " + key + " is not a digit: " + value)
-
-    def _setHeight(self, elements, key = AttributeNames.height):
-        value = self._attributes[key]["value"]
-        if value.isdigit():
-            self._widget.configure(height = int(value))
-        else:
-            self._logger.warn("For element " + self._id + " ,setHeight for " + key + " is not a digit: " + value)
-
-    #----------------------------------------------------------------------------------------------
-    #-----Special-Attributes----
-    #----------------------------------------------------------------------------------------------
-
-    def _setOnHover(self, elements): 
-        on_hover = self._attributes[AttributeNames.onhover]["value"]
-        on_hover_background_color = self._attributes[AttributeNames.onhover_background_color]["value"]
-        on_hover_foreground_color = StandardTextProcessing.parseStringWithQuotes(on_hover_background_color)
-
-        on_hover_foreground_color = self._attributes[AttributeNames.onhover_foreground_color]["value"]
-        on_hover_foreground_color = StandardTextProcessing.parseStringWithQuotes(on_hover_foreground_color)
-
-        if on_hover == "true":
-            def enter(event):
-                if on_hover_background_color != "":
-                    self._setBackgroundColor(elements, key = AttributeNames.onhover_background_color)
-                if on_hover_foreground_color != "":
-                    self._setForegroundColor(elements, key = AttributeNames.onhover_foreground_color)
-
-            def leave(event):
-                self._setBackgroundColor(elements, key = AttributeNames.backgroundcolor)
-                self._setForegroundColor(elements, key= AttributeNames.foregroundcolor)
-    
-            self._widget.bind('<Enter>', enter)
-            self._widget.bind('<Leave>', leave)
-
-    def _setFont(self, elements):
-
-        afont = font.Font(family=self._attributes[AttributeNames.font_family]["value"],
-            size = int(self._attributes[AttributeNames.font_size]["value"]), weight = self._attributes[AttributeNames.font_weight]["value"])
-        self._widget.configure(font=afont)
-
-
- 
-    #----------------------------------------------------------------------------------------------
-    #-----Actions----
-    #----------------------------------------------------------------------------------------------
-       
-    def _defineClickEvent(self, elements):
-        key = CallbackNames.click
-        if self._callbacks[key] and self._callbacks[key]["policy"]:
-            def clickEvent(event):
-                self._base_engine.assume(self._callbacks[key]["policy"])
-
-            self._widget.bind('<Button-1>', clickEvent)
-
-    def _addComponentToElements(self, elements):
-        self._widget.pack(expand=True)
-        elements[str(self._id)] = self
-
-
-
-
-
-
diff --git a/clinguin/client/presentation/tkinter/window.py b/clinguin/client/presentation/tkinter/window.py
deleted file mode 100644
index 1036789a..00000000
--- a/clinguin/client/presentation/tkinter/window.py
+++ /dev/null
@@ -1,52 +0,0 @@
-import tkinter as tk
-
-from clinguin.client.presentation.tkinter.root_cmp import RootCmp
-from clinguin.client.presentation.tkinter.standard_text_processing import StandardTextProcessing
-
-from clinguin.client.presentation.tkinter.attribute_names import AttributeNames
-from clinguin.client.presentation.tkinter.callback_names import CallbackNames
-
-class Window(RootCmp):
-
-    def _initWidget(self, elements):
-        window = tk.Tk()
-        window.title("Clinguin")
-
-        return window
-
-    @classmethod
-    def getAttributes(cls):
-        attributes = {}
-
-        attributes[AttributeNames.backgroundcolor] = {"value":"white"}
-        attributes[AttributeNames.width] = {"value":str(250)}
-        attributes[AttributeNames.height] = {"value":str(250)}
-        attributes[AttributeNames.resizable_x] = {"value":str(1)}
-        attributes[AttributeNames.resizable_y] = {"value":str(1)}
-        attributes[AttributeNames.child_org] = {"value":"flex"}
-
-        return attributes
-
-    def _setBackgroundColor(self, elements, key = AttributeNames.backgroundcolor):
-        value = StandardTextProcessing.parseStringWithQuotes(self._attributes[key]["value"])
-        self._widget.configure(background = value)
-
-    def _setDimensions(self, elements):
-        self._widget.geometry(self._attributes[AttributeNames.width]['value'] + 'x' +
-            self._attributes[AttributeNames.height]['value'] + '+' +
-            str(int(self._widget.winfo_screenwidth()/2 - int(self._attributes[AttributeNames.width]['value'])/2)) + '+' +
-            str(int(self._widget.winfo_screenheight()/2 - int(self._attributes[AttributeNames.height]['value'])/2)))
-
-    def _setResizable(self, elements):
-        self._widget.resizable(self._attributes[AttributeNames.resizable_x]['value'],self._attributes[AttributeNames.resizable_y]['value'])
-
-    def _setChildOrg(self, elements):
-        self._child_org = self._attributes[AttributeNames.child_org]["value"]
-
-    def getChildOrg(self):
-        return self._child_org
-
-    def _addComponentToElements(self, elements):
-        elements[str(self._id)] = self
-
-
diff --git a/clinguin/client_helper.py b/clinguin/client_helper.py
index fb2a8697..6ce189aa 100644
--- a/clinguin/client_helper.py
+++ b/clinguin/client_helper.py
@@ -1,14 +1,14 @@
 """
 Helper for the client-startup-process
 """
-from clinguin.client.application.client_base import ClientBase
-from clinguin.utils.logger import Logger
+from clinguin.client import ClientBase
+from clinguin.utils import Logger
 
 def start(args):
     """
     Helper for the client-startup-process
     """
-    Logger.setupLogger(args.log_args)
+    Logger.setupLogger(args.log_args, process = "client")
 
     client = ClientBase(args)
     client.startUp()
diff --git a/clinguin/parse_input.py b/clinguin/parse_input.py
index 2db06142..e9aa394a 100644
--- a/clinguin/parse_input.py
+++ b/clinguin/parse_input.py
@@ -7,21 +7,30 @@
 import os
 import inspect
 import textwrap
-import glob
+import traceback
 
-from .server.application.clinguin_backend import ClinguinBackend
-from .client.presentation.abstract_gui import AbstractGui
-#from .client.presentation.tkinter.tkinter_gui import TkinterGui
+from .show_gui_syntax_enum import ShowGuiSyntaxEnum
+
+from .server import ClinguinBackend
+from .client import AbstractGui
 
 class ArgumentParser():
     """
     ArgumentParser-Class, Responsible for parsing the command line attributes
     """
 
-    default_solver = 'ClingoBackend'
+    default_backend_exec_string = "from .server.application.default_backends import *"    
+    default_client_exec_string = "from .client.presentation.guis import *"
+
+    default_backend = 'ClingoBackend'
     default_client = 'TkinterGui'
 
     def __init__(self) -> None:
+
+        self.client_name = None
+        self.client = None
+
+
         self.titles = {
             'client': self._client_title,
             'server': self._server_title,
@@ -31,8 +40,9 @@ def __init__(self) -> None:
             'client': 'Start a client process that will render a UI.',
             'server': 'Start server process making endpoints available for a client.',
             'client-server': 'Start client and a server processes.'}
-        self.solver_name = None
-        self.solver = None
+        self.backend_name = None
+        self.backend = None
+        self._show_gui_syntax = ShowGuiSyntaxEnum.NONE
 
     def parse(self):
         """
@@ -51,19 +61,18 @@ def parse(self):
             title="Process type",
             description='The type of process to start: a client (UI) a server (Backend) or both',
             dest='process')
-
         self._createClientSubparser(subparsers)
         self._createServerSubparser(subparsers)
         self._createClientServerSubparser(subparsers)
-
+ 
         args = parser.parse_args()
 
-        self._addSelectedSolver(args)
+        self._addSelectedBackend(args)
 
         return args
 
-    def _addSelectedSolver(self, args):
-        args.solver = self.solver
+    def _addSelectedBackend(self, args):
+        args.backend = self.backend
         args.client = self.client
 
     @property
@@ -105,39 +114,85 @@ def _clinguinDescription(self, process):
         if process not in ['server', 'client', 'client-server']:
             ascci = f"{self._clinguin_title}{description}"
             return f"{inspect.cleandoc(ascci)}\n\n{description}"
-        ascci = f"{self._clinguin_title}{self.titles[process]}"
-        return f"{inspect.cleandoc(ascci)}\n\n{description}\n{self.descriptions[process]}"
+        else:
+            ascci = f"{self._clinguin_title}{self.titles[process]}"
+            return f"{inspect.cleandoc(ascci)}\n\n{description}\n{self.descriptions[process]}"
 
     def _importClasses(self, path):
-        sys.path.append(path)
-        for name in glob.glob(path + '/*.py'):
-            base = os.path.basename(name)
+
+        if os.path.isfile(path):
+            sys.path.append(os.path.dirname(path))
+            self._importFilesFromPathArray([path])
+        else: 
+            sys.path.append(path)
+            self._recursiveImport(path, "", "")
+
+    def _importFilesFromPathArray(self,file_paths, module = ""):
+        for file_path in file_paths:
+            base = os.path.basename(file_path)
             file_name = os.path.splitext(base)[0]
-            importlib.import_module(file_name)
+            ending = os.path.splitext(base)[1]
+            if ending == ".py":
+                if module != "":
+                    try:
+                        importlib.import_module(module + "." + file_name)       
+                    except Exception:
+                        print("Could not import module: " + module + "." + file_name)
+                        print("<<<BEGIN-STACK-TRACE>>>")
+                        traceback.print_exc()
+                        print("<<<END-STACK-TRACE>>>")
+                else: 
+                    importlib.import_module(file_name)       
+
+    def _recursiveImport(self, full_path, rec_path, module):
+        folder_paths = []
+        file_paths = []
+        
+        try:
+            for entity in os.scandir(os.path.join(full_path, rec_path)):
+                if entity.is_dir():
+                    folder_paths.append(entity.path)
+                elif entity.is_file():
+                    file_paths.append(entity.path)
+        except Exception:
+            print("<<<BEGIN-STACK-TRACE>>>")
+            traceback.print_exc()
+            print("<<<END-STACK-TRACE>>>")
+            raise Exception("Could not find path for importing libraries: " + os.path.join(full_path, rec_path) + ". Therefore program is terminating now (full stacktrace is printed below).")
+            
+        self._importFilesFromPathArray(file_paths)
+
+        for folder_path in folder_paths:
+            base = os.path.basename(folder_path)
+            new_module = module
+            if new_module != "":
+                new_module = new_module + "." + base
+            else:
+                new_module = base
+
+            self._recursiveImport(full_path, os.path.join(rec_path, base), new_module)
 
     def _parseCustomClasses(self):
         custom_imports_parser = argparse.ArgumentParser(add_help=False)
-        custom_imports_parser.add_argument('--custom-server-classes', type=str,
-                                           help='Location of custom classes')
-        self._addDefaultArgumentsToSolverParser(custom_imports_parser)
-        
-        custom_imports_parser.add_argument('--custom-client-classes', type=str,
-                                           help='Location of custom classes')
+        self._addDefaultArgumentsToBackendParser(custom_imports_parser)
         self._addDefaultArgumentsToClientParser(custom_imports_parser)
 
         args, _ = custom_imports_parser.parse_known_args()
     
         self.client_name = args.client
-        self.solver_name = args.solver
-        if args.custom_server_classes:
-            self._importClasses(args.custom_server_classes)
-        else:
-            self._importClasses('./clinguin/server/application/default_solvers')
+        self.backend_name = args.backend
+        if args.custom_classes:
+            self._importClasses(args.custom_classes)
 
-        if args.custom_client_classes:
-            self._importClasses(args.custom_client_classes)
-        else:
-            self._importClasses('./clinguin/client/presentation/tkinter')
+        exec(ArgumentParser.default_backend_exec_string)
+        exec(ArgumentParser.default_client_exec_string)
+
+
+        if args.gui_syntax and not args.gui_syntax_full:
+            self._show_gui_syntax = ShowGuiSyntaxEnum.SHOW
+        elif args.gui_syntax_full:
+            self._show_gui_syntax = ShowGuiSyntaxEnum.FULL
+        
 
     def _createClientSubparser(self, subparsers):
         parser_client = subparsers.add_parser(
@@ -147,9 +202,7 @@ def _createClientSubparser(self, subparsers):
             add_help=True,
             formatter_class=argparse.RawTextHelpFormatter)
 
-        self._addCustomClientsArguments(parser_client)
-
-        self._addLogArguments(parser_client, abbrevation='C', logger_name = 'client')       
+        self._addLogArguments(parser_client, abbrevation='C', logger_name = 'clinguin_client')       
 
         self._addDefaultArgumentsToClientParser(parser_client)
         self.client = self._selectSubclassAndAddCustomArguments(parser_client, AbstractGui, self.client_name, ArgumentParser.default_client)
@@ -164,11 +217,9 @@ def _createServerSubparser(self, subparsers):
             add_help=True,
             formatter_class=argparse.RawTextHelpFormatter)
 
-        self._addCustomSolversArguments(parser_server)
-
-        self._addLogArguments(parser_server, abbrevation='S', logger_name = 'server')       
-        self._addDefaultArgumentsToSolverParser(parser_server)
-        self.solver = self._selectSubclassAndAddCustomArguments(parser_server, ClinguinBackend, self.solver_name, ArgumentParser.default_solver)
+        self._addLogArguments(parser_server, abbrevation='S', logger_name = 'clinguin_server')       
+        self._addDefaultArgumentsToBackendParser(parser_server)
+        self.backend = self._selectSubclassAndAddCustomArguments(parser_server, ClinguinBackend, self.backend_name, ArgumentParser.default_backend)
 
         return parser_server
 
@@ -180,35 +231,51 @@ def _createClientServerSubparser(self, subparsers):
                                                      add_help=True,
                                                      formatter_class=argparse.RawTextHelpFormatter)
 
-        self._addCustomClientsArguments(parser_server_client)
-        self._addCustomSolversArguments(parser_server_client)
 
-        self._addLogArguments(parser_server_client, abbrevation='C', logger_name = 'client', display_name= 'client-')       
-        self._addLogArguments(parser_server_client, abbrevation='S', logger_name = 'server', display_name ='server-')       
+        self._addLogArguments(parser_server_client, abbrevation='C', logger_name = 'clinguin_client', display_name= 'client-')       
+        self._addLogArguments(parser_server_client, abbrevation='S', logger_name = 'clinguin_server', display_name ='server-')       
 
         self._addDefaultArgumentsToClientParser(parser_server_client)
         self.client = self._selectSubclassAndAddCustomArguments(parser_server_client, AbstractGui, self.client_name, ArgumentParser.default_client)
 
-        self._addDefaultArgumentsToSolverParser(parser_server_client)
-        self.solver = self._selectSubclassAndAddCustomArguments(parser_server_client, ClinguinBackend, self.solver_name, ArgumentParser.default_solver)
+        self._addDefaultArgumentsToBackendParser(parser_server_client)
+        self.backend = self._selectSubclassAndAddCustomArguments(parser_server_client, ClinguinBackend, self.backend_name, ArgumentParser.default_backend)
 
         return parser_server_client
 
-    def _addDefaultArgumentsToSolverParser(self, parser):
-        parser.add_argument('--solver', type=str,
-                            help=textwrap.dedent('''\
-                Optionally specify which solver to use using the class name.
-                See available custom solvers bellow:
+    def _addDefaultArgumentsToBackendParser(self, parser):
+        sub_classes = self._getSubClasses(ClinguinBackend)
+        sub_class_as_options = "|".join([s.__name__ for s in sub_classes])
+        sub_classes_str = "=>  Available options: {" + sub_class_as_options + "}"
+        parser.add_argument('--backend', type=str,
+                            help=textwrap.dedent(f'''\
+                Optionally specify which backend to use using the class name.
+                {sub_classes_str}
                 '''),
                             metavar='')
+        parser.add_argument(
+            '--custom-classes',
+            type=str,
+            help='Path to custom classes.',
+            metavar='')
 
     def _addDefaultArgumentsToClientParser(self, parser):
+        sub_classes = self._getSubClasses(AbstractGui)
+        sub_class_as_options = "|".join([s.__name__ for s in sub_classes])
+        sub_classes_str = "=>  Available options: {" + sub_class_as_options + "}"
         parser.add_argument('--client', type=str,
-                            help=textwrap.dedent('''\
+                            help=textwrap.dedent(f'''\
                 Optionally specify which client to use using the class name.
-                See available custom clients bellow:
+                {sub_classes_str}
                 '''),
                             metavar='')
+        parser.add_argument('--gui-syntax', 
+                action='store_true',
+                help='Show available commands for the GUI.')
+        parser.add_argument('--gui-syntax-full', 
+                action='store_true',
+                help='Show available commands for the GUI and shows available value-types.')
+        
 
     def _addLogArguments(self, parser, abbrevation='', logger_name = '', display_name=''):
 
@@ -216,7 +283,7 @@ def _addLogArguments(self, parser, abbrevation='', logger_name = '', display_nam
         group.add_argument('--' + display_name + 'log-disable-shell',
                                    action='store_true',
                                    help='Disable shell logging')
-        group.add_argument('--' + display_name + 'log-disable-file',
+        group.add_argument('--' + display_name + 'log-enable-file',
                                    action='store_true',
                                    help='Disable file logging')
         group.add_argument('--' + display_name + 'logger-name',
@@ -240,43 +307,43 @@ def _addLogArguments(self, parser, abbrevation='', logger_name = '', display_nam
             type=str,
             help='Log format shell',
             metavar='',
-            default='['+str(abbrevation)+'][%(levelname)s]<%(asctime)s>: %(message)s')
+            default='['+str(abbrevation)+'] %(levelname)s: %(message)s')
         group.add_argument(
             '--' + display_name + 'log-format-file',
             type=str,
             help='Log format file',
             metavar='',
-            default='%(levelname)s<%(asctime)s>: %(message)s')
+            default='%(levelname)s: %(message)s')
 
-    def _addCustomSolversArguments(self, parser):
-        parser.add_argument(
-            '--custom-server-classes',
-            type=str,
-            help='Path to custom solver classes',
-            metavar='')
- 
+  
+    def _getSubClasses(self, cur_class):
+        sub_classes = cur_class.__subclasses__()
+        recursive = []
+        for sub_class in sub_classes:
+            recursive.extend(self._getSubClasses(sub_class))
 
-    def _addCustomClientsArguments(self, parser):
-       parser.add_argument(
-            '--custom-client-classes',
-            type=str,
-            help='Path to custom client classes.',
-            metavar='')
+        return sub_classes + recursive
 
 
     def _selectSubclassAndAddCustomArguments(self, parser, parent, class_name, default_class):
-        sub_classes = parent.__subclasses__()
+        sub_classes = self._getSubClasses(parent)
+        
         selected_class = None
 
         for sub_class in sub_classes:
-            if not class_name and sub_class.__name__ == default_class:
-                group = parser.add_argument_group(sub_class.__name__)
+            full_class_name = sub_class.__name__
+            selected_by_default = not class_name and full_class_name == default_class
+            selected =  full_class_name == class_name
+            if selected_by_default or selected:
+                group = parser.add_argument_group(full_class_name)
                 sub_class.registerOptions(group)
-                selected_class = sub_class
-            elif sub_class.__name__ == class_name:
-                group = parser.add_argument_group(sub_class.__name__)
-                sub_class.registerOptions(group)
-                selected_class = sub_class
+        
+                should_show_gui_syntax = self._show_gui_syntax == ShowGuiSyntaxEnum.SHOW or self._show_gui_syntax  == ShowGuiSyntaxEnum.FULL
+                if should_show_gui_syntax and hasattr(sub_class, 'availableSyntax'):
+                    print(sub_class.availableSyntax(self._show_gui_syntax))
+                    sys.exit()
 
+                selected_class = sub_class
         return selected_class
 
+# W0703,R0201,W0707,W0122
diff --git a/clinguin/server/__init__.py b/clinguin/server/__init__.py
index 2c0825bf..a57b62ea 100644
--- a/clinguin/server/__init__.py
+++ b/clinguin/server/__init__.py
@@ -1,1 +1,11 @@
-# This is a package
+"""
+Server module, contains core-program classes.
+"""
+from .presentation.endpoints import Endpoints
+from .application.standard_json_encoder import StandardJsonEncoder
+from .application.clinguin_backend import ClinguinBackend
+from .data.clinguin_model import ClinguinModel
+
+__all__ = [Endpoints.__name__, StandardJsonEncoder.__name__, ClinguinBackend.__name__, ClinguinModel.__name__]
+
+
diff --git a/clinguin/server/application/attribute.py b/clinguin/server/application/attribute.py
index 65ecb123..d4131ed0 100644
--- a/clinguin/server/application/attribute.py
+++ b/clinguin/server/application/attribute.py
@@ -1,7 +1,13 @@
+"""
+Module contains the AttributeDto class.
+"""
 import json
 
 
 class AttributeDto:
+    """
+    Objects of this class represent the attributes in the json convertible hierarchy.
+    """
     def __init__(self, id, key, value):
         self.id = str(id)
         self.key = str(key)
diff --git a/clinguin/server/application/callback.py b/clinguin/server/application/callback.py
index e0134e1c..2feace40 100644
--- a/clinguin/server/application/callback.py
+++ b/clinguin/server/application/callback.py
@@ -1,7 +1,13 @@
+"""
+Module contains the CallbackDto class.
+"""
 import json
 
 
 class CallbackDto:
+    """
+    This class represents a Callback that is Json convertible. Therefore objects of this class are part of the hierarchy that will get converted to Json by the endpoints on sending the reply.
+    """
     def __init__(self, id, action, policy):
         self.id = str(id)
         self.action = str(action)
diff --git a/clinguin/server/application/clinguin_backend.py b/clinguin/server/application/clinguin_backend.py
index ab21a130..4c0948c3 100644
--- a/clinguin/server/application/clinguin_backend.py
+++ b/clinguin/server/application/clinguin_backend.py
@@ -1,11 +1,17 @@
+"""
+Module which contains the ClinguinBackend.
+"""
 import logging
 
-from clinguin.utils.custom_args import CustomArgs
+from clinguin.utils import CustomArgs
 
 # Like an interface
 
 
 class ClinguinBackend(CustomArgs):
+    """
+    Root class of all backends (here backend refers to the type like ClingoBackend, etc.). Just defines the logger, the standard arguments and get().
+    """
 
     def __init__(self, args):
         self._logger = logging.getLogger(args.log_args['name'])
diff --git a/clinguin/server/application/default_backends/__init__.py b/clinguin/server/application/default_backends/__init__.py
new file mode 100644
index 00000000..e93e8a55
--- /dev/null
+++ b/clinguin/server/application/default_backends/__init__.py
@@ -0,0 +1,9 @@
+"""
+Module that contains the default backends ClingoBackend, ClingraphBackend and TemporalBackend.
+"""
+from clinguin.server.application.default_backends.clingo_backend import ClingoBackend
+from clinguin.server.application.default_backends.clingraph_backend import ClingraphBackend
+from clinguin.server.application.default_backends.temporal_backend import TemporalBackend
+
+__all__ = [ClingoBackend.__name__,ClingraphBackend.__name__,TemporalBackend.__name__]
+
diff --git a/clinguin/server/application/default_backends/clingo_backend.py b/clinguin/server/application/default_backends/clingo_backend.py
new file mode 100644
index 00000000..fdbf946b
--- /dev/null
+++ b/clinguin/server/application/default_backends/clingo_backend.py
@@ -0,0 +1,229 @@
+"""
+Module that contains the ClingoBackend.
+"""
+import sys
+
+from clingo import Control, parse_term
+from clingo.script import enable_python
+# Self defined
+from clinguin.utils.errors import NoModelError
+from clinguin.server import StandardJsonEncoder
+from clinguin.server import ClinguinModel
+from clinguin.server import ClinguinBackend
+from clinguin.server.application.default_backends.standard_utils.brave_cautious_helper import *
+
+
+enable_python()
+
+class ClingoBackend(ClinguinBackend):
+    """
+    The ClingoBackend class is the backend that is selected by default. It provides basic functionality to argue bravely and cautiously. Further it provides several policies for assumptions, atoms and externals.
+    """
+
+    def __init__(self, args):
+        super().__init__(args)
+
+        self._source_files = args.source_files
+        self._widget_files = args.widget_files
+        
+        # For browising
+        self._handler=None
+        self._iterator=None
+
+        # To make static linters happy
+        self._assumptions = None
+        self._atoms = None
+        self._ctl = None
+        
+        self._restart()
+        
+        # I think we should remove this and only have one ClinguinModel
+        self._modelClass = ClinguinModel
+        self._model=None
+
+    @classmethod
+    def registerOptions(cls, parser):
+        parser.add_argument('--source-files', nargs='+', help='Files',metavar='')
+        parser.add_argument('--widget-files', nargs='+', help='Files for the widget generation',metavar='')
+
+    def _restart(self):
+        self._endBrowsing()
+        self._assumptions = set()
+        self._externals = {"true":set(),"false":set(),"released":set()}
+        self._atoms = set()
+        self._initCtl()
+        self._ground()
+
+    def _initCtl(self):
+        self._ctl = Control(['0'])
+        for f in self._source_files:
+            try:
+                self._ctl.load(str(f))
+            except Exception as e:
+                self._logger.critical(str(e))
+                self._logger.critical("Failed to load modules (there is likely a syntax error in your logic program), now exiting - see previous stack trace for more information.")
+                sys.exit()
+        
+        for atom in self._atoms:
+            self._ctl.add("base",[],str(atom) + ".")
+        
+        
+    
+    def _ground(self):
+        self._ctl.ground([("base", [])])
+
+    
+    def _endBrowsing(self):
+        if self._handler:
+            self._handler.cancel()
+            self._handler = None
+        self._iterator = None
+
+    def _updateModel(self):
+        try:
+            self._model = ClinguinModel.fromWidgetsFile(
+                self._ctl,
+                self._widget_files, 
+                self._assumptions)
+        except NoModelError:
+            self._model.addMessage("Error","This operation can't be performed")
+
+    def get(self):
+        """
+        Overwritten default method to get the gui as a Json structure.
+        """
+        if not self._model:
+            self._updateModel()
+
+        json_structure =  StandardJsonEncoder.encode(self._model)
+
+        return json_structure
+
+    def clearAssumptions(self):
+        """
+        Policy: clearAssumptions removes all assumptions, then basically ''resets'' the backend (i.e. it regrounds, etc.) and finally updates the model and returns the updated gui as a Json structure.
+        """
+        self._endBrowsing()
+        self._assumptions = set()
+        self._initCtl()
+        self._ground()
+
+        self._updateModel()
+        return self.get()
+
+    def addAssumption(self, predicate):
+        """
+        Policy: Adds an assumption and returns the udpated Json structure.
+        """
+        predicate_symbol = parse_term(predicate)
+        if predicate_symbol not in self._assumptions:
+            self._assumptions.add(predicate_symbol)
+            self._endBrowsing()
+            self._updateModel()
+        return self.get()
+
+    def removeAssumption(self, predicate):
+        """
+        Policy: Removes an assumption and returns the udpated Json structure.
+        """
+        # Iconf
+        predicate_symbol = parse_term(predicate)
+        if predicate_symbol in self._assumptions:
+            self._assumptions.remove(predicate_symbol)
+            self._endBrowsing()
+            self._updateModel()
+        return self.get()
+   
+    def clearAtoms(self):
+        """
+        Policy: clearAtoms removes all atoms, then basically ''resets'' the backend (i.e. it regrounds, etc.) and finally updates the model and returns the updated gui as a Json structure.
+        """
+        self._endBrowsing()
+        self._atoms = set()
+        self._initCtl()
+        self._ground()
+
+        self._updateModel()
+        return self.get()
+
+    def addAtom(self, predicate):
+        """
+        Policy: Adds an assumption and basically resets the rest of the application (reground) - finally it returns the udpated Json structure.
+        """
+        predicate_symbol = parse_term(predicate)
+        if predicate_symbol not in self._atoms:
+            self._atoms.add(predicate_symbol)
+            # Maybe best to do using the callback tuple?
+            self._initCtl()
+            self._ground()
+            self._endBrowsing()
+            self._updateModel()
+        return self.get()
+
+    def removeAtom(self,predicate):
+        """
+        Policy: Removes an assumption and basically resets the rest of the application (reground) - finally it returns the udpated Json structure.
+        """
+        predicate_symbol = parse_term(predicate)
+        if predicate_symbol in self._atoms:
+            self._atoms.remove(predicate_symbol)
+            self._initCtl()
+            self._ground()
+            self._endBrowsing()
+            self._updateModel()
+        return self.get()
+
+    def setExternal(self, predicate, value):
+        """
+        Policy: Sets the value of an external.
+        """
+        symbol = parse_term(predicate)
+        name = value
+
+        if name == "release":
+            self._ctl.release_external(parse_term(predicate))
+            self._externals["released"].add(symbol)
+
+            if symbol in self._externals["true"]:
+                self._externals["true"].remove(symbol)
+    
+            if symbol in self._externals["false"]:
+                self._externals["false"].remove(symbol)
+
+        elif name == "true":
+            self._ctl.assign_external(parse_term(predicate),True)
+            self._externals["true"].add(symbol)
+
+            if symbol in self._externals["false"]:
+                self._externals["false"].remove(symbol)
+
+        elif name == "false":
+            self._ctl.assign_external(parse_term(predicate),True)
+            self._externals["false"].add(symbol)
+
+            if symbol in self._externals["true"]:
+                self._externals["true"].remove(symbol)
+
+        else:
+            raise ValueError(f"Invalid external value {name}. Must be true, false or relase")
+
+        self._updateModel()
+        return self.get()
+
+    def nextSolution(self):
+        if not self._iterator:
+            self._ctl.configuration.solve.enum_mode = 'auto'
+            self._handler = self._ctl.solve(
+                assumptions=[(a,True) for a in self._assumptions],
+                yield_=True)
+            self._iterator = iter(self._handler)
+        try:
+            model = next(self._iterator)
+            self._model = self._modelClass.fromClingoModel(model)
+        except StopIteration:
+            self._logger.info("No more solutions")
+            self._handler.cancel()
+            self._updateModel()
+            self._model.addMessage("Browsing Information","No more solutions")
+
+        return self.get()
diff --git a/clinguin/server/application/default_backends/clingraph_backend.py b/clinguin/server/application/default_backends/clingraph_backend.py
new file mode 100644
index 00000000..b204b667
--- /dev/null
+++ b/clinguin/server/application/default_backends/clingraph_backend.py
@@ -0,0 +1,270 @@
+"""
+Module that contains the ClingraphBackend.
+"""
+import copy
+import base64
+
+import textwrap
+
+from clingo import Control
+from clingo.symbol import Function, String
+
+import clorm
+from clorm import Raw
+
+from clingraph import Factbase, compute_graphs, render
+from clingraph.clingo_utils import ClingraphContext
+
+
+# Self defined
+from clinguin.utils import StandardTextProcessing
+from clinguin.server.data.attribute import AttributeDao
+
+from clinguin.server.data.clinguin_model import ClinguinModel
+from clinguin.server import StandardJsonEncoder
+
+from clinguin.server.application.default_backends.clingo_backend import ClingoBackend
+
+from clinguin.utils import NoModelError
+
+class ClingraphBackend(ClingoBackend):
+    """
+    TODO -> Write documentation!
+    """
+
+    def __init__(self, args):
+        super().__init__(args)
+
+        self._clingraph_files = args.clingraph_files
+        self._select_model = args.select_model
+        self._type = args.type
+        self._select_graph = args.select_graph
+        self._dir = args.dir
+        self._name_format = args.name_format
+        self._engine = args.engine
+        self._disable_saved_to_file = args.disable_saved_to_file
+
+        self._intermediate_format = 'png'
+        self._encoding = 'utf-8'
+        self._attribute_image_key = 'image'
+        self._attribute_image_value = 'clingraph'
+        self._attribute_image_value_seperator = '__'
+
+        self._filled_model = None
+
+
+    @classmethod
+    def registerOptions(cls, parser):     
+        ClingoBackend.registerOptions(parser)
+
+        parser.add_argument('--clingraph-files',
+                        help = textwrap.dedent('''\
+                            A visualization encoding that will be used to generate the graph facts
+                            by calling clingo with the input.
+                            This encoding is expected to have only one stable model.'''),
+                        # type=argparse.FileType('r'),
+                        nargs='+',
+                        metavar='')
+
+        parser.add_argument('--prefix',
+                        default = '',
+                        help = textwrap.dedent('''\
+                            Prefix expected in all the considered facts.
+                            Example: --prefix=viz_ will look for predicates named viz_node, viz_edge etc.'''),
+                        type=str,
+                        metavar='')
+
+        parser.add_argument('--default-graph',
+                        default = 'default',
+                        help = textwrap.dedent('''\
+                        The name of the default graph.
+                        All nodes and edges with arity 1 will be assigned to this graph
+                            (default: %(default)s)'''),
+                        type=str,
+                        metavar='')
+
+        parser.add_argument('--select-graph',
+                help = textwrap.dedent('''\
+                    Select one of the graphs by name.
+                    Can appear multiple times to select multiple graphs'''),
+                type=str,
+                action='append',
+                nargs='?',
+                metavar="")
+
+        parser.add_argument('--select-model',
+                help = textwrap.dedent('''\
+                    Select only one of the models when using a json input.
+                    Defined by a number starting in index 0.
+                    Can appear multiple times to select multiple models.'''),
+                type=int,
+                action='append',
+                nargs='?',
+                metavar="")
+
+        parser.add_argument('--name-format',
+                    help = textwrap.dedent('''\
+                        An optional string to format the name when saving multiple files,
+                        this string can reference parameters `{graph_name}` and `{model_number}`.
+                        Example `new_version-{graph_name}-{model_number}`
+                        (default: `{graph_name}` or
+                                `{model_number}/{graph_name}` for multi model functionality from json)'''),
+                    type=str,
+                    metavar='')
+
+        parser.add_argument('--dir',
+                        default = 'out',
+                        help = textwrap.dedent('''\
+                            Directory for writing the output files
+                                (default: %(default)s)'''),
+                        type=str,
+                        metavar='')
+
+        parser.add_argument('--type',
+                    default = 'graph',
+                    choices=['graph', 'digraph'],
+                    help = textwrap.dedent('''\
+                        The type of the graph
+                        {graph|digraph}
+                            (default: %(default)s)'''),
+                    type=str,
+                    metavar='')
+
+        parser.add_argument('--engine',
+                        default = 'dot',
+                        choices=["dot","neato","twopi","circo","fdp","osage","patchwork","sfdp"],
+                        help = textwrap.dedent('''\
+                            Layout command used by graphviz
+                            {dot|neato|twopi|circo|fdp|osage|patchwork|sfdp}
+                                (default: %(default)s)'''),
+                        type=str,
+                        metavar="")
+
+        parser.add_argument('--disable-saved-to-file',
+                    action='store_true',
+                    help='Disable image saved to file')
+ 
+
+    def _computeClingraphGraphs(self,prg):
+        fbs = []
+        ctl = Control("0")
+        for f in self._clingraph_files:
+            ctl.load(f)
+        ctl.add("base",[],prg)
+        ctl.ground([("base",[])],ClingraphContext())
+
+        ctl.solve(on_model=lambda m: fbs.append(Factbase.from_model(m)))
+        if self._select_model is not None:
+            for m in self._select_model:
+                if m>=len(fbs):
+                    raise ValueError(f"Invalid model number selected {m}")
+            fbs = [f if i in self._select_model else None
+                        for i, f in enumerate(fbs) ]
+
+        
+
+        graphs = compute_graphs(fbs, graphviz_type=self._type)
+
+        return graphs
+
+    def _saveClingraphGraphsToFile(self,graphs):
+        if self._select_graph is not None:
+            graphs = [{g_name:g for g_name, g in graph.items() if g_name in self._select_graph} for graph in graphs]
+        write_arguments = {"directory":self._dir, "name_format":self._name_format}
+        paths = render(graphs,
+                format='png',
+                engine=self._engine,
+                view=False,
+                **write_arguments)
+        self._logger.debug("Clingraph saved images:")
+        self._logger.debug(paths)
+
+    
+    def _getModelFilledWithBase64ImagesFromGraphs(self,graphs):
+        model = self._model
+
+        kept_symbols = list(model.getElements()) + list(model.getCallbacks())
+
+        filled_attributes = []
+    
+        # TODO - Improve efficiency of filling attributes
+        for attribute in model.getAttributes():
+            if str(attribute.key) == self._attribute_image_key:
+                attribute_value = StandardTextProcessing.parseStringWithQuotes(str(attribute.value))
+
+                if attribute_value.startswith(self._attribute_image_value) and attribute_value != "clingraph":
+                    splits = attribute_value.split(self._attribute_image_value_seperator)
+                    splits.pop(0)
+                    rest = ""   
+                    for split in splits:
+                        rest = rest + split
+
+                    key_image = self._createImageFromGraph(graphs, key = rest)
+
+                    base64_key_image = self._convertImageToBase64String(key_image)
+
+                    filled_attributes.append(AttributeDao(Raw(Function(str(attribute.id),[])), Raw(Function(str(attribute.key),[])), Raw(String(str(base64_key_image)))))
+                else:
+                    filled_attributes.append(attribute)
+            else:
+                filled_attributes.append(attribute)
+
+        return ClinguinModel(clorm.FactBase(copy.deepcopy(kept_symbols + filled_attributes)))
+
+
+    def _createImageFromGraph(self, graphs, position = None, key = None):
+        graphs = graphs[0]
+
+        if position is not None: 
+            if (len(graphs)-1) >= position:
+                graph = graphs[list(graphs.keys())[position]]
+            else:
+                self._logger.error("Attempted to access not valid position")
+                raise Exception("Attempted to access not valid position")
+        elif key is not None:
+            if key in graphs:
+                graph = graphs[key]
+            else:
+                self._logger.error("Key not found in graphs: %s", str(key))
+                raise Exception("Key not found in graphs: " + str(key))
+        else:
+            self._logger.error("Must either specify position or key!")
+            raise Exception("Must either specify position or key!")
+
+        graph.format = self._intermediate_format
+        img = graph.pipe(engine=self._engine)
+
+        return img
+
+    def _convertImageToBase64String(self, img):
+        encoded = base64.b64encode(img)
+        decoded = encoded.decode(self._encoding)    
+        return decoded
+
+       
+    def _updateModel(self):
+        try:
+            prg = ClinguinModel.getCautiousBrave(self._ctl,self._assumptions)
+            self._model = ClinguinModel.fromWidgetsFileAndProgram(self._ctl,self._widget_files,prg)
+
+            graphs = self._computeClingraphGraphs(prg)
+
+            if not self._disable_saved_to_file:
+                print(self._disable_saved_to_file)
+                self._saveClingraphGraphsToFile(graphs)
+
+            self._filled_model = self._getModelFilledWithBase64ImagesFromGraphs(graphs)
+
+        except NoModelError:
+            self._model.addMessage("Error","This operation can't be performed")
+
+    def get(self):
+        if not self._filled_model:
+            self._updateModel()
+            
+        json_structure = StandardJsonEncoder.encode(self._filled_model)
+        return json_structure
+
+
+
+
diff --git a/old_prototype/brave_cutios_predicate.lp b/clinguin/server/application/default_backends/standard_utils/__init__.py
similarity index 100%
rename from old_prototype/brave_cutios_predicate.lp
rename to clinguin/server/application/default_backends/standard_utils/__init__.py
diff --git a/clinguin/server/application/default_backends/standard_utils/brave_cautious_helper.py b/clinguin/server/application/default_backends/standard_utils/brave_cautious_helper.py
new file mode 100644
index 00000000..0afec986
--- /dev/null
+++ b/clinguin/server/application/default_backends/standard_utils/brave_cautious_helper.py
@@ -0,0 +1,101 @@
+"""
+This module contains one string (brave_cautious_externals) that is helpful for the brave-cautious implementation.
+"""
+brave_cautious_externals = """
+#external show_brave.
+#external show_cautious.
+#external show_untagged.
+#external show_all.
+#external no_more_solutions.
+
+#show element(ID,TYPE,PARENT): _brave(element(ID,TYPE,PARENT)), show_brave.
+#show attribute(ID,NAME,VALUE): _brave(attribute(ID,NAME,VALUE)), show_brave.
+#show callback(ID,ACTION,FUNCT): _brave(callback(ID,ACTION,FUNCT)), show_brave.
+
+#show element(ID,TYPE,PARENT): _cautious(element(ID,TYPE,PARENT)), show_cautious.
+#show attribute(ID,NAME,VALUE): _cautious(attribute(ID,NAME,VALUE)), show_cautious.
+#show callback(ID,ACTION,FUNCT): _cautious(callback(ID,ACTION,FUNCT)), show_cautious.
+
+#show element(ID,TYPE,PARENT): 
+    element(ID,TYPE,PARENT),
+    not _brave(element(ID,TYPE,PARENT)), 
+    not _cautious(element(ID,TYPE,PARENT)), 
+    show_untagged.
+#show attribute(ID,NAME,VALUE): 
+    attribute(ID,NAME,VALUE),
+    not _brave(attribute(ID,NAME,VALUE)), 
+    not _cautious(attribute(ID,NAME,VALUE)), 
+    show_untagged.
+#show callback(ID,ACTION,FUNCT): 
+    callback(ID,ACTION,FUNCT),
+    not _brave(callback(ID,ACTION,FUNCT)),
+    not _cautious(callback(ID,ACTION,FUNCT)),
+    show_untagged.
+
+#show .
+
+
+#show element(ID,TYPE,PARENT): 
+    element(ID,TYPE,PARENT),
+    show_all.
+#show attribute(ID,NAME,VALUE): 
+    attribute(ID,NAME,VALUE),
+    show_all.
+#show callback(ID,ACTION,FUNCT): 
+    callback(ID,ACTION,FUNCT),
+    show_all.
+
+#defined _cautious_element_type/1.
+#defined _brave_element_type/1.
+
+_brave(element(ID, TYPE, PARENT)):-
+    _brave_element_type(TYPE),
+    element(ID, TYPE, PARENT).
+_brave(callback(ID,ACTION,FUNCT)):-
+    element(ID, TYPE, PARENT),
+    _brave_element_type(TYPE),
+    callback(ID,ACTION,FUNCT).
+_brave(attribute(ID,NAME,VAL)):-
+    element(ID, TYPE, PARENT),
+    _brave_element_type(TYPE),
+    attribute(ID,NAME,VAL).
+
+_cautious(element(ID, TYPE, PARENT)):-
+    _cautious_element_type(TYPE),
+    element(ID, TYPE, PARENT).
+_cautious(callback(ID,ACTION,FUNCT)):-
+    element(ID, TYPE, PARENT),
+    _cautious_element_type(TYPE),
+    callback(ID,ACTION,FUNCT).
+_cautious(attribute(ID,NAME,VAL)):-
+    element(ID, TYPE, PARENT),
+    _cautious_element_type(TYPE),
+    attribute(ID,NAME,VAL).
+
+#defined _cautious_element/1.
+#defined _brave_element/1.
+
+_brave(element(ID, TYPE, PARENT)):-
+    _brave_element(ID),
+    element(ID, TYPE, PARENT).
+_brave(callback(ID,ACTION,FUNCT)):-
+    element(ID, TYPE, PARENT),
+    _brave_element(ID),
+    callback(ID,ACTION,FUNCT).
+_brave(attribute(ID,NAME,VAL)):-
+    element(ID, TYPE, PARENT),
+    _brave_element(ID),
+    attribute(ID,NAME,VAL).
+
+_cautious(element(ID, TYPE, PARENT)):-
+    _cautious_element(ID),
+    element(ID, TYPE, PARENT).
+_cautious(callback(ID,ACTION,FUNCT)):-
+    element(ID, TYPE, PARENT),
+    _cautious_element(ID),
+    callback(ID,ACTION,FUNCT).
+_cautious(attribute(ID,NAME,VAL)):-
+    element(ID, TYPE, PARENT),
+    _cautious_element(ID),
+    attribute(ID,NAME,VAL).
+"""
diff --git a/clinguin/server/application/default_backends/temporal_backend.py b/clinguin/server/application/default_backends/temporal_backend.py
new file mode 100644
index 00000000..d7d32433
--- /dev/null
+++ b/clinguin/server/application/default_backends/temporal_backend.py
@@ -0,0 +1,105 @@
+"""
+Module that contains the Temporal Backend.
+"""
+
+from clingo.symbol import Function, Number
+from clingo import parse_term
+from clingo.script import enable_python
+
+# Self defined
+from clinguin.server import ClinguinModel
+from clinguin.server.application.default_backends.clingo_backend import ClingoBackend
+from clinguin.server.application.default_backends.standard_utils.brave_cautious_helper import *
+
+enable_python()
+
+class TemporalBackend(ClingoBackend):
+    """
+    TODO -> Add documentation!
+    """
+
+    def __init__(self, args):
+        self._step = 1
+        self._last_grounded_step = 0
+        self._full_plan=None
+        super().__init__(args)
+        
+
+    def _initCtl(self):
+        self._step= 1
+        self._last_grounded_step= 0
+        self._full_plan=None
+        super()._initCtl()
+
+    def _ground(self):
+        if not self._last_grounded_step:
+            self._ctl.ground([("base", [])])
+        while self._step>self._last_grounded_step:
+            self._last_grounded_step+=1
+            self._ctl.ground([("step", [Number(self._step)])])
+        if self._step>1:
+            self._ctl.assign_external(Function('query',[Number(self._step-1)]),False)
+        self._ctl.assign_external(Function('query',[Number(self._step)]),True)
+
+
+    def _findIncrementally(self):
+        if self._step>1:
+            self._ctl.assign_external(Function('check',[Number(self._step-1)]),False)
+        self._ctl.assign_external(Function('check',[Number(self._step)]),True)
+        plan = self._findPlan()
+        
+        while plan is None or self._step>100:
+            self._step +=1
+            self._ground()
+            if self._step>1:
+                self._ctl.assign_external(Function('check',[Number(self._step-1)]),False)
+            self._ctl.assign_external(Function('check',[Number(self._step)]),True)
+            plan = self._findPlan()
+
+        if self._full_plan is None:
+            raise RuntimeError("No plan found before 100 steps")
+
+
+        return self._full_plan
+
+    def _findPlan(self):
+        self._ctl.configuration.solve.enum_mode = 'auto'
+        hdn = self._ctl.solve(
+            assumptions=[(a,True) for a in self._assumptions],
+            yield_=True)
+        itr = iter(hdn)
+        try:
+            model = next(itr)
+            self._full_plan = model.symbols(atoms=True)
+            hdn.cancel()
+        except StopIteration:
+            hdn.cancel()
+            self._full_plan=None
+        
+        return self._full_plan
+
+
+    def findPlan(self):
+        if not self._full_plan:
+            self._findIncrementally()
+
+        symbols = "\n".join([str(s)+"." for s in self._full_plan])
+        wctl = ClinguinModel.widControl(self._widget_files,symbols)
+        self._model = ClinguinModel.fromCtl(wctl)
+        return self.get()
+
+    def assumeAndStep(self, predicate):
+        predicate_symbol = parse_term(predicate)
+        self._assumptions.add(predicate_symbol)
+        self._step +=1
+        self._ground()
+        self._endBrowsing()
+        self._updateModel()
+        return self.get()
+
+    def removeAssumption(self, predicate):
+        raise NotImplementedError()
+
+
+    def nextSolution(self):
+        raise NotImplementedError()
diff --git a/clinguin/server/application/default_solvers/standard_solver.py b/clinguin/server/application/default_solvers/standard_solver.py
deleted file mode 100644
index 8d8f3265..00000000
--- a/clinguin/server/application/default_solvers/standard_solver.py
+++ /dev/null
@@ -1,73 +0,0 @@
-import networkx as nx
-from typing import Sequence, Any
-
-import logging
-import clingo
-from clingo import Control
-from clingo.symbol import Function, Number, String
-
-from clinguin.server.application.standard_json_encoder import StandardJsonEncoder
-
-from clinguin.server.data.clinguin_model import ClinguinModel
-
-from clinguin.server.application.clinguin_backend import ClinguinBackend
-
-
-class ClingoBackend(ClinguinBackend):
-
-    def __init__(self, args):
-        super().__init__(args)
-        self._assumptions = set()
-        self._files = args.source_files
-
-        self._ctl = Control()
-        for f in self._files:
-            self._ctl.load(str(f))
-        self._ctl.ground([("base", [])])
-
-    @classmethod
-    def registerOptions(cls, parser):
-        parser.add_argument('source_files', nargs='+', help='Files')
-
-    # becomes an endpoint option is the basic default one! instead of solve
-    # just get
-    def get(self):
-        self._logger.debug("_get()")
-
-        model = ClinguinModel(self._files, self._logger)
-        model.computeCautious(self._ctl, self._assumptions, lambda w: True)
-        model.computeBrave(
-            self._ctl, self._assumptions, lambda w: str(
-                w.type) == 'dropdownmenuitem')
-
-        self._logger.debug("will encode")
-        return StandardJsonEncoder.encode(model)
-
-    # becomes an endpoint option
-    def assume(self, predicate):
-        self._logger.debug("assume(" + str(predicate) + ")")
-        if predicate not in self._assumptions:
-            self._assumptions.add(predicate)
-        return self.get()
-
-    # becomes an endpoint option
-    def solve(self):
-        self._logger.debug("solve()")
-        self.model = None
-        return self.get()
-
-    # becomes an endpoint option
-    def remove(self, predicate):
-        self._logger.debug("remove(" + str(predicate) + ")")
-        if predicate in self._assumptions:
-            self._assumptions.remove(predicate)
-            self._assumptions.remove("assume(" + predicate + ")")
-            self.model = None
-        return self.get()
-
-    def clear(self):
-        self._logger.debug("clear()")
-        self._assumptions.clear()
-        return self.get()
-
-
diff --git a/clinguin/server/application/element.py b/clinguin/server/application/element.py
index 4805c5a7..dcde03e0 100644
--- a/clinguin/server/application/element.py
+++ b/clinguin/server/application/element.py
@@ -1,8 +1,12 @@
+"""
+Module that contains the ElementDto class.
+"""
 import json
-from clorm import StringField
-
 
 class ElementDto:
+    """
+    The class that represents elements that are Json convertible, i.e. these components are the heart of the Json convertible hierarchy.
+    """
 
     def __init__(self, id, type, parent):
         self.id = str(id)
diff --git a/clinguin/server/application/standard_json_encoder.py b/clinguin/server/application/standard_json_encoder.py
index e19d2838..7e729188 100644
--- a/clinguin/server/application/standard_json_encoder.py
+++ b/clinguin/server/application/standard_json_encoder.py
@@ -1,62 +1,90 @@
-import json
+"""
+Module which contains the StandardJsonEncoder
+"""
+import logging
 
 import networkx as nx
 
-from typing import Sequence, Any
-
-from clinguin.server.application.element import ElementDto
-from clinguin.server.application.attribute import AttributeDto
-from clinguin.server.application.callback import CallbackDto
-
-"""
-Generates a ClassHierarchy which can easily be serialized
-"""
+from clinguin.utils import Logger
 
+from .element import ElementDto
+from .attribute import AttributeDto
+from .callback import CallbackDto
 
 class StandardJsonEncoder:
+    """
+    The standrd json encoder is responsible for converting a ClinguinModel into a json hierarchy.
+
+    Methods:
+        endocde (model : ClinguinModel) -> ElementDto 
+        _generateHierarchy (model : ClinguinModel, hierarchy_root : ElementDto, elements_dict : Dict) -> ElementDto
+    """
 
     def __init__(self):
         pass
 
     @classmethod
-    def encode(ctl, model):
+    def encode(cls, model):
+        """
+        Public easy to access wrapper for the _generateHieraryh method.
+
+        Arguments:
+            model : ClinguinModel
+        """
         elements_dict = {}
 
         root = ElementDto('root', 'root', 'root')
         elements_dict[str(root.id)] = root
 
-        ctl._generateHierarchy(model, root, elements_dict)
+        cls._generateHierarchy(model, root, elements_dict)
 
         return root
 
     @classmethod
-    def _generateHierarchy(ctl, wrapper, hierarchy_root, elements_dict):
+    def _generateHierarchy(cls, model, hierarchy_root, elements_dict):
+        """
+        Converts the ClinguinModel into an Json Hierarchy (which is represented by an ElementDto). Therefore it first gets all dependencies, then orders the elements according to the dependencies and then adds for each element its attributes, callbacks and children.
+
+        Arguments:
+            model : ClinguinModel
+            hierarchy_root : ElementDto
+            elements_dict : Dict
+        """
+        logger = logging.getLogger(Logger.server_logger_name)
 
         dependency = []
         widgets_info = {}
 
-        for w in wrapper.getElements():
+        for w in model.getElements():
             widgets_info[w.id] = {'parent': w.parent, 'type': w.type}
             dependency.append((w.id, w.parent))
 
         DG = nx.DiGraph(dependency)
         order = list(reversed(list(nx.topological_sort(DG))))
 
+        attrs = model.getAttributesGrouped()
+        attrs = {a[0]:list(a[1]) for a in attrs}
+        cbs = model.getCallbacksGrouped()
+        cbs = {a[0]:list(a[1]) for a in cbs}
+
         for element_id in order:
-            if element_id in widgets_info and str(element_id) != 'root':
-                type = widgets_info[element_id]['type']
-                parent = widgets_info[element_id]['parent']
-                element = ElementDto(element_id, type, parent)
-
-                attributes = []
-                for a in wrapper.getAttributesForElementId(element_id):
-                    attributes.append(AttributeDto(a.id, a.key, a.value))
-                element.setAttributes(attributes)
-
-                callbacks = []
-                for c in wrapper.getCallbacksForElementId(element_id):
-                    callbacks.append(CallbackDto(c.id, c.action, c.policy))
-                element.setCallbacks(callbacks)
-
-                elements_dict[str(element_id)] = element
-                elements_dict[str(element.parent)].addChild(element)
+            if str(element_id) == str(hierarchy_root.id):
+                continue
+
+            if not element_id in widgets_info:
+                logger.critical("The provided element id (ID : %s) could not be found!", str(element_id))
+                raise Exception("The provided element id (ID : " + str(element_id) + ") could not be found!")
+
+            type = widgets_info[element_id]['type']
+            parent = widgets_info[element_id]['parent']
+            element = ElementDto(element_id, type, parent)
+
+            if element_id in attrs:
+                elem_attributes = [AttributeDto(a.id, a.key, a.value) for a in attrs[element_id]]
+                element.setAttributes(elem_attributes)
+            if element_id in cbs:
+                elem_callbacks = [CallbackDto(a.id, a.action, a.policy) for a in cbs[element_id]]
+                element.setCallbacks(elem_callbacks)
+
+            elements_dict[str(element_id)] = element
+            elements_dict[str(element.parent)].addChild(element)
diff --git a/clinguin/server/data/attribute.py b/clinguin/server/data/attribute.py
index 310989f1..af9e2fcd 100644
--- a/clinguin/server/data/attribute.py
+++ b/clinguin/server/data/attribute.py
@@ -1,10 +1,18 @@
-from clorm import Predicate, ConstantField, RawField, Raw
-
+"""
+Module that contains the AttributeDao.
+"""
+from clorm import Predicate, RawField
 
 class AttributeDao(Predicate):
+    """
+    Class for CLORM (clingo-object-relational-mapping), i.e. for accessing attributes in a factbase.
+    """
     id = RawField
     key = RawField
     value = RawField
 
     class Meta:
+        """
+        Meta class
+        """
         name = "attribute"
diff --git a/clinguin/server/data/callback.py b/clinguin/server/data/callback.py
index 184c04d8..133c7de9 100644
--- a/clinguin/server/data/callback.py
+++ b/clinguin/server/data/callback.py
@@ -1,10 +1,19 @@
-from clorm import Predicate, ConstantField, RawField, Raw
-
+"""
+Module that contains the CallbackDao.
+"""
+from clorm import Predicate, RawField
 
 class CallbackDao(Predicate):
+    """
+    Class for CLORM (clingo-object-relational-mapping), i.e. for accessing callbacks in a factbase.
+    """
+
     id = RawField
     action = RawField
     policy = RawField
 
     class Meta:
+        """
+        Meta class
+        """
         name = "callback"
diff --git a/clinguin/server/data/clinguin_model.py b/clinguin/server/data/clinguin_model.py
index 8f6a7d74..52fb4276 100644
--- a/clinguin/server/data/clinguin_model.py
+++ b/clinguin/server/data/clinguin_model.py
@@ -1,21 +1,27 @@
-import clorm
-import clingo
+"""
+Module that contains the ClinguinModel class.
+"""
 import logging
+import clorm
 
-from clorm import Predicate, ConstantField, RawField, Raw
-from clingo import Control
+from clorm import Raw
+from clingo import Control,parse_term
 from clingo.symbol import Function, Number, String
 
-from clinguin.server.data.element import ElementDao
-from clinguin.server.data.attribute import AttributeDao
-from clinguin.server.data.callback import CallbackDao
+from clinguin.utils import NoModelError, Logger
 
+from .element import ElementDao
+from .attribute import AttributeDao
+from .callback import CallbackDao
 
 class ClinguinModel:
+    """
+    The ClinguinModel is the low-level-access-class for handling clorm and clingo, regarding brave-cautious and other default things. This class provides functionality to create a factbase with brave-cautious extended files, functionality to query important things for clinguin, etc.
+    """
 
-    def __init__(self, files, logger, factbase=None):
+    def __init__(self, factbase=None):
+        self._logger = logging.getLogger(Logger.server_logger_name)
 
-        self._logger = logger
         self.unifiers = [ElementDao, AttributeDao, CallbackDao]
 
         if factbase is None:
@@ -23,8 +29,179 @@ def __init__(self, files, logger, factbase=None):
         else:
             self._factbase = factbase
 
+    def __str__(self):
+        return self._factbase.asp_str()
+
+    @classmethod
+    def fromBCExtendedFile(cls, ctl,assumptions):
+        logger = logging.getLogger(Logger.server_logger_name)
+
+        ctl.assign_external(parse_term('show_all'),False)
+        ctl.assign_external(parse_term('show_cautious'),False)
+        ctl.assign_external(parse_term('show_untagged'),False)
+        ctl.assign_external(parse_term('show_brave'),True)
+        brave_model = cls.fromBraveModel(ctl,assumptions, logger)
+        # Here we could see if the user wants none tagged as cautious by default
+        ctl.assign_external(parse_term('show_brave'),False)
+        ctl.assign_external(parse_term('show_untagged'),True)
+        cautious_model = cls.fromCautiousModel(ctl,assumptions, logger)
+        ctl.assign_external(parse_term('show_untagged'),False)
+        ctl.assign_external(parse_term('show_all'),True)
+
+        return cls.combine(brave_model,cautious_model, logger)
+    
+
+    @classmethod
+    def combine(cls, cgmodel1, cgmodel2):
+        return cls(cgmodel1._factbase.union(cgmodel2._factbase))
+
+    @classmethod
+    def fromClingoModel(cls, m):
+        model = cls()
+        model._setFbSymbols(m.symbols(shown=True))
+        return model
+
+    @classmethod
+    def fromBraveModel(cls, ctl, assumptions):
+        model = cls()
+        brave_model = model.computeBrave(ctl, assumptions)
+        model._setFbSymbols(brave_model)
+        return model
+
+    @classmethod
+    def fromCautiousModel(cls, ctl, assumptions):
+        model = cls()
+        cautious_model = model.computeCautious(ctl, assumptions)
+        model._setFbSymbols(cautious_model)
+        return model
+
+    @classmethod
+    def getCautiousBrave(cls, ctl, assumptions):
+        model = cls()
+
+        cautious_model = model.computeCautious(ctl, assumptions)
+        brave_model = model.computeBrave(ctl, assumptions)
+        # c_prg = self.tagCautiousPrg(cautious_model)
+        c_prg = model.symbolsToPrg(cautious_model)
+        b_prg = model.tagBravePrg(brave_model)
+        return c_prg+b_prg
+
+    @classmethod
+    def fromWidgetsFileAndProgram(cls, ctl, widgets_files, prg):
+        model = cls()
+
+        wctl = cls.widControl(widgets_files, prg)
+
+        with wctl.solve(yield_=True) as result:
+            for m in result:
+                model_symbols = m.symbols(shown=True)
+                break
+
+        model._setFbSymbols(model_symbols)
+        return model
+
+
+    @classmethod
+    def fromWidgetsFile(cls, ctl, widgets_files, assumptions):
+        prg = cls.getCautiousBrave(ctl,assumptions)
+        return cls.fromWidgetsFileAndProgram(ctl,widgets_files,prg)
+
+    @classmethod
+    def fromCtl(cls, ctl):
+        model = cls()
+        with ctl.solve(yield_=True) as result:
+            for m in result:
+                model_symbols = m.symbols(shown=True)
+                break
+
+        model._setFbSymbols(model_symbols)
+        return model
+
+
+    @classmethod
+    def widControl(cls, widgets_files, extra_prg=""):
+        wctl = Control(['0','--warn=none'])
+        for f in widgets_files:
+            try:
+                wctl.load(str(f))
+            except Exception as e:
+                logger = logging.getLogger(Logger.server_logger_name)
+                logger.critical("File %s  could not be loaded - likely not existant or syntax error in file!", str(f))
+                raise e
+        
+        wctl.add("base",[],extra_prg)
+        wctl.add("base",[],"#show element/3. #show attribute/3. #show callback/3.")
+        wctl.ground([("base",[])])
+
+        return wctl
+
+    def addMessage(self,title,message):
+        self.addElement("message","message","window")
+        self.addAttribute("message","title",title)
+        self.addAttribute("message","message",message)
+
+    def tag(self, model, tag):
+        tagged = []
+        for s in model:
+            tagged.append(Function(tag,[s]))
+        return tagged
+
+    def symbolsToPrg(self,symbols):
+        return "\n".join([str(s)+"." for s in symbols])
+
+    def tagBravePrg(self, model):
+        tagged = self.tag(model,'_b')
+        return self.symbolsToPrg(tagged)
+    
+    def tagCautiousPrg(self, model):
+        tagged = self.tag(model,'_c')
+        return self.symbolsToPrg(tagged)
+
+
+    def addElement(self, id, t, parent):
+        if type(id)==str:
+            id = Function(id,[])
+        if type(t)==str:
+            t = Function(t,[])
+        if type(parent)==str:
+            parent = Function(parent,[])
+        self._factbase.add(ElementDao(Raw(id),Raw(t),Raw(parent)))
+
+    def addAttribute(self, id, key, value):
+        if type(id)==str:
+            id = Function(id,[])
+        if type(key)==str:
+            key = Function(key,[])
+        if type(value)==str:
+            value = String(value)
+        if type(value)==int:
+            value = Number(value)
+        self._factbase.add(AttributeDao(Raw(id),Raw(key),Raw(value)))
+
+    def filterElements(self, condition):
+        elements = self.getElements()
+        kept_elements = [e for e in elements if condition(e)]
+        kept_ids = [e.id for e in kept_elements]
+        attributes = self.getAttributes()
+        callbacks = self.getCallbacks()
+        kept_attributes = [e for e in attributes if e.id in kept_ids]
+        kept_callbacks = [e for e in callbacks if e.id in kept_ids]
+        self._factbase=clorm.FactBase(kept_elements+kept_callbacks+kept_attributes)
+
     def getElements(self):
         return self._factbase.query(ElementDao).all()
+    
+    def getAttributes(self):
+        return self._factbase.query(AttributeDao).all()
+
+    def getAttributesGrouped(self):
+        return self._factbase.query(AttributeDao).group_by(AttributeDao.id).all()
+
+    def getCallbacksGrouped(self):
+        return self._factbase.query(CallbackDao).group_by(CallbackDao.id).all()
+
+    def getCallbacks(self):
+        return self._factbase.query(CallbackDao).all()
 
     def getAttributesForElementId(self, element_id):
         return self._factbase.query(AttributeDao).where(
@@ -33,32 +210,33 @@ def getAttributesForElementId(self, element_id):
     def getCallbacksForElementId(self, element_id):
         return self._factbase.query(CallbackDao).where(
             CallbackDao.id == element_id).all()
-
-    def computeBrave(self, ctl, assumptions, condition_on_symbols):
+    
+    def _setFbSymbols(self, symbols):
+        self._factbase = clorm.unify(self.unifiers, symbols)
+
+    def _compute(self,ctl, assumptions):
+        with ctl.solve(assumptions=[(a,True) for a in assumptions],
+                yield_=True) as result:
+            model_symbols = None
+            for m in result:
+                model_symbols = m.symbols(shown=True,atoms=False)
+        if model_symbols is None:
+            raise NoModelError
+        return list(model_symbols)
+
+    def computeBrave(self, ctl, assumptions):
         ctl.configuration.solve.enum_mode = 'brave'
-        self._compute(ctl, assumptions, condition_on_symbols)
-
-    def computeCautious(self, ctl, assumptions, condition_on_symbols):
+        return self._compute(ctl, assumptions)
+    
+    def computeCautious(self, ctl, assumptions):
         ctl.configuration.solve.enum_mode = 'cautious'
-        self._compute(ctl, assumptions, condition_on_symbols)
-
-    def _compute(self, ctl, assumptions, condition_on_symbols):
-        ctl.solve(
-            on_model=self._save, assumptions=[
-                (clingo.parse_term(a), True) for a in list(assumptions)])
-        if hasattr(self, '_model'):
-            tmp_factbase = clorm.unify(self.unifiers, self._model)
-
-            for w in tmp_factbase.query(ElementDao).all():
-                if (condition_on_symbols(w)):
-                    self._factbase.add(w)
-                    for attr in tmp_factbase.query(AttributeDao).all():
-                        if str(attr.id) == str(w.id):
-                            self._factbase.add(attr)
-
-                    for call in tmp_factbase.query(CallbackDao).all():
-                        if str(call.id) == str(w.id):
-                            self._factbase.add(call)
-
-    def _save(self, model):
-        self._model = model.symbols(atoms=True, shown=True)
+        return self._compute(ctl, assumptions)
+
+    def computeAuto(self, ctl, assumptions):
+        ctl.configuration.solve.enum_mode = 'auto'
+        return self._compute(ctl, assumptions)
+
+
+    def getFactbase(self):
+        return self._factbase
+
diff --git a/clinguin/server/data/element.py b/clinguin/server/data/element.py
index 0c0874ee..14a8cbfc 100644
--- a/clinguin/server/data/element.py
+++ b/clinguin/server/data/element.py
@@ -1,10 +1,18 @@
-from clorm import Predicate, ConstantField, RawField, Raw, StringField
-
+"""
+Module that contains the ElementDao.
+"""
+from clorm import Predicate, RawField
 
 class ElementDao(Predicate):
+    """
+    Class for CLORM (clingo-object-relational-mapping), i.e. for accessing elements in a factbase.
+    """
     id = RawField
     type = RawField
     parent = RawField
 
     class Meta:
+        """
+        Meta class
+        """
         name = "element"
diff --git a/clinguin/server/presentation/backend_policy_dto.py b/clinguin/server/presentation/backend_policy_dto.py
new file mode 100644
index 00000000..862b39e0
--- /dev/null
+++ b/clinguin/server/presentation/backend_policy_dto.py
@@ -0,0 +1,11 @@
+"""
+Module that contains the BackendPolicyDto
+"""
+
+from pydantic import BaseModel
+
+class BackendPolicyDto(BaseModel):
+    """
+    Needed by the endpoints to get convert the transported json into something useful for the backend.
+    """
+    function: str
diff --git a/clinguin/server/presentation/endpoints.py b/clinguin/server/presentation/endpoints.py
index faa6dcc7..fe96b80a 100644
--- a/clinguin/server/presentation/endpoints.py
+++ b/clinguin/server/presentation/endpoints.py
@@ -1,38 +1,43 @@
-# Standard Python
-from fastapi import FastAPI, APIRouter
-
+"""
+Module for the Endpoints class.
+"""
 import logging
-import clingo
+from importlib.metadata import metadata
 
-from pydantic import BaseModel
-from typing import Sequence, Any
+from fastapi import APIRouter
 
-from importlib.metadata import metadata
+import clingo
 
+from clinguin.utils import Logger
 # Self Defined
-from clinguin.server.presentation.endpoints_helper import call_function
-from clinguin.server.presentation.solver_dto import SolverDto
-
-from clinguin.utils.logger import Logger
+from .endpoints_helper import EndpointsHelper
+from .backend_policy_dto import BackendPolicyDto
 
 
 class Endpoints:
+    """
+    The endpoints class define the available endpoints the backend (this time backend refers to the general concept of backend, like a server backend) has. These are defined in the ''__init__'', and correspond to the three methods:
+
+    Methods:
+        health -> Json : Returns name, version and description of clinguin.
+        standardExecutor -> Json : Returns the default GUI representation as Json that the Backend provides.
+        policyExecutor -> Json : Executes a policy defined by the Json passed with the Post request.
+    """
     def __init__(self, args) -> None:
-        Logger.setupLogger(args.log_args)
+        Logger.setupLogger(args.log_args, process = "server")
         self._logger = logging.getLogger(args.log_args['name'])
 
         self.router = APIRouter()
 
         # Definition of endpoints
         self.router.add_api_route("/health", self.health, methods=["GET"])
-        self.router.add_api_route("/", self.standardSolver, methods=["GET"])
-        self.router.add_api_route("/solver", self.solver, methods=["POST"])
+        self.router.add_api_route("/", self.standardExecutor, methods=["GET"])
+        self.router.add_api_route("/backend", self.policyExecutor, methods=["POST"])
 
-        self._solver = []
-        self._solver.append(args.solver(args))
+        self._backend = args.backend(args)
 
     async def health(self):
-
+        self._logger.info("--> Health")
         cuin = metadata('clinguin')
         return {
             "name": cuin["name"],
@@ -40,18 +45,22 @@ async def health(self):
             "description": cuin["summary"]
         }
 
-    async def standardSolver(self):
-        return self._solver[0].get()
+    async def standardExecutor(self):
+        self._logger.info("--> %s:   get()", self._backend.__class__.__name__)
+        return self._backend.get()
 
-    async def solver(self, solver_call_string: SolverDto):
-
-        symbol = clingo.parse_term(solver_call_string.function)
+    async def policyExecutor(self, backend_call_string: BackendPolicyDto):
+        self._logger.debug("Got endpoint")
+        symbol = clingo.parse_term(backend_call_string.function)
         function_name = symbol.name
         function_arguments = (
-            list(map(lambda symb: str(symb), symbol.arguments)))
+            list(map(str, symbol.arguments)))
+
+        call_args = ",".join(function_arguments)
+        self._logger.info("--> %s:   %s(%s))", self._backend.__class__.__name__, function_name, call_args)
 
-        result = call_function(
-            self._solver,
+        result = EndpointsHelper.callFunction(
+            self._backend,
             function_name,
             function_arguments,
             {})
diff --git a/clinguin/server/presentation/endpoints_helper.py b/clinguin/server/presentation/endpoints_helper.py
index f0d61f2a..a161fcb3 100644
--- a/clinguin/server/presentation/endpoints_helper.py
+++ b/clinguin/server/presentation/endpoints_helper.py
@@ -1,15 +1,38 @@
+"""
+Module that contains the EndpointsHelper class.
+"""
+import logging
 
-def call_function(engines, name, args, kwargs):
-    found = False
-    function = None
-    for engine in engines:
-        if hasattr(engine, name):
-            function = getattr(engine, name)
+from clinguin.utils import CaseConverter, Logger
+
+class EndpointsHelper:
+    """
+    The EndpointsHelper class is responsible for getting the correct method in the ''backend'' (here backend refers to ClingoBackend, TemporalBackend, etc.). This is done via reflections, i.e. it checks if the method is in the backend, if yes the method it returned.
+    """
+
+    @classmethod
+    def callFunction(cls, backend, name, args, kwargs):
+        logger = logging.getLogger(Logger.server_logger_name)
+
+        found = False
+        function = None
+
+        snake_case_name = name
+        camel_case_name = CaseConverter.snakeCaseToCamelCase(snake_case_name)
+
+
+        if hasattr(backend, snake_case_name):
+            function = getattr(backend, snake_case_name)
             found = True
-            break
+        elif hasattr(backend, camel_case_name):
+            function = getattr(backend, camel_case_name)
+            found = True
+
+        if found:
+            result = function(*args, **kwargs)
+            return result
+        else:
+            error_string = "Could not find function: " + name + " :in backend"
+            logger.error(error_string)
+            raise Exception(error_string)
 
-    if found:
-        result = function(*args, **kwargs)
-        return result
-    else:
-        print('[CRITICAL] - Could not find function ' + name + ' in solver')
diff --git a/clinguin/server/presentation/solver_dto.py b/clinguin/server/presentation/solver_dto.py
deleted file mode 100644
index 9cf42dbb..00000000
--- a/clinguin/server/presentation/solver_dto.py
+++ /dev/null
@@ -1,6 +0,0 @@
-from pydantic import BaseModel
-from typing import Sequence, Any
-
-
-class SolverDto(BaseModel):
-    function: str
diff --git a/clinguin/server_helper.py b/clinguin/server_helper.py
index 0e581465..7c6d6f04 100644
--- a/clinguin/server_helper.py
+++ b/clinguin/server_helper.py
@@ -1,16 +1,22 @@
+"""
+Responsible for starting the server
+"""
 import uvicorn
-from fastapi import FastAPI, APIRouter
+from fastapi import FastAPI
 
-from clinguin.utils.logger import Logger
-from clinguin.server.presentation.endpoints import Endpoints
+from clinguin.utils import Logger
+from clinguin.server import Endpoints
 
 
 def start(args):
+    """
+    Function that starts the uvicorn server.
+    """
 
     app = FastAPI()
 
     @app.on_event("startup")
-    async def startup_event():
+    async def startupEvent():
         Logger.setupUvicornLoggerOnStartup(args.log_args)
 
     endpoints = Endpoints(args)
diff --git a/clinguin/show_gui_syntax_enum.py b/clinguin/show_gui_syntax_enum.py
new file mode 100644
index 00000000..83d35a84
--- /dev/null
+++ b/clinguin/show_gui_syntax_enum.py
@@ -0,0 +1,14 @@
+"""
+Defines the possibilities how to show the syntax.
+"""
+from enum import Enum, auto
+
+class ShowGuiSyntaxEnum(Enum):
+    """
+    Defines the possibilities how to show the syntax.
+    """
+    NONE = auto()
+    SHOW = auto()
+    FULL = auto()
+
+
diff --git a/clinguin/utils/__init__.py b/clinguin/utils/__init__.py
index e69de29b..9a53e638 100644
--- a/clinguin/utils/__init__.py
+++ b/clinguin/utils/__init__.py
@@ -0,0 +1,12 @@
+"""
+The utils module of clinguin - contains some useful tools for clinguin.
+"""
+from .logger import Logger
+from .errors import NoModelError
+from .custom_args import CustomArgs
+from .case_converter import CaseConverter
+from .attribute_types.utils.standard_text_processing import StandardTextProcessing
+
+__all__ = [Logger.__name__, CustomArgs.__name__, CaseConverter.__name__,NoModelError.__name__,StandardTextProcessing.__name__]
+
+
diff --git a/clinguin/utils/attribute_types/__init__.py b/clinguin/utils/attribute_types/__init__.py
new file mode 100644
index 00000000..0de00a9e
--- /dev/null
+++ b/clinguin/utils/attribute_types/__init__.py
@@ -0,0 +1,21 @@
+"""
+Module which contains all possible attribute- and callback-types.
+"""
+from .type import Type
+from .boolean import BooleanType
+from .integer import IntegerType
+from .float import FloatType
+from .string import StringType
+from .color import ColorType
+from .enum import EnumType
+from .child_layout import ChildLayoutType
+from .symbol import SymbolType
+from .image import ImageType
+from .path import PathType
+from .popup_types import PopupTypesType
+from .font_families import FontFamiliesType
+from .font_weight import FontWeightType
+
+__all__ = [Type.__name__, BooleanType.__name__, IntegerType.__name__, FloatType.__name__, StringType.__name__, ColorType.__name__, EnumType.__name__, ChildLayoutType.__name__, SymbolType.__name__, ImageType.__name__, PathType.__name__,PopupTypesType.__name__,FontFamiliesType.__name__, FontWeightType.__name__]
+
+
diff --git a/clinguin/utils/attribute_types/boolean.py b/clinguin/utils/attribute_types/boolean.py
new file mode 100644
index 00000000..f92481a1
--- /dev/null
+++ b/clinguin/utils/attribute_types/boolean.py
@@ -0,0 +1,29 @@
+"""
+Module that contains the BooleanType class.
+"""
+
+from .type import Type
+from .utils.standard_text_processing import StandardTextProcessing
+
+class BooleanType(Type):
+    """
+    Class that resembles a boolean value in the attributes.
+    """
+
+    @classmethod
+    def parse(cls, input: str, logger):
+        parsed_string = StandardTextProcessing.parseStringWithQuotes(input)
+
+        if parsed_string.lower() == "true":
+            return True
+        elif parsed_string.lower() == "false":
+            return False
+        else:
+            logger.error("Could not parse string to boolean: " + parsed_string)
+            raise Exception("Could not parse string to boolean: " + parsed_string)
+            
+
+
+    @classmethod
+    def description(cls):
+        return "For the boolean type, either true or false are allowed - either as string or as a clingo-symbol. If one provides it as a string, it is case-insensitive."     
diff --git a/clinguin/utils/attribute_types/child_layout.py b/clinguin/utils/attribute_types/child_layout.py
new file mode 100644
index 00000000..00e8eee8
--- /dev/null
+++ b/clinguin/utils/attribute_types/child_layout.py
@@ -0,0 +1,39 @@
+"""
+Module that contains the ChildLayoutType.
+"""
+from enum import auto
+
+from .utils.standard_text_processing import StandardTextProcessing
+from .enum import EnumType
+
+
+class ChildLayoutType(EnumType):
+    """
+    The ChildLayoutType is an Enum Type, which can be used to specify the layout of the children.
+    """
+
+    FLEX = auto()
+    GRID = auto()
+    ABSSTATIC = auto()
+    RELSTATIC = auto()
+
+    @classmethod
+    def parse(cls, input: str, logger):
+        parsed_string = (StandardTextProcessing.parseStringWithQuotes(input)).lower()
+
+        if parsed_string == cls.FLEX.name.lower():
+            return cls.FLEX
+        elif parsed_string == cls.GRID.name.lower():
+            return cls.GRID
+        elif parsed_string == cls.ABSSTATIC.name.lower():
+            return cls.ABSSTATIC
+        elif parsed_string == cls.RELSTATIC.name.lower():
+            return cls.RELSTATIC
+        else:
+            logger.error("Could not parse " + parsed_string + " to child_layout type.")
+            raise Exception("Could not parse " + parsed_string + " to child_layout type.")
+        
+
+    @classmethod
+    def description(cls):
+        return "For the child-layout four different options exists: flex (default, tries to do it automatically), grid (grid-like-specification), absstatic (if one wants to specify the position with absolute-pixel coordinates) and relstatic (if one wants to specify the position with relative-pixel coordinates (from 0 to 100 percent, where 0 means left/top and 100 means right/bottom)). They can either be specified via a clingo symbol or via a string (string is case-insensitive)."
diff --git a/clinguin/utils/attribute_types/color.py b/clinguin/utils/attribute_types/color.py
new file mode 100644
index 00000000..e0b25f22
--- /dev/null
+++ b/clinguin/utils/attribute_types/color.py
@@ -0,0 +1,22 @@
+"""
+This module contains the ColorType class.
+"""
+
+from .type import Type
+from .utils.standard_text_processing import StandardTextProcessing
+
+class ColorType(Type):
+    """
+    The color type is used for specifying a color.
+    """
+
+    @classmethod
+    def parse(cls, input: str, logger):
+        parsed_string = (StandardTextProcessing.parseStringWithQuotes(input)).lower()
+
+        return parsed_string
+
+
+    @classmethod
+    def description(cls):
+        return "One can specify the color either by providing a simple-color symbol or string (like white, black, etc.), or by specifying it directly via a 9-digit hex-string, where the definition of it is: \"#RRRGGGBBB\", where R means Red, G means Green and B means Blue. E.g. black is \"#000000000\", red is \"#fff000000\", green \"#000fff000\", blue \"#000000fff\" and white \"fffffffff\"."
diff --git a/clinguin/utils/attribute_types/enum.py b/clinguin/utils/attribute_types/enum.py
new file mode 100644
index 00000000..7724d820
--- /dev/null
+++ b/clinguin/utils/attribute_types/enum.py
@@ -0,0 +1,12 @@
+"""
+This module contains the EnumType.
+"""
+
+from enum import Enum
+from .type import Type
+
+class EnumType(Type, Enum):
+    """
+    The EnumType shall not be directly used, only subtypes of the EnumType (like the ChildLayout) shall be used.
+    """
+
diff --git a/clinguin/utils/attribute_types/float.py b/clinguin/utils/attribute_types/float.py
new file mode 100644
index 00000000..ad824a58
--- /dev/null
+++ b/clinguin/utils/attribute_types/float.py
@@ -0,0 +1,25 @@
+"""
+This module contains the FloatType class.
+"""
+
+from .type import Type
+from .utils.standard_text_processing import StandardTextProcessing
+
+class FloatType(Type):
+    """
+    The flaot type shall be used, when the attribute-value is float like.
+    """
+
+    @classmethod
+    def parse(cls, input: str, logger):
+        parsed_string = StandardTextProcessing.parseStringWithQuotes(input)
+
+        try:
+            return float(parsed_string)
+        except:
+            logger.error("Could not parse string to float: " + parsed_string)
+            raise Exception("Could not parse string to float: " + parsed_string)
+
+    @classmethod
+    def description(cls):
+        return "Is a float type. A float must be specified as a string (e.g. \"5.98\")."
diff --git a/clinguin/utils/attribute_types/font_families.py b/clinguin/utils/attribute_types/font_families.py
new file mode 100644
index 00000000..f6495bdd
--- /dev/null
+++ b/clinguin/utils/attribute_types/font_families.py
@@ -0,0 +1,24 @@
+"""
+Module that contains the FontFamiliesType.
+"""
+from enum import auto
+
+
+from .utils.standard_text_processing import StandardTextProcessing
+from .type import Type
+
+class FontFamiliesType(Type):
+    """
+    The FontFamlies is a type, which can be used to specify the font family of a text.
+    """
+
+    @classmethod
+    def parse(cls, input: str, logger):
+        parsed_string = StandardTextProcessing.parseStringWithQuotes(input)
+
+        return parsed_string
+
+
+    @classmethod
+    def description(cls):
+        return "As the font-families change from system to system, clinguin cannot provide a useful selection of fonts here. Therefore one should search in one's favorite search engine, how to get a list of available fonts for one's operating system. Generally one can then use the name of the preferred font-family as the value. Some wide spread and popular font-families are (NOTE THAT THEY MIGHT NOT WORK ON YOUR SYSTEM!!!): [''helvetica'',''times'',''arial'',''courier'']."
diff --git a/clinguin/utils/attribute_types/font_weight.py b/clinguin/utils/attribute_types/font_weight.py
new file mode 100644
index 00000000..37c4f456
--- /dev/null
+++ b/clinguin/utils/attribute_types/font_weight.py
@@ -0,0 +1,58 @@
+"""
+Module that contains the FontWeightType.
+"""
+from enum import auto
+
+import itertools
+
+from .utils.standard_text_processing import StandardTextProcessing
+from .enum import EnumType
+
+class FontWeightType(EnumType):
+    """
+    The FontWeightType is an Enum Type, which can be used to specify look and feel of text.
+    """
+
+    NORMAL = auto()
+    ITALIC = auto()
+    BOLD = auto()
+    ITALIC_BOLD = auto()
+
+    @classmethod
+    def parse(cls, input: str, logger):
+        parsed_string = (StandardTextProcessing.parseStringWithQuotes(input)).lower()
+
+        normals = ["n", "normal"]
+        bolds = ["b", "bold"]
+        italics = ["i", "italic"]
+        
+        combination = [bolds, italics]
+
+        bolds_italic_list = []
+        for p in itertools.permutations(combination, 2):
+            l0 = p[0]
+            l1 = p[1]
+            zipped = list(zip(l0, l1))
+            for l in zipped:
+                bolds_italic_list.append(str(l[0]) + str(l[1]))
+                bolds_italic_list.append(str(l[0]) + "_" + str(l[1]))
+                bolds_italic_list.append(str(l[0]) + "-" + str(l[1]))
+
+        if parsed_string in bolds_italic_list:
+            return cls.ITALIC_BOLD
+        elif parsed_string in bolds:
+            return cls.BOLD
+        elif parsed_string in italics:
+            return cls.ITALIC
+        elif parsed_string in normals:
+            return cls.NORMAL
+        else:
+            error_string = "Could not parse " + parsed_string + " to FontWeightType."
+            logger.error(error_string)
+            raise Exception(error_string)
+        return cls.NORMAL
+
+    @classmethod
+    def description(cls):
+        return "For the FontWeightType several different options exists - [\"i\" or \"italic\"] for italic, [\"b\" or \"bold\"] for bold and any permuation (with the delimiters \"_\", \"-\" and no delimiter) of those for both italic and bolt. Further \"normal\" exists for specifying normal font weight."
+
diff --git a/clinguin/utils/attribute_types/image.py b/clinguin/utils/attribute_types/image.py
new file mode 100644
index 00000000..7ec529ec
--- /dev/null
+++ b/clinguin/utils/attribute_types/image.py
@@ -0,0 +1,30 @@
+"""
+This module contains the ImageType class.
+"""
+import base64
+
+from .type import Type
+from .utils.standard_text_processing import StandardTextProcessing
+
+class ImageType(Type):
+    """
+    The ImageType shall be used when the image is transferred from the backend to the frontend via a Base64 encoded string.
+    """
+
+    @classmethod
+    def parse(cls, input: str, logger):
+        parsed_string = StandardTextProcessing.parseStringWithQuotes(input)
+
+        try:
+            image_initial_bytes = parsed_string.encode('utf-8')
+            base64.b64decode(image_initial_bytes)
+        except:
+            logger.error("Sent image is not base64 encoded.")
+            raise Exception("Sent image is not base64 encoded.")
+
+        return parsed_string
+
+
+    @classmethod
+    def description(cls):
+        return "Image, needs to be a base64 encoded image, given as a string."
diff --git a/clinguin/utils/attribute_types/integer.py b/clinguin/utils/attribute_types/integer.py
new file mode 100644
index 00000000..c5c2c132
--- /dev/null
+++ b/clinguin/utils/attribute_types/integer.py
@@ -0,0 +1,27 @@
+"""
+This module contains the IntegerType class.
+"""
+
+from .type import Type
+from .utils.standard_text_processing import StandardTextProcessing
+
+class IntegerType(Type):
+    """
+    The IntegerType shall be used, when the attribute value is integer like.
+    """
+
+    @classmethod
+    def parse(cls, input: str, logger):
+        parsed_string = StandardTextProcessing.parseStringWithQuotes(input)
+
+        try:
+            return int(parsed_string)
+        except:
+            logger.error("Could not parse string to int: " + parsed_string)
+            raise Exception("Could not parse string to int: " + parsed_string)
+
+    @classmethod
+    def description(cls):
+        return "Specification as an integer, can be either specified as a symbol or a string."
+
+        
diff --git a/clinguin/utils/attribute_types/path.py b/clinguin/utils/attribute_types/path.py
new file mode 100644
index 00000000..e79890af
--- /dev/null
+++ b/clinguin/utils/attribute_types/path.py
@@ -0,0 +1,28 @@
+"""
+This module contains the PathType.
+"""
+
+from os import path
+
+from .type import Type
+from .utils.standard_text_processing import StandardTextProcessing
+
+class PathType(Type):
+    """
+    The PathType shall be used, when a path is specified (checks if path exists).
+    """
+
+    @classmethod
+    def parse(cls, input: str, logger):
+        parsed_string = StandardTextProcessing.parseStringWithQuotes(input)
+        
+        if path.exists(parsed_string):
+            return parsed_string
+        else:
+            error_string = "Could not find specified path: " + parsed_string
+            logger.error(error_string)
+            raise Exception(error_string)
+
+    @classmethod
+    def description(cls):
+        return "String, can either be specified as a string or if it is simple as a symbol."
diff --git a/clinguin/utils/attribute_types/popup_types.py b/clinguin/utils/attribute_types/popup_types.py
new file mode 100644
index 00000000..87abf027
--- /dev/null
+++ b/clinguin/utils/attribute_types/popup_types.py
@@ -0,0 +1,36 @@
+"""
+Module that contains the PopupTypesType.
+"""
+from enum import auto
+
+from .utils.standard_text_processing import StandardTextProcessing
+from .enum import EnumType
+
+class PopupTypesType(EnumType):
+    """
+    The PopupType is an Enum Type, which can be used to specify look and feel of the message box.
+    """
+
+    INFO = auto()
+    WARNING = auto()
+    ERROR = auto()
+
+    @classmethod
+    def parse(cls, input: str, logger):
+        parsed_string = (StandardTextProcessing.parseStringWithQuotes(input)).lower()
+
+        if parsed_string == cls.INFO.name.lower():
+            return cls.INFO
+        elif parsed_string == cls.WARNING.name.lower():
+            return cls.WARNING
+        elif parsed_string == cls.ERROR.name.lower():
+            return cls.ERROR
+        else:
+            error_string = "Could not parse " + parsed_string + " to PopupTypesType."
+            logger.error(error_string)
+            raise Exception(error_string)
+
+    @classmethod
+    def description(cls):
+        return "For the popup-types three different options exists: ''info'' (Default information message), ''warning'' and ''error''"
+
diff --git a/clinguin/utils/attribute_types/string.py b/clinguin/utils/attribute_types/string.py
new file mode 100644
index 00000000..cc093314
--- /dev/null
+++ b/clinguin/utils/attribute_types/string.py
@@ -0,0 +1,22 @@
+"""
+This module contains the StringType class.
+"""
+
+from .type import Type
+from .utils.standard_text_processing import StandardTextProcessing
+
+class StringType(Type):
+    """
+    The StringType shall be used, when the attribute value is string like.
+    """
+
+    @classmethod
+    def parse(cls, input: str, logger):
+        parsed_string = StandardTextProcessing.parseStringWithQuotes(input)
+
+        return parsed_string
+
+
+    @classmethod
+    def description(cls):
+        return "String, can either be specified as a string or if it is simple as a symbol."
diff --git a/clinguin/utils/attribute_types/symbol.py b/clinguin/utils/attribute_types/symbol.py
new file mode 100644
index 00000000..43bf47ae
--- /dev/null
+++ b/clinguin/utils/attribute_types/symbol.py
@@ -0,0 +1,30 @@
+"""
+This module contains the SymbolType class.
+"""
+
+import clingo
+
+from .type import Type
+from .utils.standard_text_processing import StandardTextProcessing
+
+class SymbolType(Type):
+    """
+    This class checks if the input IS A symbol, it does not parse it to a symbol.
+    """
+
+    @classmethod
+    def parse(cls, input: str, logger) -> str:
+        parsed_string = StandardTextProcessing.parseStringWithQuotes(input)
+    
+        try:
+            clingo.parse_term(parsed_string)
+            return parsed_string
+        except:
+            error_string = "The string " + parsed_string + " is not a clingo symbol!"
+            logger.error(error_string)
+            raise Exception(error_string)
+            
+
+    @classmethod
+    def description(cls):
+        return "Corresponds to a clingo-symbol, e.g. p(4)"
diff --git a/clinguin/utils/attribute_types/type.py b/clinguin/utils/attribute_types/type.py
new file mode 100644
index 00000000..911c4d73
--- /dev/null
+++ b/clinguin/utils/attribute_types/type.py
@@ -0,0 +1,22 @@
+"""
+This module contains the Type class.
+"""
+
+class Type:
+    """
+    The Type class is the super class of all Clinguin-Value-Types, i.e. each individual type must be a subtype of Type.
+    """
+
+    @classmethod
+    def parse(cls, input : str, logger):
+        """
+        Every type must override this method. This method parses/checks the given value.
+        """
+        return None
+    
+    @classmethod
+    def description(cls):
+        """
+        Every type must override this method. One provides a textual description of available values in the return string.
+        """
+        return ""
diff --git a/clinguin/utils/attribute_types/utils/__init__.py b/clinguin/utils/attribute_types/utils/__init__.py
new file mode 100644
index 00000000..e69de29b
diff --git a/clinguin/client/presentation/tkinter/standard_text_processing.py b/clinguin/utils/attribute_types/utils/standard_text_processing.py
similarity index 53%
rename from clinguin/client/presentation/tkinter/standard_text_processing.py
rename to clinguin/utils/attribute_types/utils/standard_text_processing.py
index 0c5500cf..071539da 100644
--- a/clinguin/client/presentation/tkinter/standard_text_processing.py
+++ b/clinguin/utils/attribute_types/utils/standard_text_processing.py
@@ -1,8 +1,14 @@
+"""
+This module contains the StandardTextProcessing class.
+"""
 
 class StandardTextProcessing:
+    """
+    The sole method parseStringWithQuotes removes unecessary quotes at the beginning and the end of a string.
+    """
 
     @classmethod
-    def parseStringWithQuotes(ctl, text):
+    def parseStringWithQuotes(cls, text):
         if len(text) > 0:
             if text[0] == "\"":
                 text = text[1:]
diff --git a/clinguin/utils/case_converter.py b/clinguin/utils/case_converter.py
new file mode 100644
index 00000000..57bb8ba6
--- /dev/null
+++ b/clinguin/utils/case_converter.py
@@ -0,0 +1,19 @@
+"""
+Module contains the CaseConverter class.
+"""
+
+class CaseConverter:
+    """
+    The CaseConverter class provides functionality to convert strings from one type-case (like snake_case) to another (like camelCase).
+
+    Methods:
+        snakeCaseToCamelCase(snake_case : str) -> str
+    """
+
+    @classmethod
+    def snakeCaseToCamelCase(cls, snake_case):
+        components = snake_case.split('_')
+
+        return components[0] + ''.join(x.title() for x in components[1:]) 
+
+
diff --git a/clinguin/utils/custom_args.py b/clinguin/utils/custom_args.py
index 74f262ef..a2342e42 100644
--- a/clinguin/utils/custom_args.py
+++ b/clinguin/utils/custom_args.py
@@ -1,4 +1,14 @@
+"""
+The module contains the CustomArgs class.
+"""
+
 class CustomArgs:
+    """
+    The root class of all backend- (like ClingoBackend) and gui-classes (like TkinterGui). Needed for argparse (with the method registerOptions one can specify command line arguments, that are specific to a certain class).
+
+    Method:
+        registerOptions (parser: argparse-object)
+    """
 
     @classmethod
     def registerOptions(cls, parser):
diff --git a/clinguin/utils/errors.py b/clinguin/utils/errors.py
new file mode 100644
index 00000000..76051f9f
--- /dev/null
+++ b/clinguin/utils/errors.py
@@ -0,0 +1,8 @@
+"""
+This module provides different errors for clinguin.
+"""
+
+class NoModelError(Exception):
+    """
+    The NoModelError is raised, if the provided logic program is unsatisfiable.
+    """
diff --git a/clinguin/utils/logger.py b/clinguin/utils/logger.py
index 04966a3d..aa330bff 100644
--- a/clinguin/utils/logger.py
+++ b/clinguin/utils/logger.py
@@ -1,28 +1,78 @@
-import logging
-
-log_levels = {
-    "NOTSET": logging.NOTSET,
-    "DEBUG": logging.DEBUG,
-    "INFO": logging.INFO,
-    "WARNING": logging.WARNING,
-    "ERROR": logging.ERROR,
-    "CRITICAL": logging.CRITICAL
-}
+"""
+Module that takes care of the custom logging config, so it contains the Logger-class.
+"""
 
+import logging
+import os
 
 class Logger:
+    """
+    Provides methods to set the logging config appropriatly. In principle two loggers exists - one for the client (default name: clinguin_client) and one for the server (default name: clinguin_server).
+    """
+
+    class ColoredFormatter(logging.Formatter):
+        """
+        For colored logs.
+        """
+
+        def __init__(self, msg, use_color = True):
+            logging.Formatter.__init__(self, msg)
+            self.use_color = use_color
+
+        def format(self, record):
+            levelname = record.levelname
+            if self.use_color and levelname in Logger.COLORS:
+                color =  Logger.COLOR_SEQ % (30 + Logger.COLORS[levelname])
+                levelname_color = color + levelname[0:4] + Logger.RESET_SEQ
+                record.levelname = levelname_color
+            return logging.Formatter.format(self, record)
+
+
+
+    client_logger_name = "clinguin_client"
+    server_logger_name = "clinguin_server"
+
+    log_levels = {
+        "NOTSET": logging.NOTSET,
+        "DEBUG": logging.DEBUG,
+        "INFO": logging.INFO,
+        "WARNING": logging.WARNING,
+        "ERROR": logging.ERROR,
+        "CRITICAL": logging.CRITICAL
+    }
+
+    BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE = range(8)
+    RESET_SEQ = "\033[0m"
+    COLOR_SEQ = "\033[1;%dm"
+    BOLD_SEQ = "\033[1m"
 
     @classmethod
-    def _getLogFilePath(ctl, log_arg_dict):
-        log_file_path = "./logs/" + \
-            log_arg_dict['timestamp'] + "-" + log_arg_dict['name'] + ".log"
+    def formatter_message(cls, message, use_color = True):
+        if use_color:
+            message = message.replace("$RESET", cls.RESET_SEQ).replace("$BOLD", cls.BOLD_SEQ)
+        else:
+            message = message.replace("$RESET", "").replace("$BOLD", "")
+        return message
+
+    COLORS = {
+        'WARNING': YELLOW,
+        'INFO': GREEN,
+        'DEBUG': BLUE,
+        'CRITICAL': RED,
+        'ERROR': RED
+    }
+
+    @classmethod
+    def _getLogFilePath(cls, log_arg_dict):
+        log_file_path = os.path.join("logs",
+            (log_arg_dict['timestamp'] + "-" + log_arg_dict['name'] + ".log"))
         return log_file_path
 
     @classmethod
-    def _addShellHandlerToLogger(ctl, logger, log_arg_dict):
-        shell_formatter = logging.Formatter(log_arg_dict['format_shell'])
+    def _addShellHandlerToLogger(cls, logger, log_arg_dict):
+        shell_formatter = Logger.ColoredFormatter(log_arg_dict['format_shell'])
 
-        logger.setLevel(log_levels[log_arg_dict['level']])
+        logger.setLevel(cls.log_levels[log_arg_dict['level']])
 
         handler_sh = logging.StreamHandler()
         handler_sh.setFormatter(shell_formatter)
@@ -30,8 +80,8 @@ def _addShellHandlerToLogger(ctl, logger, log_arg_dict):
         logger.addHandler(handler_sh)
 
     @classmethod
-    def _addFileHandlerToLogger(ctl, logger, log_arg_dict, log_file_path):
-        file_formatter = logging.Formatter(log_arg_dict['format_file'])
+    def _addFileHandlerToLogger(cls, logger, log_arg_dict, log_file_path):
+        file_formatter = Logger.ColoredFormatter(log_arg_dict['format_file'])
 
         with open(log_file_path, "a+") as file_object:
             file_object.write(
@@ -44,21 +94,24 @@ def _addFileHandlerToLogger(ctl, logger, log_arg_dict, log_file_path):
         logger.addHandler(handler_f)
 
     @classmethod
-    def setupLogger(ctl, log_arg_dict):
+    def setupLogger(cls, log_arg_dict, process = None):
+        if process and process == "client": 
+            cls.client_logger_name = log_arg_dict['name']
+        elif process and process == "server":
+            cls.server_logger_name = log_arg_dict['name']
 
-        log_file_path = ctl._getLogFilePath(log_arg_dict)
+        log_file_path = cls._getLogFilePath(log_arg_dict)
 
         logger = logging.getLogger(log_arg_dict['name'])
         if not log_arg_dict['shell_disabled']:
-            ctl._addShellHandlerToLogger(logger, log_arg_dict)
-        if not log_arg_dict['file_disabled']:
-            ctl._addFileHandlerToLogger(logger, log_arg_dict, log_file_path)
+            cls._addShellHandlerToLogger(logger, log_arg_dict)
+        if log_arg_dict['file_enabled']:
+            cls._addFileHandlerToLogger(logger, log_arg_dict, log_file_path)
 
     @classmethod
-    def setupUvicornLoggerOnStartup(ctl, log_arg_dict):
+    def setupUvicornLoggerOnStartup(cls, log_arg_dict):
         # ----------------------------------------------------------
         # Remove handlers from uvicorn loggers
-
         logger = logging.getLogger("uvicorn.access")
         for handler in logger.handlers:
             logger.removeHandler(handler)
@@ -72,12 +125,12 @@ def setupUvicornLoggerOnStartup(ctl, log_arg_dict):
             logger.removeHandler(handler)
 
         # Add new handlers to top-level-uvicorn logger
-        log_file_path = ctl._getLogFilePath(log_arg_dict)
+        log_file_path = cls._getLogFilePath(log_arg_dict)
 
         logger = logging.getLogger("uvicorn")
         if not log_arg_dict['shell_disabled']:
-            ctl._addShellHandlerToLogger(logger, log_arg_dict)
-        if not log_arg_dict['file_disabled']:
-            ctl._addFileHandlerToLogger(logger, log_arg_dict, log_file_path)
+            cls._addShellHandlerToLogger(logger, log_arg_dict)
+        if log_arg_dict['file_enabled']:
+            cls._addFileHandlerToLogger(logger, log_arg_dict, log_file_path)
 
 
diff --git a/docs/imgs/02_prototype_v3.drawio b/docs/imgs/02_prototype_v3.drawio
deleted file mode 100644
index 24309fdd..00000000
--- a/docs/imgs/02_prototype_v3.drawio
+++ /dev/null
@@ -1,1 +0,0 @@
-<mxfile host="Electron" modified="2022-08-03T11:05:02.294Z" agent="5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/19.0.3 Chrome/102.0.5005.63 Electron/19.0.3 Safari/537.36" etag="LpD5YKZJXrt-XmTUWS5j" version="19.0.3" type="device" pages="6"><diagram id="3vn59K5ZR0b4-7hL4XjM" name="PT-V3-Principal-Workings">5Zthd5o6GMc/jS93DwQC+NLadu3Odufmdra9zCBTzpB4Q6y6T39DTRQSumZMMNW+6DEP8CD/5wdJ/sSBN15sXlO0nL8jCc4GwEk2A+96AMAQuvx/GdjuAi6A/i4yo2kiYofANP2FRdAR0VWa4KK2IyMkY+myHoxJnuOY1WKIUrKu7/aDZPWzLtEMa4FpjDI9+iVN2HwXjaBziN/hdDaXZ3YdsWWB5M4iUMxRQtaVkHcz8MaUELb7tNiMcVaKJ3XZHXf7xNb9F6M4ZyYHZOx++OX96u39lnrDr6tVfOc4r0SWB5StxAW/JbM05qEJJTOKFuK7s60UhJJVnuAypzPwrtbzlOHpEsXl1jVHgMfmbJHxlss/6t9RnhBThjeVkPjOrzFZYEa3fBexFQyFfoIg4In2+lAONxKxeaUUvoghQcBsn/ogEv8gdPoDzYCm2W9Ecp8X6UeaZWOSEfp4rHfj3/i3kMcLRslPXNkSPP6VR5CcVeK7vyPJ7dfl9hyoyQ2a5AawK729bvW+jbjioEnv7xH0odONroGrY9yzrr6m6zViyLob3vNPfcNDTajRcpmlMWIpya3Ty28gq1+9Ak2vCcUFv0JLBYtOLVj4/BMO58moHM7wVpyhouB9dE2XuohcHLr9Wjb+AVC2v4ldHxvXm+qu11vZ2qSsehxvfqtsOhxVNuRBT9akICsa4+cfQQzRGWbPD1NwUhus6RWuVBA2FFDGKM44ig/1IV5TVcUZJiTlV7YHyIueuONkit11i6OqQzIlke8pj7pASbQTRkv0CNn+sttzN7xU7qAhd75d3Pmwjos6NDDlTkvk9MudvF8uD7zAEDxoF3hQ4UV9ThmDpyZSn5xdg6fPd48HXlgDzzEGL6yC5/4WvAQV8/00pz2F0kh5YY+/QIEnbEuhmgj0TKGBg3ABFJoO/ix7FoYKPFFbCtVEXs8UGvgqF0Ch6VAwsIvCSIFn2JZCNZE6ye2aQt2FstlcCV3dDu3XK3B1N8pqdyWU7dMppvtRo8m9dUIFJ/c5Xd2H+lxgap1S0emRio7dd9Z6s1b9Yevet33faTqbdS3rPAPlzms7kdgbfzJRzxMJebquMOx1PNceQ9eYQ7smtD7w6vi0nUr4Xn0QF6jGYNccHt1WeZGPQ9d0LiE7Wks4hMr7jFC6dH/KoZooCpVEXXN4dGPlZXJo/FrNLmsFqlOHoC2H6oAx6pnD41srbV5TtH4p8hfohS8TPU8lRjXjjLtiZZ1PqPbpXaOn+ymXgp5x72vXKFB9GRu1tvLURD1beUB3pi4FPeMO17KJsPI6dqiuA2j7XjfqewKiW3yXgp7p3Ncy8pSVT0HbJVRqItjzEiqge6Z3nz5NBiDIuGJX3yn/NCs/vZm+/1djkuENq1NYX4Sck5zvWVuxLEIoS2d5iTInBvP4VWmnpjHKRmLDIk2S8jSN/myd9SfpM7do90uRZBmkpVbBKWjASR1mHW+Rvu7QfsT/rXDBzrcIILKtCPoCw4+4WJK8wOdbBR9Au6ogE1eq8GGFReKzLIF6I4BQf2vbbwl0g3SUF+uGd2tnUwP1Njh9DXRzcIrpw1nXQOmVm37M1W8NdGNsnKU4P+NOWa1B0w+/+q2B7hDxGsQ/z7cEancQBacuge6UfF4miF3QqKjDGvDm4VfVu3ne4bfp3s3/</diagram><diagram id="Er0SknFKu_dt-jhvT9qb" name="PT-V3-Sequence-Diag-Normal">7VrRcps4FP0aT7sP8QACGx5tx0na2Z1m1p222zcZFKNGIFaIOO7XVxjJBmSb2MVkd+JkEkuHqyt079HhonEPTKLnWwaT8C8aINKzjOC5B657lmUCxxAfObIqEHfoFsCC4UAabYEZ/okkKMctMhygtGLIKSUcJ1XQp3GMfF7BIGN0WTV7oKQ6awIXSANmPiQ6+hUHPJSrUMvK8TuEF6Ga2TTklQgqYwmkIQzosgSBaQ9MGKW8aEXPE0Ty4Km4FONu9lzd3BhDMX/JgLsh+Hkz/fDJWn24+z7HP74g37uSXp4gyeSCZ4g9ISZvma9UHMTdJ3kzi8if+AERHIveOEEMR4gLe3BNJHy/xcbLEHM0S6CfD10Khggs5BERPVM0RdI4FEPYpk8ITFI8X89qCIQhP2MpfkJ/o7TgRo7SjOczTTY5X5vSLA5QIHsPmJAJJZStbx9M7al94whcj5oKAWIcPZcgGcVbRMVq2EqYyKuOyqiktGXL/nJLkA0NwhI5bAVCScrFxvc2b6IhU3dEGl0tjVoCq+FpSMy+6KWc0UekrgToAWaEb3C1QYz+7kgfZOCLw287lei7u4Kvxx6cK/Te2w295bxy7M03HHxgvnbwnbcbfHOn5HcYfEuL/YTgfM2X5/beHAL7P/fcNvU8+gT7j+971uDfLK8Mx6Nt8w8tu6Wc5HHAom4dEbyIBTannNNovU0g46O8FBYoFTMp7AYTNRjFgbKYE+o/KhNZj7tamgKYhuuOqW1E8+XbUK4eBZUaXE9gKUEDmQqGCOSCXxUu7MqP9HZPcb47FBeuzBoXrFqKU5oxH8lR5aq65shp8COiuEBc87Nmy2aFv0Eg8P8VYcX9k8sP67WfgMM3HPzXrrt14t9OP/eAkEvj3TvhMUSQ8DBvnqCZO/SwmsiXSJ4UpUJJmlNRKEVz0XKMWrrtqKXtVlUOeKeq5aDB0R65FMmAq5JZkhukB2649qgH1bMR0Sg8tqrFtsbIL0jUQFQwa/Ttn+9dEbHyaD6dleqwrYmVJzzD22KlYfTzgsAaAm8oPkEt5V7fK/+cyNih13eOcdwSg+uHTOog9awMNnUK33+alVU1/2dcib8xzU90R+sVpVmE2qxYL+p7DM9du+865+D5YcdnUmrb64LnA43nY0oJgnFB6c9MwBe5bpfGOsNssxXqHt4fDZO0Jdc1GjtdFBymfuzfLNcpJU/o/UWY2xLmYem3Sm+nfmx0uhZrrtqibe0YxOmiylCVTYm2H1NaSO8ARvk7cTxPkzV5jGucJgSurmacZT7P2EWXz6/LTv2l/SglPrAh6n7PVEM4bhfiq7P4Ir4d0hZ4Tn+4vyoetPT25xzj9kzFBOiEz/pXQTaqfFHhDlS4Xhu3QuDDu6RhkrboDGqveOZv0Vl0t1+aKsy3Xz0D018=</diagram><diagram id="gaWVhrr-wRgjmoVhxKcP" name="PT-V3-Sequence-Connection-Error">7Vpbc6M2FP4tffDs9sEegwDDY2I7aTvtNFNvp+2+dGQjG2YFYoXwZX99JZAwIBxf1rfs1jNJ0JE4iO98Op+O4g4YRutnCpPgN+Ij3DH7/roDRh3TNIDd53+EZVNY3IFbGBY09OWgrWESfkHSKO9bZKGP0tpARghmYVI3zkgcoxmr2SClZFUfNie4/tQELpBmmMwg1q1/hT4L5Fuo1xL2n1C4CNSTjb7siaAaLA1pAH2yqpjAuAOGlBBWXEXrIcICPIVLcd/Tjt5yYhTF7JAbvPnP9uDPeEr/tZdR9+NHOv487UovS4gz+cITRJeIyimzjcKBzz4Rl1mEfw3nCIcxbz0miIYRYnw8GGFpftnaHldByNAkgTNx64ozhNsCFmHeMvglDxqD/BZatjGGSRpO86f2uYWiWUbTcIn+QGnBDWElGRNPGpYxz4eSLPaRL1vzEOMhwYTm0wdja2w92dyuo6YgQJShdcUkUXxGhL8N3fAhstdWEZWUNi3ZXm0JUtIgqJDDUkYoSbkofW/jxi9k6I4Io6mFUQtgHZ49gdmFXsoo+YRUj4/mMMOstKsF0u+1I/0qAw+G37Jr6Ltt4OvYg0tBb39P0Fs9r/oBtUgA88ahMBwtFi+/Tz50wAM3vnvHfYpf/S7/eSRCkIQ9JXiJ3v+oBa0SEgFQyCXhAYeLmNumhDES8Q4U+w9CY4QNk9knLQvVg2McHRrk19RJD0wFarUQKMKQ8YxZl8IWrKW3FxLyqZQx7hqm13NB5WO1R1m5TElGZ0h6qepPw7Hl9awDyKPcMkgXiGluOd5wUxmWiAHp7tcxvEMou2Vd4X/LwRLrr6DlQKPlLymJC/qNwjTBcNOdMJrNWEbRtYjowzTIu98EK/eQxz6Rk3vJ3nR8JlY2SGkOWp96UVbquXKIQyRf6/+dX6v+Aevudn5KYCtxfB5XJS9AELNAXN5K4CTMxZrcz8hiid1nFnLr8QfeiXnHdvY4OlOesRqEvY7etRSVDLIs7Q6Jzw0PP3CjqVbEzZXuUHqq04d99HRuR89+v2eaTt8cAG/A/zb3Og3VOZG6A69nH+P4TFRuVt1XEUnD1aiMCUk6ppPXXlPKrxbi6j3XO4z0KqIink8URmi/Mrax+bCq74LCZ+xKfBUSW6BF+AzrUsJn6lnmToXvBpkAuGJJOuWnvr+0Ti3hbMfrAfC6r3MpFxAb89ZHXXTFq+ObtyVeN6BYGxdOLcP20PVCRZht6BS7hqiY+pZdY9MdHBkefy7uWLuW7L4jQediKgE0rLkqfKsybXp1mS4luQI/uOqRrGnpXLcfY8K68h92HEJ7pMWDvy+r411HOCb5IUQVSmmCMufOOIr5QUQzGUeh7+NdAa5H9Rwbp2ZEWhfEVSOiH/zUBe7uxO0bqMzy1GhqJZIihXuybto9q6KbTeFs+j2bcNqa9LvXEE79IF1VYnOST3BLWedzRlRHtzhAFJWBm6xzqqluVb/VMxIYfaD8CdI3n2vhvhiqLQ4+8zBJRUpRMjLDJPPfqobYjVKvRUOMNg1p7tLOl7H0IlyPwTb5SCGo5ZYK6ML+AhkXhzi3mH2ggWxqweF40s3fOf7uwFaGf8qA5M3Rujp6tKm2Kmfjr2vL2Y5J1Wo5Jt3Zr8T1zGenVnPPd3ARChqOjMOy3NmykHe1LKSfMz1BnH6viam5lXIO3EpdLDEB/QhKi8FxhRyPpvwKnPsVwMsMeCXMWwuKEwo63tx+Ga5YrNuvFILxfw==</diagram><diagram id="yZBI4Xxw3_X5sHy5fpLQ" name="PT-V3-Class-Diag">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</diagram><diagram id="6o26Ud6ezv8H0E_CI5g-" name="PT-V3-Tkinter-Gui">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</diagram><diagram id="J-ZGAzYPHO0NN-VS0U5W" name="PT-V3-ClingoBackend">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</diagram></mxfile>
\ No newline at end of file
diff --git a/docs/Makefile b/docs/latex/Makefile
similarity index 100%
rename from docs/Makefile
rename to docs/latex/Makefile
diff --git a/docs/clinguin.bib b/docs/latex/clinguin.bib
similarity index 100%
rename from docs/clinguin.bib
rename to docs/latex/clinguin.bib
diff --git a/docs/clinguin.pdf b/docs/latex/clinguin.pdf
similarity index 67%
rename from docs/clinguin.pdf
rename to docs/latex/clinguin.pdf
index c4343ad1..cf010cc0 100644
Binary files a/docs/clinguin.pdf and b/docs/latex/clinguin.pdf differ
diff --git a/docs/clinguin.tex b/docs/latex/clinguin.tex
similarity index 83%
rename from docs/clinguin.tex
rename to docs/latex/clinguin.tex
index 76663967..717d6f7e 100644
--- a/docs/clinguin.tex
+++ b/docs/latex/clinguin.tex
@@ -534,7 +534,96 @@ \subsubsection{Architecture}
 \end{figure}
 
 
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Timestamp 03.08. - 02.09.2022
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\newpage
+\subsection{Version 4 - Features and polishing}
+
+This stage of development saw various refactorings, some improvements and some code cleanup. In terms of refactoring the part of the backend (we agreed on the term backend instead of solver) was de facto rewritten two times, to get a more general, widely applicable and extensible backend.\\
+The following points summarize the changes:\\[1em]
+New features:
+\begin{itemize}
+    \item Backend features/examples
+    \begin{itemize}
+        \item Housing example
+        \item Temporal clingo backend and elevator example
+        \item Clingraph backend and coloring example
+        \item TSP backend and tsp example
+    \end{itemize}
+    \item GUI features
+    \begin{itemize}
+        \item Canvas widget for images
+        \item Message widget for popup messages
+        \item Layouting options for label, button and dropdown menu
+        \item Auto fit for containers, label, button and dropdown menu
+        \item Manual positioning of the window
+    \end{itemize}
+    \item Syntax can now be shown dynamically, with the acceptd types
+    \item Logs are now shown in colors
+    \item Various other improvements
+\end{itemize}
+
+\noindent Refactorings, fixes, etc.
+\begin{itemize}
+    \item Backend, the behavior how one specifies which elements shall be rendered bravely or acutiously for the default backend are now customizable
+    \item Frontend, the layouting for containers was fixed
+    \item The argument parser was refactored, so that one can now add multiple backends with the same arguments, small further improvements
+\end{itemize}
+
+\noindent
+The general idea and the general architecture didn't change in this revision, therefore most of the things previously defined still hold. Regarding the available syntax, one can take a look at the recent examples. The intermediate Json format didn't change since the first implementation. Regarding the endpoints, there actually was a revision. Now there are three endpoints:
+\begin{itemize}
+    \item \textit{''/''} with GET - This is the ''default'' backend, where one gets the GUI one gets on startup. This endpoint calls the \textit{get} method in the corresponding backend, which each backend \textbf{must} provide (a \textit{''get(self):''} method).
+    \item \textit{''/backend''} with POST - This is the endpoint, where one can send a Json with a single key \textit{function}, where the value of function determines which backend function will be called with what arguments. E.g. the json \textit{''function'':''addAtom(p(1))''} tries to call the method ''addAtom'' with the argument ''p(1)''.
+    \item \textit{''/health''} with GET - Get version and status of program.
+\end{itemize}
+
+\subsubsection{Architecture}
+
+\noindent As described in the previous section (Prototype Version 3), one could divide the program into three parts: ProgramBase, Backends and Guis.
+
+\textbf{ProgramBase}: The ProgramBase contains basically the code that is necessary to start the whole application. In addition to the code from PT-V3 it also contains more util-features, like parsing types, and other functionalities. In this definition also the part of the Client is included, that handles API requests (but to stress out one thing: The client mustn't be started, therefore one can develop the whole client by oneself, but it still makes more sense to see the part of the client that handles the API as a part of the ProgramBase for this prototype).\\[1em]
+\textbf{Backend}: The backend code is code that can be dynamically loaded on application startup that interacts with Clingo. Therefore several backends exist, like the ClingoBackend, ClingraphBackend or TemporalBackend. Which backend is loaded can be specified via command line arguments during startup.\\[1em]
+\textbf{Gui}: The gui is, like the backend, dynamically loaded. The core of the Gui is part of the ProgramBase, therefore just the ''displaying'' functions are part of this Gui. These include the files for the tkinter-widgets or in the future the files for the IPython widgets.\\[1em]
+Even though the principal working is de facto the same as before, in the following the updated-overview-UML-class diagrams are shown:
+
+\begin{figure}[ht]
+    \begin{center}
+    \includegraphics[width=0.6\textwidth]{imgs/pt-V4-class-diag-program-base.png}
+    \caption{UML-Program-base}
+    \label{fig:pt-v4-uml-program-base}
+    \end{center}
+\end{figure}
+
+\begin{figure}[ht]
+    \begin{center}
+    \includegraphics[width=0.6\textwidth]{imgs/pt-V4-class-diag-clingo-backend.png}
+    \caption{UML-clingo-backend}
+    \label{fig:pt-V4-uml-clingo-backend}
+    \end{center}
+\end{figure}
+
+\begin{figure}[ht]
+    \begin{center}
+    \includegraphics[width=0.6\textwidth]{imgs/pt-V4-class-diag-tkinter-gui.png}
+    \caption{UML-tkinter-gui}
+    \label{fig:pt-V4-uml-tkinter-gui}
+    \end{center}
+\end{figure}
+
+
+
+
+
 
+% 3.) Code documentation
+%   a.) Major classes
+%       1.) Backend: clingo-backend, clinguin-backend, endpoints, clinguinModel, (other backends?)
+%       2.) GUI: api, gui center, abstrat-gui, tkinter-gui, major tkinter widgets
+%       3.) Other: argParse, logger, types,...
+%
+%
 
 
 
diff --git a/docs/imgs/00_initial_drawings.drawio b/docs/latex/imgs/00_initial_drawings.drawio
similarity index 100%
rename from docs/imgs/00_initial_drawings.drawio
rename to docs/latex/imgs/00_initial_drawings.drawio
diff --git a/docs/imgs/01_prototype_v2.drawio b/docs/latex/imgs/01_prototype_v2.drawio
similarity index 100%
rename from docs/imgs/01_prototype_v2.drawio
rename to docs/latex/imgs/01_prototype_v2.drawio
diff --git a/docs/latex/imgs/02_prototype_v3.drawio b/docs/latex/imgs/02_prototype_v3.drawio
new file mode 100644
index 00000000..e45eefda
--- /dev/null
+++ b/docs/latex/imgs/02_prototype_v3.drawio
@@ -0,0 +1,1 @@
+<mxfile host="Electron" modified="2022-08-15T09:20:07.057Z" agent="5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/19.0.3 Chrome/102.0.5005.63 Electron/19.0.3 Safari/537.36" etag="jZS1_px_Fg9VxhxJdtAi" version="19.0.3" type="device" pages="6"><diagram id="3vn59K5ZR0b4-7hL4XjM" name="PT-V3-Principal-Workings">5Ztdl5o6FIZ/jZc9C8Knl44z05mu9tTWdrW9TCFVVpF4Qhy1v/6EMVGSMJ2UCmZ0bsZsYCPvfiDJSxx448XmNYHL+TuconwAnHQz8K4HAAAnBOxfFdnuIi4Ig11kRrKUxw6BafYL8aDDo6ssRaW0I8U4p9lSDia4KFBCpRgkBK/l3X7gXD7rEs6QFpgmMNejX7KUznfROHAO8TuUzebizK7Dtyyg2JkHyjlM8boW8m4G3phgTHefFpsxyiv1hC67426f2Lr/YgQV1OSAnN4Pv7xfvb3fEm/4dbVK7hznFc/yAPMVv+C3eJYlLDQheEbggn93uhWCELwqUlTldAbe1XqeUTRdwqTaumYMsNicLnLWctlH/TuKEyJC0aYW4t/5NcILRMmW7SIYGnL9OEHA4+31oRxuzGPzWil8HoOcgNk+9UEk9oHr9AeaAU2z34jkPi/SjyzPxzjH5PFY78a/8W8DFi8pwT9RbUv4+FcdgQtai+/+jiS3L8vtOYEmN2iSGwRd6e11q/dtzBQHTXp/jwM/cLrRNXR1jHvW1dd0vYYUWnfDe/6pb/hAE2q0XOZZAmmGC+v08hvI6levUNNrQlDJrtBSweJTCxY9/4RDRTqqhjOsleSwLFkfLekii8jEIduvVeMfEIj2N77rY+N6U9/1eitam4zWj2PNb7VNh6OqhjjoyZqUeEUS9PwjiEIyQ/T5YQpKpcGaXuFaBYOGAooYQTlD8UEe4jVVlZ9hgjN2ZXuAvPiJO06k2F03P6o+JFMS+Z7yqAuVRDthtESPkO0vuz13w0vlLjDkzreLOz+QcVGHBqbcaYmcfrkT98vlgRcaghfYBV6g8KI+p4zBUxOpT86uwdPnu8cDL5LAc4zBi+rgub8FL4XlfD/NaU+hMFJe2OMvVOCJ2lKoJgI9U2jgIFwAhaaDP8uehZECT9yWQjWR1zOFBr7KBVBoOhQM7aIwVuAZtqVQTaROcrumUHehbDZXIle3Q/v1ClzdjbLaXYlE+3SK6X7UaHJvnVDhyX1OV/ehPpeIWKdUfHqk4mP3nVJv1qo/bN37tu87TWezrmWdZ6jceW0nEnvjTyTqeSIhTtcVhr2O59pj6BpzaNeE1geejE/bqYTvyYO4UDUGu+bw6LbKi3wcuqZzCdHRWsJhoLzPiIRL96ccqoniSEnUNYdHN1ZeJofGr9XsslYCdeoQtuVQHTDGPXN4fGulzWuK1i9F/gK96GWi56nEqGaccVesrPOJ1D69a/R0P+VS0DPufe0aBaovY+PWVp6aqGcrD+jO1KWgZ9zhWjYRVl7HDtV1AG3f68Z9T0B0i+9S0DOd+1pGnrLyKWy7hEpNFPS8hAronundp0+TAQhzptjVd8I+zapPb6bv/9WYpGhDZQrlRcgFLtie0oplHoJ5NisqlBkxiMWvKjs1S2A+4hsWWZpWp2n0Z2XWn6TP3KLdL0USZRCWWg2nsAEndZh1vEX6ukP7Ef23QiU93yKA2LYi6AsMP6JyiYsSnW8VfBDYVQWRuFaFDyvEE59lCdQbAUT6W9t+S6AbpKOiXDe8WzubGqi3welroJuDU0QezroGSq/c9GOufmugG2PjPEPFGXfKag2afvjVbw10h4jVIPl5viVQu4M4PHUJdKfk8zKF9IJGRR3WgDUPv6rezfMOP073bv4H</diagram><diagram id="Er0SknFKu_dt-jhvT9qb" name="PT-V3-Sequence-Diag-Normal">7VrRcps4FP0aT7sP8QBCNjzajpO0szvNrDttt28yKEaNQKwQcdyvrzDCBmSb2MVkd+JkEksHcQXnHh0uGvfAJHy+5SgO/mI+pj3L8J974LpnWZYxsORHhqxyxLQGMEcWnPgK2wIz8hMr0FBoSnycVAYKxqggcRX0WBRhT1QwxDlbVoc9MFqdNUYLrAEzD1Ed/Up8EeSoA40tfofJIihmNg11JETFYAUkAfLZsgSBaQ9MOGMib4XPE0wz9gpe8vNu9hzdXBjHkXjJCXdD8PNm+uGTtfpw931OfnzBnnulojwhmqobnmH+hLm6ZLEqeJBXH2fNNKR/kgdMSSR74xhzEmIhx4NrquD7LTZeBkTgWYy87NSllIjEAhFS2TNlUyZNIHkK3/QpRXFC5utZDYlw7KU8IU/4b5zk2shQlopspskm5+uhLI187KveA6F0wijj68sHU3tq30CJ66wVFGAu8HMJUizeYibvhq/kEHUUFhlVmrZs1V9uBbKRQVASh12ASIlysYm9zZtsqNQdkUZHS6OWwCo9DYnZx14iOHvExREfP6CUig1eLBCjv5vpgwp8Mf02rLDv7CJf5x6ci3r37VJvwVfm3nzD5APztcmHb5d8c6fld0i+pXE/oSS758tze28Ogf2fe26beh49SrzH9z1r8G+aVYbj0bb5h5bdUk4yHoisW0eULCKJzZkQLFwvE8TFKCuFJcrkTAV2Q2hxMo78YsScMu+xGKLqcUdLk4+SYN0xtYVovnwZqrvHfqUG1xNYStBApYJjioTUV0ULu/Kjot0zkq2OQgtXZk0LVi3FCUu5h9VZ5aq6Fgg2xJEsLrDQ4qzVsrnD3xAQ+P+acKH9k8sP67WfgMM3TP5r19268G+nn3tA2qXx7p2MGGBERZA1T/DMHX5YTeRLLE+ZUu4kzanInaK5aDnGLZ123NJ2qi4H3FPdctAQaI9dymSgVWlYnA1IDlxw7VEPqnsjspFHbNWLbU2RX7CsgZhU1ujbP9+7EmLl0Xy6KovNtiZVnvAMb0uVhtHPCgJrCNyh/AS1lLt9t/xzomKHbh8eE7glBdc3mQDsQMGmLuH7T7Oyq2b/jCv5N2bZlu5ofUdJGuI2K9aL+x6jc8fuO/AcOj8c+ExObbtd6Hyg6XzMGMUoyiX9mUv4YtftylhXmG22It3D66NhkrbsuiZj2EXBYerb/s12nTD6hN9fjLktYx6WfqvyhvVto9O9WAvVlmxr2yCwiyqjqGxKsv2YsNx6ByjM3omjeRKvxWNckySmaHU1Ezz1RMovvnx+X4b1l/ajnPjAgqjHPVMNAZ0uzFdX8cV8O5QtcGF/uL8qHrT09gePCXumYgJ0omf9qyAbV764cAcuXK+NWxHw4VXSMElbcga1Vzzzt+Qsu9svTeXDt989A9Nf</diagram><diagram id="gaWVhrr-wRgjmoVhxKcP" name="PT-V3-Sequence-Connection-Error">7Vpbc6M2GP0tffDs9sEekADDY2I7aTvtNFNvp+2+dGQj28zKiBXCl/31FSBxE44v61t265kkcJA/8PmOvqNPcQcOlptnhqLFb9THpAMMf9OBww4AwHCA+JMi2xwxgWPnyJwFvsRKYBx8wRI0JJoEPo5rAzmlhAdRHZzSMMRTXsMQY3RdHzajpH7XCM2xBoyniOjoX4HPFznq2kaJ/4SD+ULd2TTklSVSgyUQL5BP1xUIjjpwwCjl+dFyM8AkZU/xkr/vacfV4sEYDvkhb/BmP9v9P8MJ+9deLbsfP7LR50lXRlkhksgPPMZshZl8ZL5VPIinj9LDZEl+DWaYBKE4e4wwC5aYi/FwSCT8UmKP60XA8ThC0/StayERgS34kogzUxyKpHEk3sKKc0JQFAeT7K6GQBieJiwOVvgPHOfaSFGa8PROgyLn2VCahD725dksIGRACWXZ48ORNbKebIHrrCkKMON4U4Eki8+Yik/DtmKIvGqrjEpNA0uer0uBFDJYVMRhKRBJUc6L2GXexIFM3RFpBFoatQTW6dmTmF3sxZzRT1hd8fEMJYQXuJogRq+d6VcVeDD9ll1j320jX+ceXop6+3ui3up51ResZQKCG6fCdLRcvPw+/tCBDwJ8907ETH8ZXfHzSFNHSvGYkhV+/6OWtEpKUoICYQkPJJiHAptQzulSXMCh/5B6TIoROv2kVaF6csyjU4P9mjvpialQrSYCwwRxUTHrVtjCtYz2QgPxKEWOuybwei6svKz2LKuQMU3YFMsoVf9pBLa8nnWAeFRYjtgccy2s4BttK8OidEC8++OY3iGSLVWXxy81WHD9FbLsa7L8JaZhLr9hEEcEbbtjzpIpTxi+lhB9FC+yy29ClXvEY5+oyb1ibwY+kyobogT91rteVJV6rRyQAMuP9f/Kr9X/oHV3Kz9lsJU8Po+qlrfAiPBFengrg5M053NyvyLzKXafVcit5x96J9Yd29kT6Ex1xmoI9jp+19JUcsSTuDugvgAefhAgUDPi5k53qDzV7sM+eTq3k6dh9ABwDNCHXl/8ba51Gq5zonT7Xs8+JvCZpNzsuq9ikqarSZlQGnWAk/VeEyaO5unRe+F3BOtdRMU8nxha4v3O2Kbmw7q+CxqfuavwVURswRbjM61LGR/Qq8ydGt8NKgF00ynpFK/6+tI6tYWzHa8H4euxzuVcMF2Yt97qojNebd+8LfO6gcTatHBqG7ZHrhdqwmxTl9g1TAXoS3ZNTXewZXj8vrhj7Zqy+7YEnYu5BNS4Fq7wrdo08Oo2XVhyhX541S1ZYOlatx9DyrvyH3aCQnuo5UN8Xl7nu85wSLNNiCqVEkKy5k4Fi9lGRLMYLwPfJ7sSXM/qORZOzYy0ToirZkTf+Kkb3N2Z2zfQmWWlEWgtkhKFe7Jv2j2r4ptN42zGPZtx2pr1u9cwTn0jXXViM5o9YClZ53NC1YVuvoGYdgZutMmkpi6r/q1ekeDwAxN3kLHFs+bh86Ha5BBPHkRxWlKUjUwJTfy36iF2o9Vr8RCzzUOaq7TzVSy9CddzUBYfaQS12lIhPcVfEBfmEGYIMKBGMtCSI/hk278z/t2+rYB/ioRkp8NNdfRwWz2r7I2/7i1n2yZVs+WYcme/ktcz751azTXfwU0obAQyD6tyZ6tC3tWqkL7P9IRI/L0WpuZSyjlwKXWxwgT1LSgtB8c1ciKb8itw7lcQLyvglThvbShOaOjEaflluHyylt8phKP/AA==</diagram><diagram id="yZBI4Xxw3_X5sHy5fpLQ" name="PT-V3-Class-Diag">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</diagram><diagram id="6o26Ud6ezv8H0E_CI5g-" name="PT-V3-Tkinter-Gui">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</diagram><diagram id="J-ZGAzYPHO0NN-VS0U5W" name="PT-V3-ClingoBackend">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</diagram></mxfile>
\ No newline at end of file
diff --git a/docs/latex/imgs/03_clingu_presentation_general b/docs/latex/imgs/03_clingu_presentation_general
new file mode 100644
index 00000000..9c58d0b4
--- /dev/null
+++ b/docs/latex/imgs/03_clingu_presentation_general
@@ -0,0 +1,1 @@
+<mxfile host="Electron" modified="2022-08-15T09:37:34.203Z" agent="5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/19.0.3 Chrome/102.0.5005.63 Electron/19.0.3 Safari/537.36" etag="N4swIw0J9ueOxXaZCZsH" version="19.0.3" type="device" pages="6"><diagram id="oaRhgPUNiZdRGCyNHYX6" name="Clinguin-Overview">5VjLctowFP0almH8BpYBknY66Uw7LJIshS1sNcKisgw4X98rLL9kQ0jqvNoNYx09kM45uvfaA3u23n/haBN9ZwGmA8sI9gN7PrCsydiCXwlkOeAZCgg5CXLIrIAFecQKNBSakgAnjYGCMSrIpgn6LI6xLxoY4pztmsNWjDb/dYNC3AIWPqJt9JYEIsrRsWtU+FdMwqj4Z9NQPWtUDFZAEqGA7WqQfTWwZ5wxkT+t9zNMJXcFL/m86yO95cY4jsU5E9YPxu3E/SZElu4WbvbwM/p9daFW2SKaqgNnLOWAUBYSf2B5FNaeLgHxQvm04SzkaK1OJLKCJs7SOMDynwwYtYuIwIsN8mXvDnwBWCTWFFomPK4IpTNGGT/MtVerleX7gCeCswdc6wm8ped60KN2ibnA+6PHN0tSwYyYrbHgGQwpJnhKh0xr7ypZJwqKaoo6CkPKSGG5csU1PCi6n0G91aIedhJikfwP7Je0vhf7ptliEQP7C9VkXEQsZDGiVxU6bfJcjblhbKPY/YXhf1QYQ6lgTe6BLZ7dqfmHxr1sDN2iOd/XO+eZapWxI+8KLmVkg+aSMv8hh64JLf4lP5k8zmm14PRw2X18giZbhVzEwZmn6DS65eeYIkG2zY30L2b7LsFV2R4yR5fKN2gJWaqhDKIkjOHZB4owXICptDuBPHCpOtYkCHIT4IQ8ouVhPSnHhpFYHE7kTgfu/NR9UUlKTa5SQ12ZE249eruMoTW2lVRnM65W+yG3Xy11YTqNi3phajeQrVYJWEGXrNzUy1W0WyL6lMRQAMQ9BzzsHQl4o8nSMPoJeLalBTyjHfDGbxnwnG522cCa5cVXHOTPetIRuDbuMEcWep1Dh8PhZ5TK0CoDqy1Vib2JVm5Lq3YYq5KAT1GSEL/JZJN2vCfirso00Lqv9VRJRzaKnFPlqio93dfz2JFc9Q7Zx+nWt6af2yFfgf1lxHRG2k0fa7bIj6lm1Qt0bSFXDxm2tlDOQ2uhvuKv13JdmvwrCdR9Kn+a3kjLe72YQ8umzlvl0tGzIkhRRj4ZP8x69ChjyVPxo1nrWs8tdl+nsi0+JjwVW+wPFVu8vmKLXta9cmwZf1w/jj6GH63P4EdLs5E5eaEfbVvzo/W2fpy0/AiSyUnxJpVfYPTKdgWFp25YSE6iadJmmRqzGGs1rYLOz5Vd9XLzKhzNlecXwGUhW76rqAK0Ziqvw1R6fdLf+7zRkmdLkhRoe8QHEycplSp1vIIQySjyweNEwEZmfb+SBC4eB07XK8nYWtpeT5/LHP1j5eTMVxI9P5whCTSrj9D5/aq+5NtXfwA=</diagram><diagram id="6OaLx1PlNT5VRpxYTqev" name="General-Architectural-Overview">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</diagram><diagram id="lPrbb9n8igJn6qbLbl-X" name="Class-Diag-Core">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</diagram><diagram id="tXYx4tRuoePLCo8_P8JQ" name="tkinter-architectural-overview">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</diagram><diagram id="i2OZl6HNaeofM9TObKwO" name="class-diag-clingo-solver">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</diagram><diagram id="bNiTy9rHvC-QgKAiw5_x" name="Clingo-backend-tkinter-frontend-example">7Vtdd5s4EP01fuweEJ95TJxkuz3dXbdOz7aPKqiYE4y8Qo6d/fUrbGGjEakJy9c6zskDGqQB3blIoyt5Yk2X218ZXi1+pyFJJsgItxPrdoKQaSM0yf+N8Hlv8T1piFgcykpHwzz+h0ijIa3rOCSZUpFTmvB4pRoDmqYk4IoNM0Y3arUfNFGfusIR0QzzACe69a845AvZC8c42t+TOFoUTzYNeWeJi8rSkC1wSDclk3U3saaMUr6/Wm6nJMnBK3DZt7t/4e7hxRhJeZ0GdOHNHUrNj1/XW2P9AbvvzE/vpJcnnKxlhz/SKA6EacZoxPBSvjt/LgBhdJ2GJPdpTKybzSLmZL7CQX53IyggbAu+TETJFJfSO2GcbF98bfMAhmARoUvC2bOoIhugK4mfJBCyZHlzDIfpS9uiFApb2rBkQHRwfQRJXEicXoEZ0jD7CUjmaZB+xEkypQllu7bWnX1n3zvCnnFGH0npjrv7y1vQlJfs+7+W4LZVuC3D0eBGVXAjpyu8rW7xvvcF4qgK7+++YztGN7i6pk7jnnG1NVxvMcej++Ate+gP3tGAul6tkjjAPKbp6PCyK5jVL16uhteMkUx0Z6SA+UMD5p0e4UgaXufpjCgFCc4yMUcruKggCiTY89e88AtyivI3WXVXuN2Wq94+F6VtzMvtRPFb6daxVV4oGu1floRaJgUiIjpE1ywgp8ckjllE+Km8RY9wKYJORQALGyOJoOKT+rpVUZVPmNFYdORAIMt/4YsrXOy7KVuVUzLgyLbAUOcCR3scNEc7kh263Zx3/oV36hB/knf2oLyzHZUuMDWoyzvNkdEv764uvFOnypO8cwblnQPoAoep2ryDjuDA2THvisd1QjxPIZ5Rm3hemXjmT4kX4mxxWOW0yMJCWBn36OcC8nhNWQgdoZ5ZqIsuFxa+Ivcbdiz0AHn8piyEjqyeWVhDxnqLLKybCbqDstAH5LlqykLoCK5xu2ahLu6NWVvxTF0N7VcqMHXVbtTiileUh0OsQr6b/TY6oNzBZU5T1+2+ZISNDil/eEq1Ltgps1mj+bDx7Nvi3Fl3NWsOm8K54MtrupA46H6Fo74XEq3rdyoNe83nWqShWTeH22cfQ/HQRpZKn6ZLCdtSkzgX6oJd87B1Pe88hkOz7orWHHQx4YDtDK9Q6V7LQ+jI94CjjnlYDL8XHlYvsk7zcFCBz4FLB7cpD2HC6PfMw/YFvibbFI03RdqkXu2UcFhtGTIGinG1p2JwzMeDc3rX1EMX6r169h00C4R7sX5jKQ866lnKQzXO6b0V6tWecEe1r3sFjwE03df1e16AIF0UfbPU+3/sX4CDT27TE1TQkdPzCSqki8vvHx5mE+QmArGb70xcRfnVh/mff2ic5GTLVRaqZ5BTmoqayoFlacJJHKU5lQVBiLDf5AprHODkWt5YxmGYP6ZSn1W5LnvwXyTaw0mkIgyFpFaik1tBJ5hmtXdGX9eyP5O/1yTj5xsE5I8tCLpM/plkK5pm5HyjYCNnZFHQVeJPayIdn2UI4IeAPH3Xtt8Q6ALpdZptKvbWziYG8DMYPAaF41IMpkmcRlSfq+c0eTrr2IDZuuo3Xv3GRhfMHh7jHVZacETQSHrGszgMTtUPxfoNji4piRgEj+cbAjh/+O7QIdCllS+rEPM3lEZ1GANRPP4Ke78wPP6W3br7Fw==</diagram></mxfile>
\ No newline at end of file
diff --git a/docs/latex/imgs/04_prototype_v4.drawio b/docs/latex/imgs/04_prototype_v4.drawio
new file mode 100644
index 00000000..c5896eaf
--- /dev/null
+++ b/docs/latex/imgs/04_prototype_v4.drawio
@@ -0,0 +1,1 @@
+<mxfile host="Electron" modified="2022-08-29T11:28:33.133Z" agent="5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/19.0.3 Chrome/102.0.5005.63 Electron/19.0.3 Safari/537.36" etag="FnEVfO18glxFBSrzg1bQ" version="19.0.3" type="device" pages="6"><diagram id="3vn59K5ZR0b4-7hL4XjM" name="PT-Vr-Principal-Workings">5Ztdl5o6FIZ/jZc9C8Knl44z05mu9tTWdrW9TCFVVpF4Qhy1v/6EMVGSMJ2UCmZ0bsZsYCPvfiDJSxx448XmNYHL+TuconwAnHQz8K4HAAAnBOxfFdnuIi4Ig11kRrKUxw6BafYL8aDDo6ssRaW0I8U4p9lSDia4KFBCpRgkBK/l3X7gXD7rEs6QFpgmMNejX7KUznfROHAO8TuUzebizK7Dtyyg2JkHyjlM8boW8m4G3phgTHefFpsxyiv1hC67426f2Lr/YgQV1OSAnN4Pv7xfvb3fEm/4dbVK7hznFc/yAPMVv+C3eJYlLDQheEbggn93uhWCELwqUlTldAbe1XqeUTRdwqTaumYMsNicLnLWctlH/TuKEyJC0aYW4t/5NcILRMmW7SIYGnL9OEHA4+31oRxuzGPzWil8HoOcgNk+9UEk9oHr9AeaAU2z34jkPi/SjyzPxzjH5PFY78a/8W8DFi8pwT9RbUv4+FcdgQtai+/+jiS3L8vtOYEmN2iSGwRd6e11q/dtzBQHTXp/jwM/cLrRNXR1jHvW1dd0vYYUWnfDe/6pb/hAE2q0XOZZAmmGC+v08hvI6levUNNrQlDJrtBSweJTCxY9/4RDRTqqhjOsleSwLFkfLekii8jEIduvVeMfEIj2N77rY+N6U9/1eitam4zWj2PNb7VNh6OqhjjoyZqUeEUS9PwjiEIyQ/T5YQpKpcGaXuFaBYOGAooYQTlD8UEe4jVVlZ9hgjN2ZXuAvPiJO06k2F03P6o+JFMS+Z7yqAuVRDthtESPkO0vuz13w0vlLjDkzreLOz+QcVGHBqbcaYmcfrkT98vlgRcaghfYBV6g8KI+p4zBUxOpT86uwdPnu8cDL5LAc4zBi+rgub8FL4XlfD/NaU+hMFJe2OMvVOCJ2lKoJgI9U2jgIFwAhaaDP8uehZECT9yWQjWR1zOFBr7KBVBoOhQM7aIwVuAZtqVQTaROcrumUHehbDZXIle3Q/v1ClzdjbLaXYlE+3SK6X7UaHJvnVDhyX1OV/ehPpeIWKdUfHqk4mP3nVJv1qo/bN37tu87TWezrmWdZ6jceW0nEnvjTyTqeSIhTtcVhr2O59pj6BpzaNeE1geejE/bqYTvyYO4UDUGu+bw6LbKi3wcuqZzCdHRWsJhoLzPiIRL96ccqoniSEnUNYdHN1ZeJofGr9XsslYCdeoQtuVQHTDGPXN4fGulzWuK1i9F/gK96GWi56nEqGaccVesrPOJ1D69a/R0P+VS0DPufe0aBaovY+PWVp6aqGcrD+jO1KWgZ9zhWjYRVl7HDtV1AG3f68Z9T0B0i+9S0DOd+1pGnrLyKWy7hEpNFPS8hAronundp0+TAQhzptjVd8I+zapPb6bv/9WYpGhDZQrlRcgFLtie0oplHoJ5NisqlBkxiMWvKjs1S2A+4hsWWZpWp2n0Z2XWn6TP3KLdL0USZRCWWg2nsAEndZh1vEX6ukP7Ef23QiU93yKA2LYi6AsMP6JyiYsSnW8VfBDYVQWRuFaFDyvEE59lCdQbAUT6W9t+S6AbpKOiXDe8WzubGqi3welroJuDU0QezroGSq/c9GOufmugG2PjPEPFGXfKag2afvjVbw10h4jVIPl5viVQu4M4PHUJdKfk8zKF9IJGRR3WgDUPv6rezfMOP073bv4H</diagram><diagram id="Er0SknFKu_dt-jhvT9qb" name="PT-V4-Sequence-Diag-Normal">7VnbUtswEP2aDOWBjG3Zif0YQgLttFOm6dCWN8UWsYoSubJMCF9f2Zbii3KB4IR2CDOAdCytrD1nV2u7BfrTx0sGo/ALDRBpWUbw2AIXLcvyXEv8TYFFDnQMCUwYDnLILIARfkISNCSa4ADFlYGcUsJxVAV9Opshn1cwyBidV4fdUVJdNYITpAEjHxId/YEDHuao6xgFfoXwJFQrm4a8MoVqsATiEAZ0XoLAoAX6jFKet6aPfURS3ym/5POGa64ub4yhGX/OhKsueBoOPn61Fh+vbsf49w3yvTNp5QGSRG54hNgDYvKW+UL5Qdx9lDaTKfmM7xDBM9E7jxDDU8TFeHBBJHxdYOfzEHM0iqCfTp0LgQgs5FMieqZoCtI4FFPYsk8IjGI8zlY1BMKQn7AYP6BvKM61kaI04elK/SXn2VCazAIUyN4dJqRPCWXZ7YOBPbCHjsB1rykXIMbRYwmSXrxEVOyGLcQQedVRjEpJW7bszwuBLGUQlsRhKxBKUU6WtgveRENS9wIaXY1GjcCqe7YQs857MWf0HqkrAbqDCeFLXAWI0V7t6Y0KfLb7bafifXeV83Xfg3253nu/rrecN/a96bxf55srs84BnW9pvu8TnO75eHSs5RDY/9zRYeo8tqzOnyQtS85hHCdT9KF3WkAavSVSUkdgUTv1CJ7MBDamnNNpFieQ8V5ajgmUiqUUNsRETUazQI0YE+rfqyGyJnQ1ngIYh1nH1CLRfH4cyu2joFIH6gyWGOpILhgikAuBVYvOFQRJa9cUp+GhxHBm1sRg1TiOacJ8JGeVK7uaIWeLHeHFCeKanUwuyx2+QkHg/83CSvw7H4HWG2dh3feXg+8t0BPYyYmwGCJIeJg2dwjbFSFZJfI5USfjIhfzdipysW4/OF8SsG4zAWu71UAD3q4B29liaE3ECjLgojQsSgfEG264dtyA6iOiaOQWG00HtqbIGyTOYSqU1fv56/ZQQqycDrurUr1z2KbKHY6RplRpGO3svUoXeF3xH9Qo99pe+WdHxXa9tvMSww0puP6sDZwDKNjUJXz9dVTOqmPo3wtNpm3jTPye0/T9Vi/bWFYxFfVSr2ieHpPw3uXu2m3X2YfcNxveU8K2vUPIvaPJ/VOcpWsBXuA4InBxNuIs8XnC0DF/NyxoXWu22YiIN0fKlkWayt81QTuHqEBUAb6qKC4/yA5f+VR7zMwVroHntLvrM3OnoULEeYnZPckYuIeQsf5x5piXD5mX61m5EQFvjpItizQlZ1ArM8xXyVl0i8+Y+fDiWzAY/AU=</diagram><diagram id="gaWVhrr-wRgjmoVhxKcP" name="PT-V4-Sequence-Connection-Error">7Vpbk5s2FP4tffCkfbAHEGB43LW923bamZ06nTZ5ychGtpnIiAixtvPrK4HETfga3zapH3bRQRyJ73w6n47sDhgs188Uxos/SYBwxzKCdQcMO5blen3+Vxg2ucEWLWGY0zDITWZpGIdfkTQa0pqGAUpqHRkhmIVx3TglUYSmrGaDlJJVvduM4PqoMZwjzTCeQqxb/wkDtsitnmOU9l9ROF+okU1D3llC1VkakgUMyKpiAqMOGFBCWH61XA8QFtgpXPLnnrbcLSZGUcQOecCf/eb0/44m9JPzuux+/EhHXyZd6eUV4lS+8BjRV0TllNlG4cBnH4vLdIn/CGcIhxFvPcaIhkvEeH8wxNL8UtoeV4uQoXEMp+LRFScIty3YEvOWyS950Bjkj9CijTGMk3CSjWpwC0XTlCbhK/oLJTk3hJWkTIw0KGKedSVpFKBAtmYhxgOCCc2mD0b2yH5yuF1HTUGAKEPrikmi+IwIfxu64V3kXUdFVFLasmV7VRKkoMGiQg5bGaEk5bzwXcaNX8jQHRFGSwujFsA6PHsCsw29hFHyGak7AZrBFLPCrhaI0WtHeicDD4bfdmroe23g69iDS0Hv/EjQ2z2/+gG1SADrxqEwXS0Wz6P3HfDQETNzv6Qi1T6KMSqNRqwqkRC4hFwJHnA4j7htQhgjS34DRcGDkBZhw2T6WUs+9ZiYR0cEBTVR0uNRQVjxnyIMGU+UdQVsgVh6eyEhn0oR2q5p+T0PVD52e3CVy4SkdIqkl6rsNBzbfs8+gDPKLYN0jpjmluMNN5VuseiQbH8d0z+EqSXZcv8l9Qqsv4GNfY2Nvyckyuk4DJMYw013zGg6ZSlF1yJiAJNFdvtNsHIPeZwTObmX7E3HZ2Jlg5RWv3XUi7JST5EDHCL5Wv9v+FplD9h3t+FTutomde/ecZcLBDFbiMtbCZyEOV+T+xmZL7H7zEJePf7APzHvOO4eR2fKM3aDsNfRu5ZakkGWJt0BCbjh4SdutNSKuLnSHUpPdeiwj57u7ehpGD3Lcg2rD/w+/9/c6zRU50Tq9v2ec4zjM1G5WWxfRSRNT6MyJiTmZUNWck0ov5qLq5+53mH0yy7xfKJwifYrYxubDyv2Lih85rbEVyGxDVqEz7QvJXyWnmXuVPhukAmAJ5akW3zq+0v71BLOcf0eALt9nUu5gNiYtw510RWvTm3elnjdgGJtXDi1DNtD1wsVYY6pU+waomLpW3aNTXdwUnj8cbhrb1uy+04C3YupBNCw5qrwvcq05ddlupDkCvzgqiexlq1z3XmMCOvK7+k4hM5Qiwd/X1bHu45wRLJDiCqU0gRlzp1yFLODiGYyXoZBgLcFuB7Vc2ycmhFpXRBXjYh+8FMXuLsTt++gMstSo6WVSIoU3sm66fTsim42hbPp92zC6WjS711DOPWDdFWJzUg2wZKy6nsdcaObHyCKysCL1xnVyq998vqtnpHA8D3lI0jffK65+7yrtjj4zMM4ESlFycgUkzR4qxriNEq9Fg0x2zSkuUs7X8bSi3A9BmXykUJQyy0V0IX9BTIuDlFmsQyggWxpweF40s2/Gf5e31GGD0VAsuZwXe093FRblbPx3dpytmNStVqOSXfOjrie+ezUbu75Di5CQcOReViWO1sW8q+WhfRzpieIkx81MTW3Uu6BW6mLJSagH0FpMTiukOPRlL98874BeJkBr4R5a0FxQkHHm+Vv4PLFWv6QEIz+Aw==</diagram><diagram id="yZBI4Xxw3_X5sHy5fpLQ" name="PT-V4-program-base">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</diagram><diagram id="6o26Ud6ezv8H0E_CI5g-" name="PT-V4-Tkinter-Gui">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</diagram><diagram id="J-ZGAzYPHO0NN-VS0U5W" name="PT-V4-ClingoBackend">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</diagram></mxfile>
\ No newline at end of file
diff --git a/docs/imgs/client-server-v1.png b/docs/latex/imgs/client-server-v1.png
similarity index 100%
rename from docs/imgs/client-server-v1.png
rename to docs/latex/imgs/client-server-v1.png
diff --git a/docs/imgs/client-server.png b/docs/latex/imgs/client-server.png
similarity index 100%
rename from docs/imgs/client-server.png
rename to docs/latex/imgs/client-server.png
diff --git a/docs/imgs/mvc-architecture.png b/docs/latex/imgs/mvc-architecture.png
similarity index 100%
rename from docs/imgs/mvc-architecture.png
rename to docs/latex/imgs/mvc-architecture.png
diff --git a/docs/imgs/mvc.png b/docs/latex/imgs/mvc.png
similarity index 100%
rename from docs/imgs/mvc.png
rename to docs/latex/imgs/mvc.png
diff --git a/docs/imgs/overview.png b/docs/latex/imgs/overview.png
similarity index 100%
rename from docs/imgs/overview.png
rename to docs/latex/imgs/overview.png
diff --git a/docs/latex/imgs/pt-V4-03_clingu_presentation_general-Clingo-backend-tkinter-frontend-example.drawio.png b/docs/latex/imgs/pt-V4-03_clingu_presentation_general-Clingo-backend-tkinter-frontend-example.drawio.png
new file mode 100644
index 00000000..b1896bde
Binary files /dev/null and b/docs/latex/imgs/pt-V4-03_clingu_presentation_general-Clingo-backend-tkinter-frontend-example.drawio.png differ
diff --git a/docs/latex/imgs/pt-V4-class-diag-clingo-backend.png b/docs/latex/imgs/pt-V4-class-diag-clingo-backend.png
new file mode 100644
index 00000000..190ee44e
Binary files /dev/null and b/docs/latex/imgs/pt-V4-class-diag-clingo-backend.png differ
diff --git a/docs/latex/imgs/pt-V4-class-diag-program-base.png b/docs/latex/imgs/pt-V4-class-diag-program-base.png
new file mode 100644
index 00000000..9180d750
Binary files /dev/null and b/docs/latex/imgs/pt-V4-class-diag-program-base.png differ
diff --git a/docs/latex/imgs/pt-V4-class-diag-tkinter-gui.png b/docs/latex/imgs/pt-V4-class-diag-tkinter-gui.png
new file mode 100644
index 00000000..0f449cf9
Binary files /dev/null and b/docs/latex/imgs/pt-V4-class-diag-tkinter-gui.png differ
diff --git a/docs/imgs/pt-v2-class-diag.png b/docs/latex/imgs/pt-v2-class-diag.png
similarity index 100%
rename from docs/imgs/pt-v2-class-diag.png
rename to docs/latex/imgs/pt-v2-class-diag.png
diff --git a/docs/imgs/pt-v2-sequence-failure.png b/docs/latex/imgs/pt-v2-sequence-failure.png
similarity index 100%
rename from docs/imgs/pt-v2-sequence-failure.png
rename to docs/latex/imgs/pt-v2-sequence-failure.png
diff --git a/docs/imgs/pt-v2-sequence-normal.png b/docs/latex/imgs/pt-v2-sequence-normal.png
similarity index 100%
rename from docs/imgs/pt-v2-sequence-normal.png
rename to docs/latex/imgs/pt-v2-sequence-normal.png
diff --git a/docs/imgs/pt-v2-server-client.png b/docs/latex/imgs/pt-v2-server-client.png
similarity index 100%
rename from docs/imgs/pt-v2-server-client.png
rename to docs/latex/imgs/pt-v2-server-client.png
diff --git a/docs/imgs/pt-v3-class-diag-core-module.png b/docs/latex/imgs/pt-v3-class-diag-core-module.png
similarity index 100%
rename from docs/imgs/pt-v3-class-diag-core-module.png
rename to docs/latex/imgs/pt-v3-class-diag-core-module.png
diff --git a/docs/imgs/pt-v3-class-diag-program-base.png b/docs/latex/imgs/pt-v3-class-diag-program-base.png
similarity index 100%
rename from docs/imgs/pt-v3-class-diag-program-base.png
rename to docs/latex/imgs/pt-v3-class-diag-program-base.png
diff --git a/docs/imgs/pt-v3-class-diag-tkinter-client.png b/docs/latex/imgs/pt-v3-class-diag-tkinter-client.png
similarity index 100%
rename from docs/imgs/pt-v3-class-diag-tkinter-client.png
rename to docs/latex/imgs/pt-v3-class-diag-tkinter-client.png
diff --git a/docs/latex/imgs/pt-v4-presentatin-general-architectural-overview.png b/docs/latex/imgs/pt-v4-presentatin-general-architectural-overview.png
new file mode 100644
index 00000000..e917759c
Binary files /dev/null and b/docs/latex/imgs/pt-v4-presentatin-general-architectural-overview.png differ
diff --git a/docs/latex/imgs/pt-v4-presentatin-general-clinguin-idea.png b/docs/latex/imgs/pt-v4-presentatin-general-clinguin-idea.png
new file mode 100644
index 00000000..b655c9ad
Binary files /dev/null and b/docs/latex/imgs/pt-v4-presentatin-general-clinguin-idea.png differ
diff --git a/docs/imgs/uml-client.png b/docs/latex/imgs/uml-client.png
similarity index 100%
rename from docs/imgs/uml-client.png
rename to docs/latex/imgs/uml-client.png
diff --git a/docs/imgs/uml-extended-server.png b/docs/latex/imgs/uml-extended-server.png
similarity index 100%
rename from docs/imgs/uml-extended-server.png
rename to docs/latex/imgs/uml-extended-server.png
diff --git a/docs/imgs/uml-std-server.png b/docs/latex/imgs/uml-std-server.png
similarity index 100%
rename from docs/imgs/uml-std-server.png
rename to docs/latex/imgs/uml-std-server.png
diff --git a/docs/read_the_docs/Makefile b/docs/read_the_docs/Makefile
new file mode 100644
index 00000000..d0c3cbf1
--- /dev/null
+++ b/docs/read_the_docs/Makefile
@@ -0,0 +1,20 @@
+# Minimal makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line, and also
+# from the environment for the first two.
+SPHINXOPTS    ?=
+SPHINXBUILD   ?= sphinx-build
+SOURCEDIR     = source
+BUILDDIR      = build
+
+# Put it first so that "make" without argument is like "make help".
+help:
+	@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+
+.PHONY: help Makefile
+
+# Catch-all target: route all unknown targets to Sphinx using the new
+# "make mode" option.  $(O) is meant as a shortcut for $(SPHINXOPTS).
+%: Makefile
+	@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
diff --git a/docs/read_the_docs/make.bat b/docs/read_the_docs/make.bat
new file mode 100644
index 00000000..6fcf05b4
--- /dev/null
+++ b/docs/read_the_docs/make.bat
@@ -0,0 +1,35 @@
+@ECHO OFF
+
+pushd %~dp0
+
+REM Command file for Sphinx documentation
+
+if "%SPHINXBUILD%" == "" (
+	set SPHINXBUILD=sphinx-build
+)
+set SOURCEDIR=source
+set BUILDDIR=build
+
+if "%1" == "" goto help
+
+%SPHINXBUILD% >NUL 2>NUL
+if errorlevel 9009 (
+	echo.
+	echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
+	echo.installed, then set the SPHINXBUILD environment variable to point
+	echo.to the full path of the 'sphinx-build' executable. Alternatively you
+	echo.may add the Sphinx directory to PATH.
+	echo.
+	echo.If you don't have Sphinx installed, grab it from
+	echo.https://www.sphinx-doc.org/
+	exit /b 1
+)
+
+%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
+goto end
+
+:help
+%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
+
+:end
+popd
diff --git a/docs/read_the_docs/source/clinguin/api.rst b/docs/read_the_docs/source/clinguin/api.rst
new file mode 100644
index 00000000..4397c8d9
--- /dev/null
+++ b/docs/read_the_docs/source/clinguin/api.rst
@@ -0,0 +1,56 @@
+API Documentation
+#################
+
+.. _api_fields:
+
+Clinguin
+========
+.. automodule:: clinguin
+    :members:
+
+Client
+======
+.. automodule:: clinguin.client
+    :members:
+
+Client Guis
+-----------
+.. automodule:: clinguin.client.presentation.guis
+    :members:
+
+Client Tkinter Gui
+^^^^^^^^^^^^^^^^^^
+
+.. automodule:: clinguin.client.presentation.guis.tkinter_gui.tkinter_widgets
+    :members:
+
+.. automodule:: clinguin.client.presentation.guis.tkinter_gui.tkinter_utils
+    :members:
+
+
+
+Server
+======
+.. automodule:: clinguin.server
+    :members:
+
+Server Default Backends
+-----------------------
+.. automodule:: clinguin.server.application.default_backends
+    :members:
+
+Utils
+=====
+
+.. automodule:: clinguin.utils
+    :members:
+
+Utils attribute types
+---------------------
+
+.. automodule:: clinguin.utils.attribute_types
+    :members:
+
+
+
+
diff --git a/docs/read_the_docs/source/clinguin/customize_guide.rst b/docs/read_the_docs/source/clinguin/customize_guide.rst
new file mode 100644
index 00000000..450412f9
--- /dev/null
+++ b/docs/read_the_docs/source/clinguin/customize_guide.rst
@@ -0,0 +1,477 @@
+Customize Guide
+###############
+
+This guide is for the people, that already have a special use case in mind, where the standard clinguin framework is not enough.
+
+Idea
+====
+
+The idea regarding the extensibility of clinguin is, that one can tailor the program to ones needs. Clinguin was designed with this in mind, therefore several default backends are provided, which can be tailored to ones needs. For example take the ClingoBackend - the basic idea here is to do meta-reasoning about logic programs in terms of cautious-brave. The problem is, that this type of reasoning is simply not enough, e.g. take the example, where one now wants reason about graphs.
+
+Example: Extending ClingoBackend with Clingraph
+======================================================
+
+Now one wants to display graphs inside Clinguin. In general there exists the package Clingraph, where one can reason about graphs. Now the idea is to extend the ClingoBackend with some further functionality to get the ClingraphBackend. As the ClingraphBackend is already included in the `default_solvers` we show you the necessary steps that are required to implement the same functionality by yourself. 
+
+The first step is to create a new folder any directory, **with one noteable exception**: If you downloaded the source of Clinguin **DO NOT** create the file inside any subfolder of `/clinguin` (where `/` is the root of the root of the source) and do not create the file in any parent of `/clinguin` (e.g. if you have the source located in `/home/test/my_prgs/clinguin/`, do not create the file in `/home`, `/home/test` or `/home/test/my_prgs` - but as an example something like `/home/my_backends/` would be perfectly fine). E.g. one could name this folder `test`. 
+
+Then one creates inside this `test` folder another folder, which is now assumed to be named `backends` and then inside this folder one has to create a file. The name of the file can be chosen as you want (we will assume `your_clingraph_backend.py` from here on).
+ 
+The next step is to open the file, to import the `ClingoBackend` and create a class that inherits from this class. One can import `ClingoBackend` by specifying `from clinguin.server.application.default_backends import ClingoBackend` at the beginning of the file (in the default_solvers ClingraphBackend we imported it with `from clinguin.server.application.default_backends.clingo_backend import ClingoBackend`, as the ClingraphBackend is also included in `default_backends` and we wanted to avoid cyclic imports).
+
+The next step is to write our new backend, where we can e.g. start with:
+
+.. code-block::
+
+    class YourClingraphBackend(ClingoBackend):
+        """
+        TODO
+        """
+
+With this we get the whole functionality of ClingoBackend, to test if the class is recognised by Clinguin. For this we first navigate to the path of the file and then type:
+
+.. code-block:: bash
+
+    $ clinguin client-server --custom-classses "./backends" -h
+
+Now we should get the help of the Clinguin application, where there is also the `--backend` option and in the text of this option there should now be the following line (assuming you don't have other Backends in this directory): `{ClingoBackend|ClingraphBackend|TemporalBackend|YourClingraphBackend}`.
+
+If this is shown, then we can make our final test, that we did the above steps correctly (see below).
+
+If this is not shown, then be sure that you are in the correct directory and that you correctly extended your own class - if this does not help, create a GitHub issue with the *EXACT* things you did, your system, etc.
+
+Starting the Sudoku with *YourClingraphBackend*:
+------------------------------------------------
+
+For this we now assume that you copied the whole `/examples` folder into your current directory (the `test` directory from above). With these preconditions fulfilled one needs to specify one's own backend, this can be done by specifying both `--custom-classes` and `--backend`:
+
+
+.. code-block:: bash
+
+    $ clinguin client-server --custom-classes "./backends" --backend YourClingraphBackend --source-files examples/clingo/sudoku/instance.lp examples/clingo/sudoku/encoding.lp --widget-files examples/clingo/sudoku/widgets.lp
+
+Now Sudoku should open and it should work as expected. If not and you tripple checked that you did everything as specified above, create a GitHub issue with the *EXACT* things you did, your system, etc.
+
+Extending the Class with command line arguments:
+------------------------------------------------
+
+A logical next step is to ask yourself what functionalities your extension should have and what kind of files/command line arguments you need for this. Therefore you can define custom command line options, that will get passed to your backend in the `__init__` method.
+
+You can add additional cmd-arguments by overwriting the `registerOptions` method. As we want to keep the `ClingoBackend` arguments and just want to add your own arguments you can do the following:
+
+.. code-block:: python 
+
+    @classmethod
+    def registerOptions(cls, parser):
+        ClingoBackend.registerOptions(parser)
+
+        # YOUR ARGUMENTS
+        # parser is a argparse object (see https://docs.python.org/3/library/argparse.html)
+        # ...
+        # ...
+
+To implement a very basic version of the ClingraphBackend you can copy-paste the following. In this version the only additional command line option is the option to specify the additional clingraph files (one can ignore most of the lines from the `__init__` method for now):
+
+.. code-block:: python
+
+    def __init__(self, args):
+        super().__init__(args)
+
+        self._clingraph_files = args.clingraph_files
+
+        # Just defaults, that can be set in the ''real'' ClingraphBackend
+        self._select_graph = "default"
+        self._dir = "out"
+        self._type = "graph"
+        self._engine = "dot"
+        self._disable_saved_to_file = True
+
+        self._name_format = ""
+        self._select_model = None
+
+        # Some attributes for the automatic replacement
+        self._intermediate_format = 'png'
+        self._encoding = 'utf-8'
+        self._attribute_image_key = 'image'
+        self._attribute_image_value = 'clingraph'
+        self._attribute_image_value_seperator = '__'
+
+        # Important for later
+        self._filled_model = None
+
+    @classmethod
+    def registerOptions(cls, parser):
+        ClingoBackend.registerOptions(parser)
+
+        parser.add_argument('--clingraph-files',
+                        nargs='+',
+                        metavar='')
+
+
+As after every step you can now validate, if you did it right: Go into the directory where you executed `clinguin` previously and type the follwoing:
+
+.. code-block:: bash
+
+    $ clinguin client-server --custom-classes "./backends" --backend YourClingraphBackend -h
+
+Again the help should show and now there should be a section at the bottom `YourClingraphBackend` where there are three arguments listed:
+
+1. `--source-files` - From ClingoBackend
+2. `--widget-files` - From ClingoBackend
+3. `--clingraph-files` - You just added this one, congrats
+
+
+Programming functionality into your class:
+------------------------------------------
+
+In order to program additional functionality, one must understand some basics of how the ClingoBackend works: ClingoBackend provides several policies (which can be extended by custom classes, for looking up what policies are look into the user guide and into the ClingoBackend-API-Documentation), where each policy de facto does the following things:
+
+1. Execute the policy
+2. Update the *model* (see below)
+3. Generate the Json hierarchy (see below)
+
+Step 1. is different for each policy, but steps 2. and 3. are basically the same for all (or most) policies. Step 2. says that it updates the *model*, where the model corresponds to an instance of the `ClinguinModel` (see also the corresponding API documentation) class, which is basically a low-level tool, which directly accesses clingo-models (one can think of it as a Clingo and CLORM (Clingo ORM) wrapper). This wrapper provides some functionality that is useful for various default Clinguin things, like computing the cautious/brave sets, etc.
+
+So step 2. updates the ClinguinModel and depending on the policy re-computes some answer-sets if needed. This is mostly done in the `ClingoBackend` `_updateModel` method (see below). Step 3. takes than this updatd model and generates a Class-Hierarchy, that is Json-convertible, i.e. it uses the classes `ElementDto`, `AttributeDto` and `CallbackDto`, where each instance of the classes are Json convertible and form a hierarchy which corresponds to the graphical user interface. Step 3. is performed in the `get` method, take a look at the API for more information.
+
+For now step 2. is important, more specifically the `_updateModel` method: So back to our idea of extending Clinguin with Clingraph. As in the `_updateModel` method one computes the model which is then converted and sent back to the client, it makes sense to **overwrite/extend this method to provide further functionality**. In the normal ClingoBackend we call a ClinguinModel method which is called `fromWidgetsFile`, which is inturn just a wrapper for two other methods: `getCautiousBrave` and `fromWidgetsFileAndProgram`. As we need the return value of `getCautiousBrave` we cannot just call the wrapper, therefore as a first step, we overwrite the `_updateModel` with the following:
+
+.. code-block:: python
+
+    def _updateModel(self):
+        try:
+            prg = ClinguinModel.getCautiousBrave(self._ctl,self._assumptions)
+            self._model = ClinguinModel.fromWidgetsFileAndProgram(self._ctl,self._widget_files,prg)
+        except NoModelError:
+            # Notifies the user by a popup, that this is not possible.
+            self._model.addMessage("Error","This operation can't be performed")
+
+
+This would work the same as the default implementation, therefore now we can actually extend it: We are not going into the details of the individual methods here, so we just describe them a bit and you can copy paste them (don't forget to use the `updateModel` from below).
+
+The method `computeClingraphGraphs` is called by `updateModel` and it takes use of the Clingraph API. It computes the graphs and saves them into an intermediate format:
+
+.. code-block:: python
+
+    def _computeClingraphGraphs(self,prg):
+        fbs = []
+        ctl = Control("0")
+        for f in self._clingraph_files:
+            ctl.load(f)
+        ctl.add("base",[],prg)
+        ctl.ground([("base",[])],ClingraphContext())
+
+        ctl.solve(on_model=lambda m: fbs.append(Factbase.from_model(m)))
+        if self._select_model is not None:
+            for m in self._select_model:
+                if m>=len(fbs):
+                    raise ValueError(f"Invalid model number selected {m}")
+            fbs = [f if i in self._select_model else None
+                        for i, f in enumerate(fbs) ]
+
+
+
+        graphs = compute_graphs(fbs, graphviz_type=self._type)
+
+        return graphs
+
+There is the possibility to save a graph to a file (only makes sense if you are in control of the Clinguin-Server), which is handled by the `saveClingraphGraphsToFile` method:
+
+.. code-block:: python
+ 
+    def _saveClingraphGraphsToFile(self,graphs):
+        if self._select_graph is not None:
+            graphs = [{g_name:g for g_name, g in graph.items() if g_name in self._select_graph} for graph in graphs]
+        write_arguments = {"directory":self._dir, "name_format":self._name_format}
+        paths = render(graphs,
+                format='png',
+                engine=self._engine,
+                view=False,
+                **write_arguments)
+        self._logger.debug("Clingraph saved images:")
+        self._logger.debug(paths)
+
+The next method creates a binary image from a graph and returns it:
+
+.. code-block:: python
+
+    def _createImageFromGraph(self, graphs, position = None, key = None):
+        graphs = graphs[0]
+
+        if position is not None:
+            if (len(graphs)-1) >= position:
+                graph = graphs[list(graphs.keys())[position]]
+            else:
+                self._logger.error("Attempted to access not valid position")
+                raise Exception("Attempted to access not valid position")
+        elif key is not None:
+            if key in graphs:
+                graph = graphs[key]
+            else:
+                self._logger.error("Key not found in graphs: %s", str(key))
+                raise Exception("Key not found in graphs: " + str(key))
+        else:
+            self._logger.error("Must either specify position or key!")
+            raise Exception("Must either specify position or key!")
+
+        graph.format = self._intermediate_format
+        img = graph.pipe(engine=self._engine)
+
+        return img
+
+The next method might also interest you for other backends: It converts an image into a Base64 string encoding (which is basically just a String Encoded image, which can be send to the client, which you can use for other Graphics/Images). Note: One needs both `base64.b64encode` and `encoded.decode(self._encoding)` (where `self._encoding = utf-8`). 
+
+.. code-block:: python
+
+    def _convertImageToBase64String(self, img):
+
+        encoded = base64.b64encode(img)
+        decoded = encoded.decode(self._encoding)    
+
+        return decoded
+
+The next method searches through all attributes and looks up all the places, where the value starts with `clingraph__` and then takes everything that is after the `__` as a key for the graph. E.g. the default graph in clingraph is called `default`, so to display the default image one can specify it as `clingraph__default`. This value will then be replaced with the actual image. For the replacement the method first converts the graph into an image, then into a Base64 encoding and then replaces the value of the attribute.
+
+.. code-block:: python
+
+    def _getModelFilledWithBase64ImagesFromGraphs(self,graphs):
+        model = self._model
+
+        kept_symbols = list(model.getElements()) + list(model.getCallbacks())
+
+        filled_attributes = []
+
+        # TODO - Improve efficiency of filling attributes
+        for attribute in model.getAttributes():
+            if str(attribute.key) == self._attribute_image_key:
+                attribute_value = StandardTextProcessing.parseStringWithQuotes(str(attribute.value))
+
+                if attribute_value.startswith(self._attribute_image_value) and attribute_value != "clingraph":
+                    splits = attribute_value.split(self._attribute_image_value_seperator)
+                    splits.pop(0)
+                    rest = ""
+                    for split in splits:
+                        rest = rest + split
+
+                    key_image = self._createImageFromGraph(graphs, key = rest)
+
+                    base64_key_image = self._convertImageToBase64String(key_image)
+
+                    filled_attributes.append(AttributeDao(Raw(Function(str(attribute.id),[])), Raw(Function(str(attribute.key),[])), Raw(String(str(base64_key_image)))))
+                else:
+                    filled_attributes.append(attribute)
+            else:
+                filled_attributes.append(attribute)
+
+        return ClinguinModel(clorm.FactBase(copy.deepcopy(kept_symbols + filled_attributes)))
+
+The next-to-last thing to do is to edit our `updateModel` method, as we need to call the methods above to provide the functionality. We need to add a `_filed_model` to distinguish between the models that are filled with the base64 string and those who are not (if we don't do this, we run into a mess with policies):
+
+.. code-block:: python
+
+    def _updateModel(self):
+        try:
+            prg = ClinguinModel.getCautiousBrave(self._ctl,self._assumptions)
+            self._model = ClinguinModel.fromWidgetsFileAndProgram(self._ctl,self._widget_files,prg)
+
+            graphs = self._computeClingraphGraphs(prg)
+
+            if not self._disable_saved_to_file:
+                self._saveClingraphGraphsToFile(graphs)
+
+            self._filled_model = self._getModelFilledWithBase64ImagesFromGraphs(graphs)
+
+        except NoModelError:
+            self._model.addMessage("Error","This operation can't be performed")
+
+The last step is now to tell backend, that we actually want to send the `filled_model` back and not the `model`. This can be done by editing the `get` method:
+
+.. code-block:: python
+
+    def get(self):
+        if not self._filled_model:
+            self._updateModel()
+
+        json_structure = StandardJsonEncoder.encode(self._filled_model)
+        return json_structure
+
+
+The full example is shown at the end of the file, with this you can execute the coloring example by typing:
+
+.. code-block:: bash
+    
+    $ clinguin client-server --custom-classes "./backends/" --backend YourClingraphBackend --source-files examples/clingraph/coloring/encoding.lp --widget-files examples/clingraph/coloring/ui.lp --clingraph-files examples/clingraph/coloring/viz.lp
+
+Full Example:
+-------------
+
+.. code-block:: python
+
+    from clinguin.server.data.attribute import AttributeDao
+
+    from clinguin.server.data.clinguin_model import ClinguinModel
+    from clinguin.server import StandardJsonEncoder
+
+    from clinguin.server.application.default_backends import ClingoBackend
+
+    from clinguin.utils import NoModelError
+
+    class YourClingraphBackend(ClingoBackend):
+        """
+        TODO
+        """
+
+        def __init__(self, args):
+            super().__init__(args)
+
+            self._clingraph_files = args.clingraph_files
+
+            # Just defaults, that can be set in the ''real'' ClingraphBackend
+            self._select_graph = "default"
+            self._dir = "out"
+            self._type = "graph"
+            self._engine = "dot"
+            self._disable_saved_to_file = True
+
+            self._name_format = ""
+            self._select_model = None
+
+            # Some attributes for the automatic replacement
+            self._intermediate_format = 'png'
+            self._encoding = 'utf-8'
+            self._attribute_image_key = 'image'
+            self._attribute_image_value = 'clingraph'
+            self._attribute_image_value_seperator = '__'
+
+
+            # Important for later
+            self._filled_model = None
+
+        @classmethod
+        def registerOptions(cls, parser):
+            ClingoBackend.registerOptions(parser)
+
+            parser.add_argument('--clingraph-files',
+                            nargs='+',
+                            metavar='')
+
+        def get(self):
+            if not self._filled_model:
+                self._updateModel()
+
+            json_structure = StandardJsonEncoder.encode(self._filled_model)
+            return json_structure
+
+        def _updateModel(self):
+            try:
+                prg = ClinguinModel.getCautiousBrave(self._ctl,self._assumptions)
+                self._model = ClinguinModel.fromWidgetsFileAndProgram(self._ctl,self._widget_files,prg)
+
+                graphs = self._computeClingraphGraphs(prg)
+
+                if not self._disable_saved_to_file:
+                    self._saveClingraphGraphsToFile(graphs)
+
+                self._filled_model = self._getModelFilledWithBase64ImagesFromGraphs(graphs)
+
+            except NoModelError:
+                self._model.addMessage("Error","This operation can't be performed")
+
+
+
+        def _computeClingraphGraphs(self,prg):
+            fbs = []
+            ctl = Control("0")
+            for f in self._clingraph_files:
+                ctl.load(f)
+            ctl.add("base",[],prg)
+            ctl.ground([("base",[])],ClingraphContext())
+
+            ctl.solve(on_model=lambda m: fbs.append(Factbase.from_model(m)))
+            if self._select_model is not None:
+                for m in self._select_model:
+                    if m>=len(fbs):
+                        raise ValueError(f"Invalid model number selected {m}")
+                fbs = [f if i in self._select_model else None
+                            for i, f in enumerate(fbs) ]
+
+
+
+            graphs = compute_graphs(fbs, graphviz_type=self._type)
+
+            return graphs
+
+        def _saveClingraphGraphsToFile(self,graphs):
+            if self._select_graph is not None:
+                graphs = [{g_name:g for g_name, g in graph.items() if g_name in self._select_graph} for graph in graphs]
+            write_arguments = {"directory":self._dir, "name_format":self._name_format}
+            paths = render(graphs,
+                    format='png',
+                    engine=self._engine,
+                    view=False,
+                    **write_arguments)
+            self._logger.debug("Clingraph saved images:")
+            self._logger.debug(paths)
+
+        def _createImageFromGraph(self, graphs, position = None, key = None):
+            graphs = graphs[0]
+
+            if position is not None:
+                if (len(graphs)-1) >= position:
+                    graph = graphs[list(graphs.keys())[position]]
+                else:
+                    self._logger.error("Attempted to access not valid position")
+                    raise Exception("Attempted to access not valid position")
+            elif key is not None:
+                if key in graphs:
+                    graph = graphs[key]
+                else:
+                    self._logger.error("Key not found in graphs: %s", str(key))
+                    raise Exception("Key not found in graphs: " + str(key))
+            else:
+                self._logger.error("Must either specify position or key!")
+                raise Exception("Must either specify position or key!")
+
+            graph.format = self._intermediate_format
+            img = graph.pipe(engine=self._engine)
+
+            return img
+
+        def _convertImageToBase64String(self, img):
+
+            encoded = base64.b64encode(img)
+            decoded = encoded.decode(self._encoding)
+
+            return decoded
+        def _getModelFilledWithBase64ImagesFromGraphs(self,graphs):
+            model = self._model
+
+            kept_symbols = list(model.getElements()) + list(model.getCallbacks())
+
+            filled_attributes = []
+
+            # TODO - Improve efficiency of filling attributes
+            for attribute in model.getAttributes():
+                if str(attribute.key) == self._attribute_image_key:
+                    attribute_value = StandardTextProcessing.parseStringWithQuotes(str(attribute.value))
+
+                    if attribute_value.startswith(self._attribute_image_value) and attribute_value != "clingraph":
+                        splits = attribute_value.split(self._attribute_image_value_seperator)
+                        splits.pop(0)
+                        rest = ""
+                        for split in splits:
+                            rest = rest + split
+
+                        key_image = self._createImageFromGraph(graphs, key = rest)
+
+                        base64_key_image = self._convertImageToBase64String(key_image)
+
+                        filled_attributes.append(AttributeDao(Raw(Function(str(attribute.id),[])), Raw(Function(str(attribute.key),[])), Raw(String(str(base64_key_image)))))
+                    else:
+                        filled_attributes.append(attribute)
+                else:
+                    filled_attributes.append(attribute)
+
+            return ClinguinModel(clorm.FactBase(copy.deepcopy(kept_symbols + filled_attributes)))
+
+
diff --git a/docs/read_the_docs/source/clinguin/installation.rst b/docs/read_the_docs/source/clinguin/installation.rst
new file mode 100644
index 00000000..8b548098
--- /dev/null
+++ b/docs/read_the_docs/source/clinguin/installation.rst
@@ -0,0 +1,36 @@
+Installation
+############
+
+Clinguin Installation guide:
+
+Current installation procedure
+===============================
+
+Currently the recommended way to install clinguin is to execute the following command in the top level clinguin directory:
+
+.. code-block:: bash
+
+    $ python setup.py install
+
+After this, one can run clinguin by executing (-h for help):
+
+.. code-block:: bash
+
+    $ clinguin -h
+
+
+Starting in development mode
+============================
+
+Another possibility to run clinguin is by typing the following (-h for help):
+
+.. code-block:: bash
+
+    $ python start.py -h
+
+
+
+
+
+
+
diff --git a/docs/read_the_docs/source/clinguin/user_guide.rst b/docs/read_the_docs/source/clinguin/user_guide.rst
new file mode 100644
index 00000000..7f449d1e
--- /dev/null
+++ b/docs/read_the_docs/source/clinguin/user_guide.rst
@@ -0,0 +1,169 @@
+User Guide
+##########
+
+This guide is for the people, who want to get to know how clinguin works.
+
+The first example
+=================
+
+Before understanding how clinguin works, we can run a first example: Sudoku. For this one must first install clinguin and can the execute the following command:
+
+.. code-block:: bash
+
+    $ clinguin client-server --source-files examples/clingo/sudoku/instance.lp examples/clingo/sudoku/encoding.lp --widget-files examples/clingo/sudoku/widgets.lp
+
+
+After execution a Sudoku window should open, where one can play a round of Sudoku. The `client-server` specified, that both client and server shall be started at the same time, so it has the look and feel of a single program. If one wants to seperate `client` and `server`, one could start them in two shells:
+
+.. code-block:: bash
+
+    $ clinguin server --source-files examples/clingo/sudoku/instance.lp examples/clingo/sudoku/encoding.lp --widget-files examples/clingo/sudoku/widgets.lp
+
+The source and gui files are only specified for the server, the client does not need to care about this. As one can see, we have specified three files: `instance.lp`, `encoding.lp` and `widgets.lp`. This is a common seperation for clinguin, therefore one can at first expiremnt with the encoding/problem one is working on, and after that create a ui for the problem, to showcase, debug, etc., etc.
+
+.. code-block:: bash
+
+    $ clinguin client 
+
+Principles - The first SeLf-wRiTtEn example
+===========================================
+
+After the startup of your first clinguin example, it is now time to understand the basic techniques how to write your own program. For this you must create two files: An empty file `empty.lp` and a ui-file `ui.lp`.
+
+In general in clinguin we have three different symbols, whith whom one create the whole gui:
+
+* **element**: Is a clingo symbol with three arguments: `element(<ID>,<TYPE>,<PARENT>)` and corresponds to an element in the Gui. The `root` parent is pre-defined and is used as the parent of the window (see below).
+* **attribute**: Is a clingo symbol with three arguments: `attribute(<ID-OF-ELEMENT>,<KEY>,<VALUE>)`, with which one can set various attributes of an element, like background-color, etc. 
+* **callback**: Is a clingo symbol with three arguments: `callback(<ID-OF-ELEMENT>,<ACTION>,<POLICY>)`, with which one can define how an element behaves (how = policy) on certain actions.
+
+Each clinguin `ui.lp` file must contain exactly one element of type `window`. For example, the following code generates a window with the dimensions 400x400 and with the background color pink:
+
+.. code-block::
+
+    element(window, window, root).
+    attribute(window, height, 400).
+    attribute(window, width, 400).
+    attribute(window, background_color, pink).
+
+The next task is to execute this program and show actually the window. This can be done by:
+
+.. code-block:: bash
+
+    $ clinguin client-server --source-files empty.lp --widget-files ui.lp
+
+
+Available Syntax - The second self-written example
+==================================================
+
+As now one can imagine, clinguin features a bunch of pre-defined element types:
+
+* window
+* container
+* button
+* label
+* dropdown_menu
+
+    * dropdown_menu_item
+
+* message
+* menu_bar
+
+    * menu_bar_section
+
+        * menu_bar_section_item
+
+* canvas
+
+For each of these element types there exists a bunch of available attributes. One can look the up by typing:
+
+.. code-block:: bash
+    
+    $ clinguin client-server --gui-syntax
+
+If one is  also interested in what values one might set, one can also look at the full syntax:
+
+.. code-block:: bash
+    
+    $ clinguin client-server --gui-syntax-full
+
+
+Our next example captures a bit more how one structures the gui. For this we take a simple logic program as our source-file (e.g. `source.lp`), which has two models: `p(1)` and `p(2)`:
+
+.. code-block::
+
+    1{p(1);p(2)}1.
+
+
+Now we create a Gui (e.g. `ui.lp`), where we assume either `p(1)` or `p(2)` and provide a functionality to reset it:
+
+.. code-block::
+
+    element(window, window, root).
+    attribute(window, height, 400).
+    attribute(window, width, 400).
+
+    element(dpm, dropdown_menu, window).
+    attribute(dpm, selected, V) :- p(V).
+
+    element(dmp(V), dropdown_menu_item, dpm) :- _b(p(V)).
+    attribute(dmp(V), label, V) :- _b(p(V)).
+    callback(dmp(V), click, add_assumption(p(V))) :- _b(p(V)).
+
+    element(l, label, window).
+    attribute(l, label, "Clear assumptions").
+    attribute(l, font_weight, "italic").
+    attribute(l, font_size, 20).
+    attribute(l, background_color, "#ff4d4d").
+    attribute(l, on_hover, "True").
+    attribute(l, on_hover_background_color, "#990000").
+    callback(l, click, clear_assumptions).
+
+With this done, we can start our application:
+
+.. code-block:: bash
+
+    $ clinguin client-server --source-files source.lp --widget-files ui.lp
+
+
+We have four different elements:
+
+1. window 
+
+    * As in the previous example it just defines the size of the window.
+
+2. dpm (dropdown_menu) 
+
+    * It's parent is the `window` which means, that it is directly shown below the window. 
+    * The attribute `selected` can be used to show the text in the ''selected'' field of the dropdown.
+
+3. dpm(V) (dropdown_menu_item) 
+
+    * A dropdown_menu_item can only be the child of a dropdown_menu (and no other element type)
+    * We want to have one item for each model, therefore we have the `_b(p(V))` in the body. The enclosing `_b` of a symbol means, that we reason bravely (so basically the union of all models), therefore we have here both `p(1)` and `p(2)`.
+    * We add two attributes: One to define the text (attribute key `label`) and what shall happen on a click (then we want to add the assumption, that either `p(1)` or `p(2)` exist).
+
+4. b (label)
+
+    * We use this label to display the text `Clear assumptions` and further create an action, that when one clicks on it, all assumptions are cleared.
+    * All other attributes are only there for the look and feel of the label (on hover, etc.)
+
+Available policies:
+-------------------
+
+Above we have seen two different policies: `add_assumption` and `clear_assumptions`. Therefore one might wonder what kinds of policies are actually available? - It is pointed out here, that this can currently onle be looked up in the API documentation under the section `Server`/`Server Default Backends`/`ClingoBackend` (class `ClingoBackend`).
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/read_the_docs/source/conf.py b/docs/read_the_docs/source/conf.py
new file mode 100644
index 00000000..0e828839
--- /dev/null
+++ b/docs/read_the_docs/source/conf.py
@@ -0,0 +1,82 @@
+# Configuration file for the Sphinx documentation builder.
+#
+# This file only contains a selection of the most common options. For a full
+# list see the documentation:
+# https://www.sphinx-doc.org/en/master/usage/configuration.html
+
+# -- Path setup --------------------------------------------------------------
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#
+import os
+import sys
+sys.path.insert(0, os.path.abspath('.'))
+autodoc_mock_imports = ["clingo","clorm","networkx","graphviz","jsonschema"]
+
+# -- Project information -----------------------------------------------------
+
+project = 'clinguin'
+copyright = '2022, Alexander Beiser,Susana Hahn'
+author = 'Alexander Beiser,Susana Hahn'
+
+# The full version, including alpha/beta/rc tags
+release = '0.0.1'
+
+
+# -- General configuration ---------------------------------------------------
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = [
+    'nbsphinx',
+    'sphinx_rtd_theme',
+    'sphinx.ext.autodoc',
+    'sphinx.ext.napoleon',
+    'sphinx.ext.autosectionlabel',
+    'sphinx.ext.intersphinx'
+]
+
+napoleon_include_init_with_doc = False
+napoleon_use_admonition_for_examples = False
+napoleon_use_admonition_for_references = True
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+# This pattern also affects html_static_path and html_extra_path.
+exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
+
+
+# -- Options for HTML output -------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages.  See the documentation for
+# a list of builtin themes.
+#
+html_theme = 'sphinx_rtd_theme'
+
+html_theme_options = { 
+    'canonical_url': '', 
+#    'analytics_id': 'UA-XXXXXXX-1',  #  Provided by Google in your dashboard
+    'logo_only': False,
+    'display_version': True,
+    'display_version': True,
+    'prev_next_buttons_location': 'bottom',
+    'style_external_links': False,
+    # Toc options
+    'collapse_navigation': True,
+    'sticky_navigation': False,
+    'navigation_depth': 4,
+    'includehidden': True,
+    'titles_only': False
+}
+
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+#html_static_path = ['_static']
diff --git a/docs/read_the_docs/source/index.rst b/docs/read_the_docs/source/index.rst
new file mode 100644
index 00000000..1c8dd521
--- /dev/null
+++ b/docs/read_the_docs/source/index.rst
@@ -0,0 +1,19 @@
+.. clinguin documentation master file, created by
+   sphinx-quickstart on Wed Aug 31 12:21:45 2022.
+   You can adapt this file completely to your liking, but it should at least
+   contain the root `toctree` directive.
+
+Welcome to clinguin's documentation!
+====================================
+
+.. toctree::
+   :maxdepth: 2
+   :caption: Contents:
+
+   clinguin/installation
+   clinguin/user_guide
+   clinguin/customize_guide
+   clinguin/api
+
+
+
diff --git a/examples/clingo/housing/README.md b/examples/clingo/housing/README.md
new file mode 100644
index 00000000..faf9e05b
--- /dev/null
+++ b/examples/clingo/housing/README.md
@@ -0,0 +1,1 @@
+start with: `clinguin client-server --source-files examples/clingo/housing/instance.lp examples/clingo/housing/encoding.lp --widget-files examples/clingo/housing/widgets.lp`
diff --git a/examples/clingo/housing/encoding.lp b/examples/clingo/housing/encoding.lp
new file mode 100644
index 00000000..2e445977
--- /dev/null
+++ b/examples/clingo/housing/encoding.lp
@@ -0,0 +1,9 @@
+
+{in_house(P)}:-person(P).
+% :- #count{P : person(P), in_house(P)} > #count{P : person(P), in_house(P)}.
+
+{assign(bed(N,R),P)}:-in_house(P),bed(N,R).
+
+:- assign(B,P1),assign(B,P2),P1!=P2.
+:- assign(B1,P),assign(B2,P),B1!=B2.
+:- in_house(P), not assign(_,P).
diff --git a/examples/clingo/housing/instance.lp b/examples/clingo/housing/instance.lp
new file mode 100644
index 00000000..55ce9ec7
--- /dev/null
+++ b/examples/clingo/housing/instance.lp
@@ -0,0 +1,17 @@
+room(1,"Bedroom 1").
+room(2,"Livingroom").
+room(3,"Bedroom 2").
+bed(1,1).
+bed(2,1).
+bed(1,2).
+bed(1,3).
+bed(2,3).
+bed(3,3).
+person(max).
+person(phil).
+person(anna).
+person(sus).
+person(tobias).
+person(sven).
+person(torsten).
+
diff --git a/examples/clingo/housing/widgets.lp b/examples/clingo/housing/widgets.lp
new file mode 100644
index 00000000..e3f21e7f
--- /dev/null
+++ b/examples/clingo/housing/widgets.lp
@@ -0,0 +1,115 @@
+#const height_value= 800.
+#const height_names= 250.
+#const width_value= 400.
+#const color_considered = "#C1E5AE".
+#const color_considered_on_hover = "#6cc13e".
+#const color_not_considered = "#E5C2AE".
+#const color_not_considered_on_hover = "#c16e3e".
+
+% Window
+element(window, window, root).
+attribute(window, height, height_value).
+attribute(window, width, width_value).
+attribute(window, background_color, white).
+attribute(window, resizable_x, 1).
+attribute(window, resizable_y, 1).
+attribute(window, child_layout, absstatic).
+
+% Menu bar
+element(m, menu_bar, window).
+element(ms, menu_bar_section, m).
+attribute(ms, label, "Options").
+element(ms_clear, menu_bar_section_item, ms).
+attribute(ms_clear, label, "Clear").
+callback(ms_clear, click, clear_assumptions).
+element(ms_next, menu_bar_section_item, ms).
+attribute(ms_next, label, "Next").
+callback(ms_next, click, nextSolution).
+
+% Top container
+element(upper_container, container, window).
+attribute(upper_container, height, height_names).
+attribute(upper_container, width, width_value).
+attribute(upper_container, child_layout, grid).
+
+% Top container titles
+in_house_column_label(add_person_container,"People not considered";
+                remove_person_container,"People considered").
+in_house_column(C):-in_house_column_label(C,_).
+
+element((C,title), label, upper_container):-in_house_column(C).
+attribute((C,title), grid_row, 0):-in_house_column(C).
+attribute((C,title), height, 20):-in_house_column(C).
+attribute((C,title), width, width_value/2):-in_house_column(C).
+
+attribute((C,title), label, L):-in_house_column_label(C,L).
+attribute((C,title), font_size, 18):-in_house_column(C).
+
+attribute((remove_person_container,title), grid_column, 1).
+attribute((add_person_container,title), grid_column, 0).
+attribute((remove_person_container,title), background_color, color_considered ).
+attribute((add_person_container,title), background_color, color_not_considered ).
+
+% Add and remove comulmns
+element(C, container, upper_container):- in_house_column(C) .
+attribute(C, grid_row, 1):-in_house_column(C).
+attribute(C, height, height_names-20):-in_house_column(C).
+attribute(C, width, width_value/2):-in_house_column(C).
+attribute(C, child_layout, flex):-in_house_column(C).
+attribute(remove_person_container, grid_column, 1).
+attribute(add_person_container, grid_column, 0).
+
+% People to add to the house
+can_add(P):-person(P), not in_house(P).
+
+element(person_add(P), label, add_person_container):- can_add(P).
+attribute(person_add(P), label, P) :- can_add(P).
+attribute(person_add(P), background_color, color_not_considered) :- can_add(P).
+callback(person_add(P), click,add_assumption(in_house(P))):- can_add(P).
+attribute(person_add(P), on_hover, true) :- can_add(P).
+attribute(person_add(P), on_hover_background_color, color_not_considered_on_hover) :- can_add(P).
+
+% People to remove from the house
+can_remove(P):- in_house(P).
+element(person_remove(P), label, remove_person_container):- can_remove(P).
+attribute(person_remove(P), label, P) :- can_remove(P).
+attribute(person_remove(P), background_color, color_considered) :- can_remove(P).
+callback(person_remove(P), click, remove_assumption(in_house(P))):-can_remove(P).
+attribute(person_remove(P), on_hover, true) :- can_remove(P).
+attribute(person_remove(P), on_hover_background_color, color_considered_on_hover) :- can_remove(P).
+
+% Rooms container
+element(rooms_main_container, container, window).
+attribute(rooms_main_container, height, height_value - height_names).
+attribute(rooms_main_container, width, width_value).
+attribute(rooms_main_container, pos_x, 0).
+attribute(rooms_main_container, pos_y, height_names).
+attribute(rooms_main_container, child_layout, grid).
+
+% Room container
+element(room(I), container, rooms_main_container) :- room(I,_).
+attribute(room(I), height, 200) :- room(I,_).
+attribute(room(I), width, 200) :- room(I,_).
+attribute(room(I), grid_column, (I-1)\2) :- room(I,_).
+attribute(room(I), grid_row, (I-1)/2) :- room(I,_).
+attribute(room(I), child_layout, absstatic) :- room(I,_).
+
+% Room title
+element(room_title(I), label, room(I)) :- room(I,_).
+attribute(room_title(I), height, 20) :- room(I,_).
+attribute(room_title(I), width, 190) :- room(I,_).
+attribute(room_title(I), label, T) :- room(I,T).
+
+% Room beds dropdowns
+element(room_dropdown(B,I), dropdown_menu, room(I)) :- bed(B,I).
+attribute(room_dropdown(B,I), selected, P) :- assign(bed(B,I),P).
+attribute(room_dropdown(B,I), height, 50) :- bed(B,I).
+attribute(room_dropdown(B,I), width, 100) :- bed(B,I).
+attribute(room_dropdown(B,I), pos_y, B*40):- bed(B,I).
+
+element(mi(B,I,P), dropdown_menu_item, room_dropdown(B,I)) :- _b(assign(bed(B,I),P)).
+attribute(mi(B,I,P), label, P) :- _b(assign(bed(B,I),P)).
+callback(mi(B,I,P), click, add_assumption(assign(bed(B,I),P))) :- _b(assign(bed(B,I),P)).
+%mi(B,I,P) :- _b(bed(B,I)), _b(person(P)).
+
+
diff --git a/examples/clingo/sudoku/README.md b/examples/clingo/sudoku/README.md
new file mode 100644
index 00000000..bcc7db73
--- /dev/null
+++ b/examples/clingo/sudoku/README.md
@@ -0,0 +1,1 @@
+Start with: `clinguin client-server --source-files examples/clingo/sudoku/instance.lp examples/clingo/sudoku/encoding.lp --widget-files examples/clingo/sudoku/widgets.lp`
diff --git a/examples/clingo/sudoku/brave_cautious_show.lp b/examples/clingo/sudoku/brave_cautious_show.lp
new file mode 100644
index 00000000..2ebe75a3
--- /dev/null
+++ b/examples/clingo/sudoku/brave_cautious_show.lp
@@ -0,0 +1,66 @@
+#external show_brave.
+#external show_cautious.
+#external show_untagged.
+#external show_all.
+
+#show element(ID,TYPE,PARENT): _brave(element(ID,TYPE,PARENT)), show_brave.
+#show attribute(ID,NAME,VALUE): _brave(attribute(ID,NAME,VALUE)), show_brave.
+#show callback(ID,ACTION,FUNCT): _brave(callback(ID,ACTION,FUNCT)), show_brave.
+
+#show element(ID,TYPE,PARENT): _cautious(element(ID,TYPE,PARENT)), show_cautious.
+#show attribute(ID,NAME,VALUE): _cautious(attribute(ID,NAME,VALUE)), show_cautious.
+#show callback(ID,ACTION,FUNCT): _cautious(callback(ID,ACTION,FUNCT)), show_cautious.
+
+#show element(ID,TYPE,PARENT): 
+    element(ID,TYPE,PARENT),
+    not _brave(element(ID,TYPE,PARENT)), 
+    not _cautious(element(ID,TYPE,PARENT)), 
+    show_untagged.
+#show attribute(ID,NAME,VALUE): 
+    attribute(ID,NAME,VALUE),
+    not _brave(attribute(ID,NAME,VALUE)), 
+    not _cautious(attribute(ID,NAME,VALUE)), 
+    show_untagged.
+#show callback(ID,ACTION,FUNCT): 
+    callback(ID,ACTION,FUNCT),
+    not _brave(callback(ID,ACTION,FUNCT)),
+    not _cautious(callback(ID,ACTION,FUNCT)),
+    show_untagged.
+
+#show .
+
+
+#show element(ID,TYPE,PARENT): 
+    element(ID,TYPE,PARENT),
+    show_all.
+#show attribute(ID,NAME,VALUE): 
+    attribute(ID,NAME,VALUE),
+    show_all.
+#show callback(ID,ACTION,FUNCT): 
+    callback(ID,ACTION,FUNCT),
+    show_all.
+
+
+_brave(element(ID, TYPE, PARENT)):-
+    _brave_element_type(TYPE),
+    element(ID, TYPE, PARENT).
+_brave(callback(ID,ACTION,FUNCT)):-
+    element(ID, TYPE, PARENT),
+    _brave_element_type(TYPE),
+    callback(ID,ACTION,FUNCT).
+_brave(attribute(ID,NAME,VAL)):-
+    element(ID, TYPE, PARENT),
+    _brave_element_type(TYPE),
+    attribute(ID,NAME,VAL).
+
+_cautious(element(ID, TYPE, PARENT)):-
+    _cautious_element_type(TYPE),
+    element(ID, TYPE, PARENT).
+_cautious(callback(ID,ACTION,FUNCT)):-
+    element(ID, TYPE, PARENT),
+    _cautious_element_type(TYPE),
+    callback(ID,ACTION,FUNCT).
+_cautious(attribute(ID,NAME,VAL)):-
+    element(ID, TYPE, PARENT),
+    _cautious_element_type(TYPE),
+    attribute(ID,NAME,VAL).
\ No newline at end of file
diff --git a/examples/sudoku/encoding.lp b/examples/clingo/sudoku/encoding.lp
similarity index 100%
rename from examples/sudoku/encoding.lp
rename to examples/clingo/sudoku/encoding.lp
diff --git a/examples/sudoku/instance.lp b/examples/clingo/sudoku/instance.lp
similarity index 100%
rename from examples/sudoku/instance.lp
rename to examples/clingo/sudoku/instance.lp
diff --git a/examples/clingo/sudoku/widgets.lp b/examples/clingo/sudoku/widgets.lp
new file mode 100644
index 00000000..5d55ff82
--- /dev/null
+++ b/examples/clingo/sudoku/widgets.lp
@@ -0,0 +1,127 @@
+
+element(window, window, root).
+#const height_value= 550.
+#const width_value= 550.
+#const grid_height_value = 450.
+#const grid_width_value = 450.
+#const dim = 3.
+
+%---------------------------------------------------------------------------------------
+% Window
+%---------------------------------------------------------------------------------------
+
+attribute(window, height, height_value).
+attribute(window, width, width_value).
+attribute(window, background_color, white).
+attribute(window, resizable_x, 0).
+attribute(window, resizable_y, 0).
+attribute(window, child_layout, grid).
+
+%---------------------------------------------------------------------------------------
+% Sudoku-Grid
+%---------------------------------------------------------------------------------------
+
+element(uc, container, window).
+attribute(uc, grid_column, 0).
+attribute(uc, grid_row, 0).
+attribute(uc, height, grid_height_value).
+attribute(uc, width, grid_width_value).
+attribute(uc, child_layout, grid).
+
+% Grid cells
+cell_color(X,Y,gray):-subgrid(X,Y,S), S\2==0.
+cell_color(X,Y,white):-subgrid(X,Y,S), S\2!=0.
+
+menu(X,Y):-pos(X,Y), not initial(X,Y,_).
+
+element(c(X,Y), label, uc) :- initial(X,Y,V).
+element(c(X,Y), dropdown_menu, uc) :- menu(X,Y).
+
+attribute(c(X,Y), grid_column, X-1) :- pos(X,Y).
+attribute(c(X,Y), grid_row, Y-1) :- pos(X,Y).
+attribute(c(X,Y),background_color,COLOR):- cell_color(X,Y,COLOR).
+attribute(c(X,Y), height, grid_height_value/(dim*dim)) :- pos(X,Y).
+attribute(c(X,Y), width, grid_width_value/(dim*dim)) :- pos(X,Y).
+
+attribute(c(X,Y), background_color, COLOR) :- initial(X,Y,V), cell_color(X,Y,COLOR).
+attribute(c(X,Y), label, V) :- initial(X,Y,V).
+attribute(c(X,Y), font_size, 16) :- initial(X,Y,V).
+
+% Option Menu
+attribute(c(X,Y), background_color, COLOR) :- menu(X,Y), cell_color(X,Y,COLOR).
+attribute(c(X,Y), selected, V) :- menu(X,Y), sudoku(X,Y,V).
+
+% Option menu Item
+element(mi(X,Y,V), dropdown_menu_item, c(X,Y)) :- menu(X,Y), _b(sudoku(X,Y,V)).
+attribute(mi(X,Y,V), label, V) :- menu(X,Y), _b(sudoku(X,Y,V)).
+callback(mi(X,Y,V), click, add_assumption(sudoku(X,Y,V))) :- menu(X,Y), _b(sudoku(X,Y,V)).
+
+%---------------------------------------------------------------------------------------
+% Menu Bar
+%---------------------------------------------------------------------------------------
+
+element(m, menu_bar, window).
+element(ms, menu_bar_section, m).
+attribute(ms, label, "Options").
+element(ms_clear, menu_bar_section_item, ms).
+attribute(ms_clear, label, "Clear").
+callback(ms_clear, click, clear_assumptions).
+element(ms_next, menu_bar_section_item, ms).
+attribute(ms_next, label, "Next").
+callback(ms_next, click, next_solution).
+
+%---------------------------------------------------------------------------------------
+% Footer Buttons
+%---------------------------------------------------------------------------------------
+
+element(buttonsc_c, container, window).
+attribute(buttonsc_c, grid_column, 0).
+attribute(buttonsc_c, grid_row, 1).
+attribute(buttonsc_c, height, height_value - grid_height_value).
+attribute(buttonsc_c, width, width_value).
+attribute(buttonsc_c, background_color, white).
+attribute(buttonsc_c, child_layout, absstatic).
+
+element(buttonsc, container, buttonsc_c).
+attribute(buttonsc, pos_x, 200).
+attribute(buttonsc, pos_y, 5).
+attribute(buttonsc, height, 300).
+attribute(buttonsc, width, 150).
+attribute(buttonsc, background_color, white).
+attribute(buttonsc, child_layout, grid).
+
+element(clear_label, label, buttonsc).
+attribute(clear_label, height,45).
+attribute(clear_label, width,150).
+attribute(clear_label, grid_column, 0).
+attribute(clear_label, grid_row, 0).
+attribute(clear_label, label, "Clear").
+attribute(clear_label, background_color, "#ff4e4e").
+attribute(clear_label, on_hover, true).
+attribute(clear_label, on_hover_background_color, "#a00000").
+attribute(clear_label, on_hover_foreground_color, "#111111"). 
+callback(clear_label, click, clear_assumptions). 
+
+element(next_label, label, buttonsc).
+attribute(next_label, grid_column, 0).
+attribute(next_label, grid_row, 1).
+attribute(next_label, height,45).
+attribute(next_label, width,150).
+attribute(next_label, label, "Next Solution").
+attribute(next_label, background_color, "#4eff4e").
+attribute(next_label, on_hover, true).
+attribute(next_label, on_hover_background_color, "#00a000").
+attribute(next_label, on_hover_foreground_color, "#111111"). 
+attribute(next_label, font_family, "Helvetica").
+attribute(next_label, font_weight, "bold").
+attribute(next_label, font_size, 16).
+callback(next_label, click, nextSolution). 
+
+%---------------------------------------------------------------------------------------
+% Messages
+%---------------------------------------------------------------------------------------
+
+element(message, message, window) :- no_more_solutions.
+attribute(message, title, "Finished") :- no_more_solutions.
+attribute(message, message, "No more solutions available.") :- no_more_solutions.
+
diff --git a/examples/clingo/sudoku/widgets_manual_tag.lp b/examples/clingo/sudoku/widgets_manual_tag.lp
new file mode 100644
index 00000000..6920eeb5
--- /dev/null
+++ b/examples/clingo/sudoku/widgets_manual_tag.lp
@@ -0,0 +1,66 @@
+element(window, window, root).
+
+#const height_value= 550.
+#const width_value= 550.
+
+#const grid_height_value = 450.
+#const grid_width_value = 450.
+
+attribute(window, height, height_value).
+attribute(window, width, width_value).
+attribute(window, background_color, white).
+attribute(window, resizable_x, 0).
+attribute(window, resizable_y, 0).
+attribute(window, child_layout, absstatic).
+
+element(m, menu_bar, window).
+
+element(ms, menu_bar_section, m).
+attribute(ms, label, "Options").
+
+element(msi1, menu_bar_section_item, ms).
+attribute(msi1, label, "Clear").
+callback(msi1, click, clear_assumptions).
+
+element(uc, container, window).
+attribute(uc, child_layout, grid).
+attribute(uc, pos_x, 50).
+attribute(uc, pos_y, 15).
+attribute(uc, height, grid_height_value).
+attribute(uc, width, grid_width_value).
+
+c(X,Y) :- pos(X,Y).
+
+element(c(X,Y), container, uc) :- c(X,Y).
+attribute(c(X,Y), grid_column, X-1) :- c(X,Y).
+attribute(c(X,Y), grid_row, Y-1) :- c(X,Y).
+% attribute(c(X,Y),background_color,blue):- c(X,Y).
+% attribute(c(X,Y),background_color,blue):- subgrid(X,Y,S).
+attribute(c(X,Y),background_color,grey):- subgrid(X,Y,S), S\2==0.
+attribute(c(X,Y),background_color,white):- subgrid(X,Y,S), S\2!=0.
+attribute(c(X,Y), height, grid_height_value/(dim*dim)) :- c(X,Y).
+attribute(c(X,Y), width, grid_width_value/(dim*dim)) :- c(X,Y).
+
+element(m(X,Y), dropdown_menu, c(X,Y)) :- c(X,Y).
+_brave(element(mi(X,Y,V), dropdown_menu_item, m(X,Y))) :- sudoku(X,Y,V).
+
+_brave(callback(mi(X,Y,V), click, add_assumption(sudoku(X,Y,V)))) :- sudoku(X,Y,V).
+_brave(attribute(mi(X,Y,V), label, V)) :- sudoku(X,Y,V).
+
+attribute(m(X,Y), selected, V) :- sudoku(X,Y,V).
+
+element(lc, container, window).
+attribute(lc, height, 70).
+attribute(lc, width, 250).
+attribute(lc, pos_x, 150).
+attribute(lc, pos_y, 475).
+
+element(ll, label, lc).
+attribute(ll, label, "Clear assumptions").
+attribute(ll, background_color, red).
+attribute(ll, on_hover, true).
+attribute(ll, on_hover_background_color, blue).
+attribute(ll, on_hover_foreground_color, white). 
+callback(ll, click, clear_assumptions). 
+
+
diff --git a/examples/clingo/sudoku/widgets_not_tagged.lp b/examples/clingo/sudoku/widgets_not_tagged.lp
new file mode 100644
index 00000000..0a683640
--- /dev/null
+++ b/examples/clingo/sudoku/widgets_not_tagged.lp
@@ -0,0 +1,66 @@
+element(window, window, root).
+
+#const height_value= 550.
+#const width_value= 550.
+
+#const grid_height_value = 450.
+#const grid_width_value = 450.
+
+attribute(window, height, height_value).
+attribute(window, width, width_value).
+attribute(window, background_color, white).
+attribute(window, resizable_x, 0).
+attribute(window, resizable_y, 0).
+attribute(window, child_layout, absstatic).
+
+element(m, menu_bar, window).
+
+element(ms, menu_bar_section, m).
+attribute(ms, label, "Options").
+
+element(msi1, menu_bar_section_item, ms).
+attribute(msi1, label, "Clear").
+callback(msi1, click, clear_assumptions).
+
+element(uc, container, window).
+attribute(uc, child_layout, grid).
+attribute(uc, pos_x, 50).
+attribute(uc, pos_y, 15).
+attribute(uc, height, grid_height_value).
+attribute(uc, width, grid_width_value).
+
+c(X,Y) :- pos(X,Y).
+
+element(c(X,Y), container, uc) :- c(X,Y).
+attribute(c(X,Y), grid_column, X-1) :- c(X,Y).
+attribute(c(X,Y), grid_row, Y-1) :- c(X,Y).
+% attribute(c(X,Y),background_color,blue):- c(X,Y).
+% attribute(c(X,Y),background_color,blue):- subgrid(X,Y,S).
+attribute(c(X,Y),background_color,grey):- subgrid(X,Y,S), S\2==0.
+attribute(c(X,Y),background_color,white):- subgrid(X,Y,S), S\2!=0.
+attribute(c(X,Y), height, grid_height_value/(dim*dim)) :- c(X,Y).
+attribute(c(X,Y), width, grid_width_value/(dim*dim)) :- c(X,Y).
+
+element(m(X,Y), dropdown_menu, c(X,Y)) :- c(X,Y).
+element(mi(X,Y,V), dropdown_menu_item, m(X,Y)) :- sudoku(X,Y,V).
+
+callback(mi(X,Y,V), click, add_assumption(sudoku(X,Y,V))) :- sudoku(X,Y,V).
+
+attribute(m(X,Y), selected, V) :- sudoku(X,Y,V).
+attribute(mi(X,Y,V), label, V) :- sudoku(X,Y,V).
+
+element(lc, container, window).
+attribute(lc, height, 70).
+attribute(lc, width, 250).
+attribute(lc, pos_x, 150).
+attribute(lc, pos_y, 475).
+
+element(ll, label, lc).
+attribute(ll, label, "Clear assumptions").
+attribute(ll, background_color, red).
+attribute(ll, on_hover, true).
+attribute(ll, on_hover_background_color, blue).
+attribute(ll, on_hover_foreground_color, white). 
+callback(ll, click, clear_assumptions). 
+
+
diff --git a/examples/clingraph/coloring/README.md b/examples/clingraph/coloring/README.md
new file mode 100644
index 00000000..f5b52590
--- /dev/null
+++ b/examples/clingraph/coloring/README.md
@@ -0,0 +1,5 @@
+# Graph coloring example
+
+```
+clinguin client-server --source-files examples/clingraph/coloring/encoding.lp --widget-files examples/clingraph/coloring/ui.lp   --backend=ClingraphBackend --clingraph-files=examples/clingraph/coloring/viz.lp
+```
\ No newline at end of file
diff --git a/examples/clingraph/coloring/encoding.lp b/examples/clingraph/coloring/encoding.lp
new file mode 100644
index 00000000..a126da23
--- /dev/null
+++ b/examples/clingraph/coloring/encoding.lp
@@ -0,0 +1,14 @@
+node(1..6).
+
+edge(
+    (1,2); (1,3); (1,4);
+    (2,4); (2,5); (2,6);
+    (3,4); (3,5);
+    (5,6)
+).
+
+color(red; green; blue).
+
+{ assign(N, C) : color(C) } = 1 :- node(N).
+
+:- edge((N, M)), assign(N, C), assign(M, C).
\ No newline at end of file
diff --git a/examples/clingraph/coloring/ui.lp b/examples/clingraph/coloring/ui.lp
new file mode 100644
index 00000000..51d0f1ad
--- /dev/null
+++ b/examples/clingraph/coloring/ui.lp
@@ -0,0 +1,38 @@
+element(window, window, root).
+
+attribute(window, height, 50) :- h(X).
+attribute(window, width, 50) :- w(X).
+attribute(window, child_layout, grid).
+
+element(canv, canvas, window).
+attribute(canv, image, clingraph__default).
+attribute(canv, width, 250).
+attribute(canv, height, 250).
+attribute(canv, resize, true).
+
+element(bf, container, window).
+attribute(bf, background_color, pink).
+attribute(bf, grid_row, 1):-node(N).
+attribute(bf, child_layout, grid).
+
+element(node(N), container, bf):-node(N).
+attribute(node(N), width, 200):-node(N).
+attribute(node(N), height, 30):-node(N).
+attribute(node(N), grid_row, N):-node(N).
+attribute(node(N), child_layout, grid):-node(N).
+
+
+element(l(N), label, node(N)):-node(N).
+attribute(l(N), grid_column, 0):-node(N).
+attribute(l(N), label, N):-node(N).
+
+element(dmc(N), dropdown_menu, node(N)):-node(N).
+attribute(dmc(N), grid_column, 1):-node(N).
+attribute(dmc(N), width, 100):-node(N).
+attribute(dmc(N), height, 30):-node(N).
+attribute(dmc(N), selected, C):-assign(N,C).
+
+element(dmi(N,C), dropdown_menu_item, dmc(N)):-_b(assign(N,C)).
+attribute(dmi(N,C), label, C):-_b(assign(N,C)).
+callback(dmi(N,C), click, add_assumption(assign(N,C))):-_b(assign(N,C)).
+
diff --git a/examples/clingraph/coloring/viz.lp b/examples/clingraph/coloring/viz.lp
new file mode 100644
index 00000000..c35c89a6
--- /dev/null
+++ b/examples/clingraph/coloring/viz.lp
@@ -0,0 +1,3 @@
+attr(node, N, style, filled):- node(N).
+attr(node, N, color, C):- assign(N, C).
+
diff --git a/examples/name_replacer.sh b/examples/name_replacer.sh
new file mode 100755
index 00000000..38f46af5
--- /dev/null
+++ b/examples/name_replacer.sh
@@ -0,0 +1,41 @@
+#!/bin/bash
+# find_and_replace.sh
+
+find . -type f -name "*.lp" -exec sed -i '' -e "s/backgroundcolor/background_color/g" {} +
+find . -type f -name "*.lp" -exec sed -i '' -e "s/foregroundcolor/foreground_color/g" {} +
+
+find . -type f -name "*.lp" -exec sed -i '' -e "s/onhover/on_hover/g" {} +
+find . -type f -name "*.lp" -exec sed -i '' -e "s/hoverfore/hover_fore/g" {} +
+find . -type f -name "*.lp" -exec sed -i '' -e "s/hoverback/hover_back/g" {} +
+find . -type f -name "*.lp" -exec sed -i '' -e "s/hoverborder/hover_border/g" {} +
+
+find . -type f -name "*.lp" -exec sed -i '' -e "s/fontfamily/font_family/g" {} +
+find . -type f -name "*.lp" -exec sed -i '' -e "s/fontsize/font_size/g" {} +
+find . -type f -name "*.lp" -exec sed -i '' -e "s/fontweight/font_weight/g" {} +
+
+find . -type f -name "*.lp" -exec sed -i '' -e "s/resizablex/resizable_x/g" {} +
+find . -type f -name "*.lp" -exec sed -i '' -e "s/resizabley/resizable_y/g" {} +
+
+find . -type f -name "*.lp" -exec sed -i '' -e "s/childorg/child_layout/g" {} +
+find . -type f -name "*.lp" -exec sed -i '' -e "s/gridcolumn/grid_column/g" {} +
+find . -type f -name "*.lp" -exec sed -i '' -e "s/gridrow/grid_row/g" {} +
+find . -type f -name "*.lp" -exec sed -i '' -e "s/rowspan/row_span/g" {} +
+find . -type f -name "*.lp" -exec sed -i '' -e "s/columnspan/column_span/g" {} +
+
+find . -type f -name "*.lp" -exec sed -i '' -e "s/posx/pos_x/g" {} +
+find . -type f -name "*.lp" -exec sed -i '' -e "s/posy/pos_y/g" {} +
+
+find . -type f -name "*.lp" -exec sed -i '' -e "s/borderwidth/border_width/g" {} +
+find . -type f -name "*.lp" -exec sed -i '' -e "s/bordercolor/border_color/g" {} +
+
+
+find . -type f -name "*.lp" -exec sed -i '' -e "s/dropdownmenu/dropdown_menu/g" {} +
+find . -type f -name "*.lp" -exec sed -i '' -e "s/menuitem/menu_item/g" {} +
+find . -type f -name "*.lp" -exec sed -i '' -e "s/menubar/menu_bar/g" {} +
+find . -type f -name "*.lp" -exec sed -i '' -e "s/barsection/bar_section/g" {} +
+find . -type f -name "*.lp" -exec sed -i '' -e "s/sectionitem/section_item/g" {} +
+
+
+
+
+
diff --git a/examples/optimization/tsp/README.md b/examples/optimization/tsp/README.md
new file mode 100644
index 00000000..39331162
--- /dev/null
+++ b/examples/optimization/tsp/README.md
@@ -0,0 +1,1 @@
+Execute with: `clinguin client-server --custom-classes examples/optimization/tsp/ --backend TspBackend --source-files examples/optimization/tsp/encoding.lp examples/optimization/tsp/instance.lp --widget-files examples/optimization/tsp/ui.lp --clingraph-files examples/optimization/tsp/viz.lp`
diff --git a/examples/optimization/tsp/encoding.lp b/examples/optimization/tsp/encoding.lp
new file mode 100644
index 00000000..e57c3eb9
--- /dev/null
+++ b/examples/optimization/tsp/encoding.lp
@@ -0,0 +1,11 @@
+2{selected(V0,V1) : edge((V0,V1)); selected(V2,V0) : edge((V2,V0))}2 :- node(V0).
+
+r(V) :- selected(0,V).
+r(V1) :- selected(V0, V1), r(V0).
+r(V0) :- selected(V0, V1), r(V1).
+
+:- node(V), not r(V).
+
+
+%#minimize{C:cost(C)}.
+
diff --git a/examples/optimization/tsp/instance.lp b/examples/optimization/tsp/instance.lp
new file mode 100644
index 00000000..953df265
--- /dev/null
+++ b/examples/optimization/tsp/instance.lp
@@ -0,0 +1,30 @@
+
+node(0..6).
+
+edge((0,1)).
+edge((0,3)).
+edge((0,4)).
+edge((1,2)).
+edge((2,3)).
+edge((3,4)).
+edge((3,5)).
+edge((3,6)).
+edge((4,5)).
+edge((4,6)).
+edge((5,6)).
+
+weight(0,1,5).
+weight(0,3,4).
+weight(0,4,3).
+weight(1,2,3).
+weight(2,3,2).
+weight(3,4,3).
+weight(3,5,2).
+weight(3,6,3).
+weight(4,5,4).
+weight(4,6,1).
+weight(5,6,2).
+
+
+
+
diff --git a/examples/optimization/tsp/tsp_backend.py b/examples/optimization/tsp/tsp_backend.py
new file mode 100644
index 00000000..c37fff4e
--- /dev/null
+++ b/examples/optimization/tsp/tsp_backend.py
@@ -0,0 +1,144 @@
+from clinguin.server.application.default_backends.clingraph_backend import *
+from clingo import Symbol, Number
+
+class TspBackend(ClingraphBackend):
+
+    # Computes the set difference between the brave and cautious model.
+    def doSetDifference(self, brave_model, cautious_model):
+
+        brave_cautious_difference = []
+
+        for b in brave_model:
+            found = False
+
+            for c in cautious_model:
+                if str(b) == str(c):
+                    found = True
+                    break
+
+            if not found:
+                brave_cautious_difference.append(b)
+
+        return brave_cautious_difference
+
+    # Very inefficient but does it's job
+    def calculateCautiousCost(self, cautious_model):
+        cost = 0
+        for c in cautious_model:
+            if str(c.name) == "selected":
+                v0 = str(c.arguments[0])
+                v1 = str(c.arguments[1])
+                for c2 in cautious_model:
+                    if str(c2.name) == "weight":
+                        v0_w = str(c2.arguments[0])
+                        v1_w = str(c2.arguments[1])
+                        
+                        if v0 == v0_w and v1 == v1_w:
+                            cost = cost + int(str(c2.arguments[2]))
+                            
+
+                        
+                #for c2 in cautious_model:
+            #print(c)
+
+        symb = Function("_cautious_cost", [Number(cost)])
+    
+
+        print(cost)
+        print(symb)
+        return symb        
+        
+
+    def _updateModel(self):
+        super()._updateModel()
+        try:
+
+            ctl = self._ctl
+            assumptions = self._assumptions
+
+            model = ClinguinModel()
+            
+            cautious_model = model.computeCautious(ctl, assumptions)
+            cautious_model.append(self.calculateCautiousCost(cautious_model))
+
+            brave_model = model.computeBrave(ctl, assumptions)
+            brave_cautious_difference = self.doSetDifference(brave_model, cautious_model)
+            # c_prg = self.tag_cautious_prg(cautious_model)
+            c_prg = model.symbolsToPrg(cautious_model)
+            b_prg = model.tagBravePrg(brave_model)
+            bcd_prg = model.tag(brave_cautious_difference, "_bcd")
+            bcd_prg = model.symbolsToPrg(bcd_prg)
+
+            atom_prg = model.tag(self._atoms, "_atom")
+            atom_prg = model.symbolsToPrg(atom_prg)
+
+            assumption_prg = model.tag(self._assumptions, "_assumption")
+            assumption_prg = model.symbolsToPrg(assumption_prg)
+
+            print("assumptions:")
+            print(assumption_prg)
+
+
+            #prg = ClinguinModel.getCautiosBrave(self._ctl,self._assumptions)
+            prg = c_prg + b_prg + bcd_prg + atom_prg + assumption_prg
+
+            self._model = ClinguinModel.fromWidgetsFileAndProgram(self._ctl,self._widget_files,prg)
+
+            graphs = self._computeClingraphGraphs(prg)
+
+            self._saveClingraphGraphsToFile(graphs)
+
+            self._filled_model = self._getModelFilledWithBase64ImagesFromGraphs(graphs)
+
+        except NoModelError:
+            self._model.addMessage("Error","This operation can't be performed")
+
+    def saveBest(self, m):
+        self._best = m.symbols(shown=True, atoms=False)
+
+    def addBestToAtoms(self, cautious, best):
+        for b in best:
+            if str(b.name) == "selected":
+                v0 = b.arguments[0]
+                v1 = b.arguments[1]
+                found = False
+
+                for c in cautious:
+                    if str(c.name) == "selected":
+                        v0_c = c.arguments[0]
+                        v1_c = c.arguments[1]
+                        if str(v0) == str(v0_c) and str(v1) == str(v1_c):
+                            found = True
+                            break
+
+                # If b in best but not in cautious, then add:
+                if not found:
+                    self._assumptions.add(b) 
+
+    def findMinimum(self):
+
+        # Get Cautiuos
+        ctl = self._ctl
+        assumptions = self._assumptions
+        model = ClinguinModel()
+        cautious = model.computeCautious(ctl, assumptions)
+
+        # Get Best Model
+        self._initCtl()
+        self._ctl.add("base",[],"#minimize{C:cost(C)}.")
+        self._ground()
+        self._ctl.solve(on_model=lambda m:self.saveBest(m))
+        best = list(self._best)
+        
+
+        self.addBestToAtoms(cautious, best)
+        print("WORKED!")
+
+        self._initCtl()
+        self._ground()
+ 
+        self._updateModel()
+
+        return self.get()
+
+
diff --git a/examples/optimization/tsp/ui.lp b/examples/optimization/tsp/ui.lp
new file mode 100644
index 00000000..8a9f450b
--- /dev/null
+++ b/examples/optimization/tsp/ui.lp
@@ -0,0 +1,113 @@
+element(window, window, root).
+
+attribute(window, height, 500) :- h(X).
+attribute(window, width, 500) :- w(X).
+attribute(window, child_layout, grid).
+
+% ----------------------------------------------------------------------
+% ------------------- DISPLAY GRAPH ------------------------------------
+element(canv, canvas, window).
+attribute(canv, image, clingraph__default).
+attribute(canv, width, 250).
+attribute(canv, height, 250).
+attribute(canv, resize, true).
+
+% ----------------------------------------------------------------------
+% ------------------- DROPDOWN SECTION ---------------------------------
+element(c_r_u, container, window).
+attribute(c_r_u, grid_column, 1).
+attribute(c_r_u, width, 250).
+attribute(c_r_u, height, 250).
+attribute(c_r_u, background_color, pink).
+attribute(c_r_u, child_layout, grid).
+
+element(dma_c, container, c_r_u).
+attribute(dma_c, child_layout, grid).
+attribute(dma_c, height, 125).
+attribute(dma_c, width, 250).
+
+element(dma_l, label, dma_c).
+attribute(dma_l, label, "Add").
+
+element(dma, dropdown_menu, dma_c).
+attribute(dma, grid_column, 1).
+
+element(dma(V0,V1), dropdown_menu_item, dma) :- _bcd(selected(V0,V1)).
+attribute(dma(V0,V1), label, e(V0,V1)) :- _bcd(selected(V0,V1)).
+callback(dma(V0,V1), click, add_assumption(selected(V0,V1))) :- _bcd(selected(V0,V1)).
+
+element(dmd_c, container, c_r_u).
+attribute(dmd_c, grid_row, 1).
+attribute(dmd_c, height, 125).
+attribute(dmd_c, width, 250).
+attribute(dmd_c, child_layout, grid).
+
+element(dmd_l, label, dmd_c).
+attribute(dmd_l, label, "Remove").
+
+element(dmd, dropdown_menu, dmd_c).
+attribute(dmd, grid_column, 1).
+
+element(dmd(V0,V1), dropdown_menu_item, dmd) :- _assumption(selected(V0,V1)).
+attribute(dmd(V0,V1), label, e(V0,V1)) :- _assumption(selected(V0,V1)).
+callback(dmd(V0,V1), click, remove_assumption(selected(V0,V1))) :- _assumption(selected(V0,V1)).
+
+% ----------------------------------------------------------------------
+% ------------------- LOWER SECTION ------------------------------------
+element(c2, container, window).
+attribute(c2, grid_row, 1).
+attribute(c2, width, 500).
+attribute(c2, height, 250).
+attribute(c2, background_color, black).
+attribute(c2, grid_column_span, 2).
+attribute(c2, child_layout, grid).
+
+% ------------------- CLEAR BUTTON ---------------------------------
+element(clear, button, c2).
+attribute(clear, label, "Clear").
+attribute(clear, height, 125).
+attribute(clear, width, 150).
+callback(clear, click, clear_assumptions).
+
+% ------------------- FIND MIN ---------------------------------
+element(find_min, button, c2).
+attribute(find_min, label, "Find Min.").
+attribute(find_min, height, 125).
+attribute(find_min, width, 150).
+callback(find_min, click, find_minimum).
+attribute(find_min, grid_row, 1).
+
+
+% ------------------- COST 1 LABEL ---------------------------------
+element(cur_cost_l, label, c2).
+attribute(cur_cost_l, label, "Current Cost:").
+attribute(cur_cost_l, height, 120).
+attribute(cur_cost_l, width, 350).
+attribute(cur_cost_l, grid_row, 0).
+attribute(cur_cost_l, grid_column, 1).
+
+
+% ------------------- COST 2 LABEL AND COST CALCULATION ---------------------------------
+cost(CC) :- CC = #sum{C,V0,V1 : selected(V0,V1), weight(V0,V1,C)}.
+attribute(cur_cost_b, label, C) :- cost(C).
+
+% Showcase, that one can also argue on a meta level in the backend:
+%attribute(cur_cost_b, label, C) :- _cautious_cost(C).
+
+element(cur_cost_b, label, c2).
+attribute(cur_cost_b, height, 120).
+attribute(cur_cost_b, width, 350).
+attribute(cur_cost_b, grid_column, 1).
+attribute(cur_cost_b, grid_row, 1).
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/optimization/tsp/viz.lp b/examples/optimization/tsp/viz.lp
new file mode 100644
index 00000000..18e263fe
--- /dev/null
+++ b/examples/optimization/tsp/viz.lp
@@ -0,0 +1,4 @@
+attr(node, N, style, filled) :- node(N).
+attr(edge, (V0, V1), label, C) :- weight(V0, V1, C).
+attr(edge, (V0, V1), color, red) :- selected(V0,V1).
+
diff --git a/examples/sudoku/widgets.lp b/examples/sudoku/widgets.lp
deleted file mode 100644
index b243d660..00000000
--- a/examples/sudoku/widgets.lp
+++ /dev/null
@@ -1,66 +0,0 @@
-element(window, window, root).
-
-#const height_value= 550.
-#const width_value= 550.
-
-#const grid_height_value = 450.
-#const grid_width_value = 450.
-
-attribute(window, height, height_value).
-attribute(window, width, width_value).
-attribute(window, backgroundcolor, white).
-attribute(window, resizablex, 0).
-attribute(window, resizabley, 0).
-attribute(window, childorg, absstatic).
-
-element(m, menubar, window).
-
-element(ms, menubarsection, m).
-attribute(ms, label, "Options").
-
-element(msi1, menubarsectionitem, ms).
-attribute(msi1, label, "Clear").
-callback(msi1, click, clear).
-
-element(uc, container, window).
-attribute(uc, childorg, grid).
-attribute(uc, posx, 50).
-attribute(uc, posy, 15).
-attribute(uc, height, grid_height_value).
-attribute(uc, width, grid_width_value).
-
-c(X,Y) :- pos(X,Y).
-
-element(c(X,Y), container, uc) :- c(X,Y).
-attribute(c(X,Y), gridcolumn, X-1) :- c(X,Y).
-attribute(c(X,Y), gridrow, Y-1) :- c(X,Y).
-% attribute(c(X,Y),backgroundcolor,blue):- c(X,Y).
-% attribute(c(X,Y),backgroundcolor,blue):- subgrid(X,Y,S).
-attribute(c(X,Y),backgroundcolor,grey):- subgrid(X,Y,S), S\2==0.
-attribute(c(X,Y),backgroundcolor,white):- subgrid(X,Y,S), S\2!=0.
-attribute(c(X,Y), height, grid_height_value/(dim*dim)) :- c(X,Y).
-attribute(c(X,Y), width, grid_width_value/(dim*dim)) :- c(X,Y).
-
-element(m(X,Y), dropdownmenu, c(X,Y)) :- c(X,Y).
-element(mi(X,Y,V), dropdownmenuitem, m(X,Y)) :- sudoku(X,Y,V).
-
-callback(mi(X,Y,V), click, assume(sudoku(X,Y,V))) :- sudoku(X,Y,V).
-
-attribute(m(X,Y), selected, V) :- sudoku(X,Y,V).
-attribute(mi(X,Y,V), label, V) :- sudoku(X,Y,V).
-
-element(lc, container, window).
-attribute(lc, height, 70).
-attribute(lc, width, 250).
-attribute(lc, posx, 150).
-attribute(lc, posy, 475).
-
-element(ll, label, lc).
-attribute(ll, label, "Clear assumptions").
-attribute(ll, backgroundcolor, red).
-attribute(ll, onhover, true).
-attribute(ll, onhoverbackgroundcolor, blue).
-attribute(ll, onhoverforegroundcolor, white). 
-callback(ll, click, clear). 
-
-
diff --git a/examples/temporal/elevator/README.md b/examples/temporal/elevator/README.md
new file mode 100644
index 00000000..17d8f8c0
--- /dev/null
+++ b/examples/temporal/elevator/README.md
@@ -0,0 +1,6 @@
+
+# Temporal elevator problem
+
+```
+clinguin client-server --source-files examples/temporal/elevator/encoding.lp --widget-files examples/temporal/elevator/widgets.lp   --backend=TemporalBackend
+```
\ No newline at end of file
diff --git a/examples/temporal/elevator/encoding.lp b/examples/temporal/elevator/encoding.lp
new file mode 100644
index 00000000..89d43fc5
--- /dev/null
+++ b/examples/temporal/elevator/encoding.lp
@@ -0,0 +1,35 @@
+floor(0..10).
+init_on(1).
+n_floors(10).
+
+
+
+#program base.
+holds(on(F),0) :- init_on(F). 
+holds(called(6),0).
+
+#program step(t).
+
+#external query(t).
+#external check(t).
+#external call(F,t):floor(F).
+
+holds(called(F),t):-call(F,t).
+action(up;down;serve;wait).
+1 { occ(A,t): action(A)} 1.
+
+holds(on(F+1),t) :- occ(up,t), holds(on(F),t-1).
+holds(on(F-1),t) :- occ(down,t), holds(on(F),t-1).
+holds(on(F),t) :- occ(wait,t), holds(on(F),t-1).
+holds(on(F),t) :- occ(serve,t), holds(on(F),t-1).
+served(F,t) :-  occ(serve,t), holds(on(F),t-1).
+holds(called(F),t) :- holds(called(F),t-1), not served(F,t).
+
+:- occ(up,t), holds(on(F),t-1), not floor(F+1).
+:- occ(down,t), holds(on(F),t-1), not floor(F-1).
+:- occ(serve,t), holds(on(F),t-1), not holds(called(F),t-1).
+
+goal(t):- #count{F:holds(called(F),t)}==0, query(t).
+:-check(t), not goal(t).
+
+
diff --git a/examples/temporal/elevator/widgets.lp b/examples/temporal/elevator/widgets.lp
new file mode 100644
index 00000000..b56591e0
--- /dev/null
+++ b/examples/temporal/elevator/widgets.lp
@@ -0,0 +1,86 @@
+#const height_value= 800.
+#const width_value= 300.
+#const color_elevator = "#C1E5AE".
+#const color_request = "#E5C2AE".
+
+element(window, window, root).
+attribute(window, height, height_value).
+attribute(window, width, width_value).
+attribute(window, child_layout, absstatic).
+
+% Info section
+element(info, container, window).
+attribute(info, pos_x, 140 ).
+attribute(info, pos_y, 0 ).
+attribute(info, child_layout, grid).
+
+element(info_find_goal, label, info).
+attribute(info_find_goal, grid_row, 0).
+attribute(info_find_goal, font_size, 20).
+attribute(info_find_goal, label, "✓"):- goal(T),query(T).
+attribute(info_find_goal, label, "✕"):- not goal(T),query(T).
+attribute(info_find_goal, foreground_color,green).
+
+element(info_find_l, button, info):-not goal(T),query(T).
+attribute(info_find_l, height, 70 ):-not goal(T),query(T).
+attribute(info_find_l, width, 120 ):-not goal(T),query(T).
+attribute(info_find_l, grid_row, 1):-not goal(T),query(T).
+attribute(info_find_l, label, "Find plan"):-not goal(T),query(T).
+callback(info_find_l, click, findPlan):-not goal(T),query(T).
+
+element(info_steps_l, label, info).
+attribute(info_steps_l, grid_row, 4).
+attribute(info_steps_l, label, "History:").
+attribute(info_steps_l, font_size, 18).
+
+element(info_step_c(T),label,info):-occ(A,T).
+attribute(info_step_c(T),grid_row,T+4):-occ(A,T).
+attribute(info_step_c(T),height,30):-occ(A,T).
+attribute(info_step_c(T),width,200):-occ(A,T).
+attribute(info_step_c(T),label,A):-occ(A,T).
+
+
+% Elevator section
+element(elevator, container, window).
+attribute(elevator, child_layout, grid).
+
+element(elevator_row(F), container, elevator):-floor(F).
+attribute(elevator_row(F), grid_column, 0):-floor(F).
+attribute(elevator_row(F), grid_row, N-(F-1)):-floor(F),n_floors(N).
+attribute(elevator_row(F), child_layout, grid):-floor(F).
+
+on_floor(F,T):-floor(F), holds(on(F),T-1), query(T).
+call_floor(F,T):-floor(F), holds(called(F),T-1), query(T).
+
+element(elevator_floor(F), dropdown_menu, elevator_row(F)):-floor(F).
+attribute(elevator_floor(F), height, 70):-floor(F).
+attribute(elevator_floor(F), width, 70):-floor(F).
+attribute(elevator_floor(F), grid_column, 0):-floor(F).
+attribute(elevator_floor(F), grid_row, 0):-floor(F).
+
+attribute(elevator_floor(F), background_color, color_elevator):- on_floor(F,T).
+
+element(elevator_occ_mi(F,A), dropdown_menu_item, elevator_floor(F)):-
+    on_floor(F,T),
+    _b(occ(A,T)).
+attribute(elevator_occ_mi(F,A), label, A):-
+    on_floor(F,T),
+    _b(occ(A,T)).
+callback(elevator_occ_mi(F,A), click, assumeAndStep(occ(A,T))):-
+    on_floor(F,T),
+    _b(occ(A,T)).
+
+
+element(elevator_call(F), button, elevator_row(F)):-floor(F).
+attribute(elevator_call(F), height, 70):-floor(F).
+attribute(elevator_call(F), width, 70):-floor(F).
+attribute(elevator_call(F), grid_column, 1):-floor(F).
+attribute(elevator_call(F), grid_row, 0):-floor(F).
+
+attribute(elevator_call(F), background_color, color_request):- floor(F), call_floor(F,T).
+
+attribute(elevator_call(F), label, "--"):-floor(F),not call_floor(F,_).
+
+% TODO - Wasn't able to get it working with externals
+callback(elevator_call(F), click, add_atom(holds(called(F),T-1))):-query(T),floor(F),not call_floor(F,_).
+
diff --git a/examples/temporal/my_classes.py b/examples/temporal/my_classes.py
deleted file mode 100644
index 92c2ea2f..00000000
--- a/examples/temporal/my_classes.py
+++ /dev/null
@@ -1,8 +0,0 @@
-from clinguin.server.application.clinguin_backend import ClinguinBackend
-
-class TemporalBackend(ClinguinBackend):
-    
-    
-    @classmethod
-    def _registerOptions(cls, parser):
-        parser.add_argument('temporal_horizon', type=int)
\ No newline at end of file
diff --git a/old_prototype/README.md b/old_prototype/README.md
deleted file mode 100644
index 69f96142..00000000
--- a/old_prototype/README.md
+++ /dev/null
@@ -1,89 +0,0 @@
-# Clinguin :penguin:
-
-## Goal
-
-A framework to design interactive UIs using clingo. 
-
-- UIs are defined by facts
-- UIs are rendered using some backend
-  - We are using [tkinter](https://docs.python.org/3/library/tkinter.html) at the moment.
-  - We might want to provide different backends, such as ipwidgets
-
-## Requirements
-
-- clingo 
-- clorm
-- networkx
-- tkinter
-
-## Usage
-
-Example with sudoku:
-
-The following command will open a window defined via [`examples/sudoku/widgets.lp`](examples/sudoku/widgets.lp)
-
-```
-python clinguin.py examples/sudoku/encoding.lp examples/sudoku/widgets.lp examples/sudoku/instance.lp
-```
-
-## Basic prototype
-
-This is a very simple prototype so the code is not optimized or modularized. 
-
-### The layout and widgets
-
-The UI layout is defined based on the cautions model with the following predicates:
-
-#### Window configuration
-
-```
-window(FUNCTION,ARG,VALUE).
-```
-
-calls the function `FUNCTION` using argument `ARG` and value `VALUE`
-
-```python
-w = Tk()
-w.FUNCTION(ARG=VALUE)
-```
-
-if `ARG` is a number is the position of the argument in the call, otherwise is a keyword argument
-
-
-#### Widget creation
-
-
-```
-widget(TYPE,ID,PARENT).
-```
-
-crates a widget of type `TYPE` (`menu`,`frame`) with an identifier `ID` and a parent `PARENT` which can be an id of another widget or `window`.
-
-#### Widget location
-
-```
-geo(ID,TYPE,ARG,VALUE)
-```
-
-Uses the geometry manager `TYPE` (`grid`,`place`,`pack`) on  the widget `ID` passing the argument and value.
-
-#### Widget configuration
-
-```
-config(ID,ARG,VALUE)
-```
-
-Configures the widget `ID` by passing the argument and value.
-
-### The widgets options
-
-The UI options are defined based on the appearance of the following predicate in the brave model
-
-```
-opt(ID,VAL,SYMBOL)
-```
-
-Adds an option with value `VAL` to the widget `ID` that asserts the symbol `SYMBOL` when it is selected.
-
-
-
diff --git a/old_prototype/brave_cautious.py b/old_prototype/brave_cautious.py
deleted file mode 100644
index d8d6f82c..00000000
--- a/old_prototype/brave_cautious.py
+++ /dev/null
@@ -1,45 +0,0 @@
-import sys
-from clingo import parse_term, Control
-
-ctl = Control()
-
-for f in sys.argv[1:]:
-    ctl.load(str(f))
-
-dynamic_shows = '''
-#show.
-#external only_brave.
-#show _brave(X):_brave(X), only_brave.
-#external only_cautious.
-#show _cautious(X):_cautious(X), only_cautious.
-'''
-
-ctl.add("base","",dynamic_shows)
-ctl.ground([("base",[])])
-assumptions= ["assign(1,red)"] #Selected by the user
-
-# Collect brave
-ctl.assign_external(parse_term('only_brave'),True)
-ctl.configuration.solve.enum_mode = 'brave'
-with ctl.solve(assumptions=[(parse_term(a),True) for a in assumptions],
-                yield_=True) as result:
-    brave_model = None
-    for m in result:
-        brave_model  = [a.arguments[0] for a in m.symbols(shown=True)]
-
-    for a in brave_model:
-        print(f"{a}.")
-
-# Collect cautious
-ctl.assign_external(parse_term('only_brave'),False)
-ctl.assign_external(parse_term('only_cautious'),True)
-ctl.configuration.solve.enum_mode = 'cautious'
-with ctl.solve(assumptions=[(parse_term(a),True) for a in assumptions],
-                yield_=True) as result:
-    cautious_model = None
-    for m in result:
-        cautious_model  = [a.arguments[0] for a in m.symbols(shown=True)]
-
-    for a in cautious_model:
-        print(f"{a}.")
-        
\ No newline at end of file
diff --git a/old_prototype/clinguin.py b/old_prototype/clinguin.py
deleted file mode 100644
index 9e811b88..00000000
--- a/old_prototype/clinguin.py
+++ /dev/null
@@ -1,257 +0,0 @@
-from ast import arg
-from clingo import Control
-import clingo
-import clorm
-from clorm import Predicate, ConstantField, RawField, Raw
-from clingo.symbol import Function, Number, String
-import networkx as nx
-import sys 
-
-
-from tkinter import *
-
-
-class Config(Predicate):
-    id = RawField
-    argument = RawField
-    value = RawField
-
-    class Meta:
-        name = "config"
-
-class Widget(Predicate):
-    option = ConstantField
-    id = RawField
-    master = RawField
-
-    class Meta:
-        name = "widget"
-
-
-class Option(Predicate):
-    id = RawField
-    value = RawField
-    atom = RawField
-
-    class Meta:
-        name = "opt"
-
-class Geo(Predicate):
-    id = RawField
-    option = ConstantField
-    argument = RawField
-    value = RawField
-
-class Window(Predicate):
-    option = ConstantField
-    argument = RawField
-    value = RawField
-
-    class Meta:
-        name = "window"
-
-
-unifiers = [Config,Widget,Option,Geo,Window]
-
-ctl = Control()
-
-for f in sys.argv[1:]:
-    ctl.load(str(f))
-
-ctl.ground([("base", [])])
-
-
-
-def get_val(s):
-    if s.type == clingo.SymbolType.String:
-        return s.string
-    if s.type == clingo.SymbolType.Number:
-        return s.number
-    if s.type == clingo.SymbolType.Function:
-        if s.name == "":
-            return str(s)
-        return s.name
-
-def get_args(confs):
-    args = {}
-    kargs = {}
-    for c in confs:
-        arg = get_val(c.argument.symbol)
-        if type(arg) == int:
-            args[arg]= get_val(c.value.symbol)
-        else:
-            kargs[arg] = get_val(c.value.symbol)
-    args_list = []
-    pos = list(args.keys())
-    pos.sort()
-    for a in pos:
-        args_list.append(args[a])
-
-    return args_list, kargs
-
-class ClinWidget():
-
-    def __init__(self):
-        self.brave_model = None
-        self.widgets = {}
-        self.assumptions = set()
-        self.selected_var = {}
-        self.window=Tk()
-        self.update()
-        self.window.mainloop()
-
-
-
-    def set_select(self, w_id, val, ass):
-        self.selected_var[w_id].set(val)
-        self.assumptions.add(ass)
-        self.update()
-
-
-    def save_brave(self, model):
-        self.brave_model= model.symbols(atoms=True,shown=True)
-
-    def save_cautious(self, model):
-        self.cautious_model= model.symbols(atoms=True,shown=True)
-
-    def config_window(self,fb):
-        q = fb.query(Window)
-        q = q.group_by(Window.option)
-        for name, window in q.all():
-            args,kargs = get_args(window)
-            getattr(self.window,name)(*args,**kargs)
-
-
-    def create_widget(self, w_id, w_info, args, kargs):
-        t = w_info['option']
-        if str(w_info['master'].symbol)=='window':
-            master = self.window
-        else:
-            master = self.widgets[w_info['master']]
-        if t == "menu":
-            self.selected_var[w_id]=StringVar(value=" ")
-            widget = OptionMenu(
-                master,
-                self.selected_var[w_id],"")
-            widget.config(**kargs)
-            return widget
-        if t=="frame":
-
-            widget = Frame(master)
-            widget.config(**kargs)
-            # TODO this option should be general...
-            widget.grid_propagate(0)
-            return widget
-        
-        if t=="label":
-            
-            widget =  Label(master)
-            widget.config(**kargs)
-            return widget
-        
-        raise(RuntimeError(f"Wrong option {t}" ))
-
-
-    def new_widget(self, fb, w_id, w_info):
-
-        # Get creation options
-        q = fb.query(Config).where(Config.id==w_id)
-        
-        args,kargs = get_args(q.all())
-        widget = self.create_widget(w_id,w_info,args,kargs)
-
-        # Place widget
-        q = fb.query(Geo).where(Geo.id==w_id)
-        q = q.group_by(Geo.option)
-        q_list = list(q.all())
-        if len(q_list)>1:
-            raise(RuntimeError("Can only have one geo"))
-        elif len(q_list)==0:
-            widget.pack()
-        else:
-            for n in q.all():
-                name = n[0]
-                args,kargs = get_args(n[1])
-                
-                if name == 'grid':
-                    widget.grid(*args,**kargs)
-                elif name == 'place':
-                    widget.place(*args,**kargs)
-                elif name == 'pack':
-                    widget.pack(*args,**kargs)
-                else:
-                    raise RuntimeError(f"Invalid geo {name}")
-            
-        return widget
-
-
-
-            
-    def update(self):
-        self.create_layout()
-        self.update_options()
-
-
-    def update_options(self):
-        ctl.configuration.solve.enum_mode = 'brave'
-        ctl.solve(on_model=self.save_brave,assumptions=[(a,True) for a in list(self.assumptions)])
-        prg = "\n".join([str(s)+"." for s in self.brave_model])
-        fb = clorm.parse_fact_string(prg, unifiers)
-        for id, w in self.widgets.items():
-            if type(w)!=OptionMenu:
-                continue
-            if type(w['menu'])!=str:            
-                w['menu'].delete(0,'end')
-            q = fb.query(Option).where(Option.id==id)
-            # Only menu
-            q_list = list(q.all())
-            for opt in q_list:
-                v = get_val(opt.value.symbol)
-                w["menu"].add_command(label=v,
-                        command = lambda value=v, id=id, ass=opt.atom.symbol: 
-                        self.set_select(id,value,ass))
-            
-            if len(q_list)==1:
-                self.selected_var[id].set(get_val(q_list[0].value.symbol))
-
-    def create_layout(self):
-        # Get cautios model
-        ctl.configuration.solve.enum_mode = 'cautious'
-        ctl.solve(on_model=self.save_cautious,assumptions=[(a,True) for a in list(self.assumptions)])
-        prg = "\n".join([str(s)+"." for s in self.cautious_model])
-        fb = clorm.parse_fact_string(prg, unifiers)
-        
-        # Remove current widgets
-        for w_id, w in self.widgets.items():
-            w.destroy()
-        
-        self.config_window(fb)
-
-        # Get widget dependency to define creation order
-        q = fb.query(Widget)
-        dependency = []
-        widgets_info = {}        
-        for w in fb.query(Widget).all():
-            widgets_info[w.id]={'master':w.master,'option':w.option}
-            dependency.append((w.id,w.master))
-        DG = nx.DiGraph(dependency)
-        order = list(reversed(list(nx.topological_sort(DG))))
-        
-        # Create widgets in order
-        for w_id in order:
-            if (w_id==Raw(Function("window"))):
-                continue
-
-            w_info = widgets_info[w_id]
-            #DO this with clorm class
-            self.widgets[w_id] = self.new_widget(fb, w_id,w_info)
-            
-
-
-
-cw = ClinWidget()
-
-    
-
-
-
diff --git a/old_prototype/coloring1.lp b/old_prototype/coloring1.lp
deleted file mode 100644
index afc916fb..00000000
--- a/old_prototype/coloring1.lp
+++ /dev/null
@@ -1,24 +0,0 @@
-% Instance
-node(1..4).
-edge(1,2).
-edge(1,3).
-color(red; green).
-
-% Encoding
-{ assign(N, C) : color(C) } = 1 :- node(N).
-:- edge(N, M), assign(N, C), assign(M, C).
-
-
-% My labeled code
-_cautious(paint(N,C)):-assign(N,C). %Cautious
-_brave(option(N,C)):-assign(N,C). %Brave
-
-% Exptected output
-% paint(1,red).
-% paint(2,green).
-% paint(3,green).
-% option(1,red).
-% option(2,green).
-% option(3,green).
-% option(4,green).
-% option(4,red).
\ No newline at end of file
diff --git a/old_prototype/examples/sudoku/encoding.lp b/old_prototype/examples/sudoku/encoding.lp
deleted file mode 100644
index 4d8dc9eb..00000000
--- a/old_prototype/examples/sudoku/encoding.lp
+++ /dev/null
@@ -1,17 +0,0 @@
-% %%%%%%%%%%%%%%%%%%%%%%%%% Encoding
-
-#const dim = 3.
-
-val(1..dim*dim).
-pos(X,Y) :- val(X), val(Y).
-
-subgrid(X,Y,(((X-1)/dim)*dim+((Y-1)/dim))) :- pos(X,Y).
-
-1 { sudoku(X,Y,V) : val(V) } 1 :- pos(X,Y).
-
-:- sudoku(X,Y,V), sudoku(X',Y,V), X != X'.
-:- sudoku(X,Y,V), sudoku(X,Y',V), Y != Y'.
-:- sudoku(X,Y,V), sudoku(X',Y',V), subgrid(X,Y,S), subgrid(X',Y',S), (X,Y)!=(X',Y').
-
-
-sudoku(X,Y,V) :- initial(X,Y,V).
diff --git a/old_prototype/examples/sudoku/instance.lp b/old_prototype/examples/sudoku/instance.lp
deleted file mode 100644
index c4861fda..00000000
--- a/old_prototype/examples/sudoku/instance.lp
+++ /dev/null
@@ -1,37 +0,0 @@
-% %%%%%%%%%%%%%%%%%%%%%%%%% Instance
-
-initial(5,1,8).
-initial(6,2,7).
-initial(7,1,4).
-initial(8,2,2).
-initial(8,1,6).
-initial(9,2,9).
-initial(3,3,9).
-initial(4,3,3).
-initial(6,3,6).
-initial(7,3,5).
-initial(8,3,7).
-initial(1,4,7).
-initial(2,4,6).
-initial(4,4,4).
-initial(7,4,9).
-initial(8,4,3).
-initial(2,5,3).
-initial(3,5,2).
-initial(4,5,8).
-initial(7,5,7).
-initial(9,5,5).
-initial(1,6,9).
-initial(2,6,1).
-initial(3,6,8).
-initial(8,6,4).
-initial(9,6,6).
-initial(1,7,6).
-initial(5,7,7).
-initial(6,7,8).
-% initial(8,7,9).
-% initial(9,7,4).
-% initial(2,8,7).
-% initial(3,8,3).
-% initial(4,8,6).
-% initial(5,8,9).
diff --git a/old_prototype/examples/sudoku/widgets.lp b/old_prototype/examples/sudoku/widgets.lp
deleted file mode 100644
index 5892f534..00000000
--- a/old_prototype/examples/sudoku/widgets.lp
+++ /dev/null
@@ -1,36 +0,0 @@
-% ------------------------------
-% Window setup
-window(minsize, width, 900).
-window(minsize, height, 900).
-window(title, 0, "Sudoku").
-window(resizable, 0, 0).
-window(resizable, 1, 0).
-
-% ------------------------------
-% Cautious models update after every change
-
-% Make frames to define grid
-widget(frame,f(X,Y),window):- pos(X,Y).
-config(f(X,Y),bg,white):- subgrid(X,Y,S), S\2==0.
-geo(f(X,Y),grid,row,X):- pos(X,Y).
-geo(f(X,Y),grid,column,Y):- pos(X,Y).
-config(f(X,Y),width,100):- pos(X,Y).
-config(f(X,Y),height,100):- pos(X,Y).
-config(f(X,Y),highlightbackground,black):- pos(X,Y).
-config(f(X,Y),highlightthickness,1):- pos(X,Y).
-
-% Make menu buttons
-widget(menu,m(X,Y),f(X,Y)):- pos(X,Y).
-config(m(X,Y),font,"Arial 16"):- pos(X,Y).
-config(m(X,Y),width,1):- pos(X,Y).
-config(m(X,Y),fg,gray):- pos(X,Y), initial(X,Y,_).
-config(m(X,Y),bg,white):- subgrid(X,Y,S), S\2==0.
-geo(m(X,Y),grid,column,X\3):- pos(X,Y).
-geo(m(X,Y),grid,row,Y\3):- pos(X,Y).
-geo(m(X,Y),grid,padx,25):- pos(X,Y).
-geo(m(X,Y),grid,pady,37):- pos(X,Y).
-
-% ------------------------------
-% Brave models update after every chaange
-opt(m(X,Y),V,sudoku(X,Y,V)):- sudoku(X,Y,V).
-
diff --git a/setup.cfg b/setup.cfg
index 09a56a55..58658c35 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -20,7 +20,10 @@ install_requires =
     pydantic
     networkx
     uvicorn
-    importlib
+    Pillow
+    sphinx
+    nbsphinx
+    sphinx_rtd_theme
 
 [options.entry_points]
 console_scripts =
diff --git a/syntax_discussion/20220705_susana_syntax_idea.lp b/syntax_discussion/20220705_susana_syntax_idea.lp
deleted file mode 100644
index 3a949dc0..00000000
--- a/syntax_discussion/20220705_susana_syntax_idea.lp
+++ /dev/null
@@ -1,62 +0,0 @@
-% attr(ID,ATTRNAME,ARGVALUE,VALUE)
-% menu1.title("Sudoku")
-attr(window,title,0,"Sudoku").
-
-
-% element(ID,TYPE,PARENT_ID).  Perhaps we want parent as another predicare if not all UIS nee it
-% menu1 = menu(parent=window)
-element(menu1,menu,window).
-
-% menu1.config(bgcolor=blue,fontcolor=white)
-attr(menu1,cofig,bgcolor,blue).
-attr(menu1,cofig,fontcolor,white).
-
-% menu1.config(bgcolor=blue,fontcolor=white)
-attr(menu1,grid,x,1).
-attr(menu1,grid,y,1).
-
-
-element(opt1,option,menu).
-attr(opt1,??,label,"MyOption"). 
-
-% One of the following. Perhaps there are also other things like on_clink vs on_hover 
-attr(opt1,??,command,assert(mysymbol,true)).
-% callback(opt1,assert(mysymbol,true)).
-
-
-% Idea for interanl representation. Perhaps we also want it to be ordered by dependency
-{window:{
-    attr:{
-        title:{
-            0: "Sudoku"
-        }
-    }
-},
-elements:{
-    menu1:{
-        type: menu,
-        parent: window,
-        attr:{
-            config:{
-                bgcolor:blue,
-                fontcolor:white
-            },
-            grid:{
-                x:1,
-                y:1
-            }
-        }
-
-    },
-    opt1:{
-        type:option,
-        parent:menu1,
-        attr:{
-            label: "Myoption".
-            command: "assert(mysymbol,true)"     Perhaps the solver could have a function to map a symbol into a call "def call_by_symbol(symbol)". (This might be even better)
-        }
-    }
-
-}
-
-
diff --git a/syntax_discussion/20220706_alex_json_format.txt b/syntax_discussion/20220706_alex_json_format.txt
deleted file mode 100644
index 623a0c55..00000000
--- a/syntax_discussion/20220706_alex_json_format.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-I would use a more hierarchical approach, as this one can be directly parsed into an object-oriented-programming language:
-
-[
-    {
-        "element_id" : "window-0",
-        "element_type" : "window",
-        "element-parent" : "root",
-        "attribute-background-color" : "gray",
-        "attribute-children-organisation" : "grid",
-        "children" : [
-            {
-                "element_id" : "button-0",
-                "element_type" : "button",
-                "element-parent" : "window-0",
-                "callback" : 
-                    {
-                        "action" : "on-click",
-                        "policy" : "add",
-                        "predicate" : "sudoku(1,1,1)"
-                    }
-            },
-            {
-                ...
-            },
-            ...
-        ]
-
-    },
-    {
-        "element_id" : "window-1",
-        ...
-    }
-]
diff --git a/syntax_discussion/20220706_alex_syntax.lp b/syntax_discussion/20220706_alex_syntax.lp
deleted file mode 100644
index 94539251..00000000
--- a/syntax_discussion/20220706_alex_syntax.lp
+++ /dev/null
@@ -1,40 +0,0 @@
-% Syntax (Extension of Logic-Program):
-
-% element(ID,TYPE,PARENT_ID)
-%   -> Adds an element to the GUI
-%   -> ID       -> Must be unique, alphanumeric
-%   -> TYPE     -> One of:
-%       - WINDOW        - Creates a window
-%       - CONTAINER     - A container (div in HTML, frame in tkinter)
-%       - LABEL         - A line of text
-%       - BUTTON        - A button
-%       - DROPDOWN      - Dropdown menu
-%       - CANVAS        - One can draw whatever one likes, could be ''interesting'' to implement
-%       - ...?
-%   -> PARENT_ID -> Parent of the element to add, for window maybe ''root''?
-
-% attribute(ELEMENT_ID, ATTRIBUTE_KEY, ATTRIBUTE_VALUE)
-%   -> Defines an attribute of an element
-%   -> ELEMENT_ID       -> The ID of the corresponding element
-%   -> ATTRIBUTE_KEY    -> One of:
-%       - BACKGROUND-COLOR / BC
-%       - FONT-COLOR / FC
-%       - CHILDREN-ORGANISATION
-%       - X/Y 
-%       - SHAPE
-%       - ...
-%   -> ATTRIBUTE_VALUE -> Depends on key:
-%       - BC -> Green,Blue,... (some colors)
-%       - FC -> same as BC
-%       - CHILDREN-ORGANISATION -> grid/canvas/...
-%       - X/Y -> Numeric value (outcome depends on parent-children-organisation)
-%       - SHAPE -> Maybe oval or something like that
-%       - ...
-
-% callback(ELEMENT_ID, ACTION, ADD/RMV, PREDICATE)
-%   -> ELEMENT_ID       -> The ID of the corresponding element
-%   -> ACTION           -> CLICK,ON-HOVER,... (when the rule fires)
-%   -> POLICY           -> If the predicate shall be assumed or removed (only removed from assumptions or removed from program?)
-%   -> PREDICATE        -> The predicate 
-
- 
diff --git a/syntax_discussion/20220707_alex_json_format.txt b/syntax_discussion/20220707_alex_json_format.txt
deleted file mode 100644
index 01fe91ba..00000000
--- a/syntax_discussion/20220707_alex_json_format.txt
+++ /dev/null
@@ -1,40 +0,0 @@
-Included the feedback from the 2022-07-07 meeting
-I would use a more hierarchical approach, as this one can be directly parsed into an object-oriented-programming language:
-
-[
-    {
-        "element" : {
-            "id" : "window-0",
-            "type" : "window",
-            "parent" : "root",
-            },
-        "attributes" : [
-            "background-color" : "gray",
-            "children-organisation" : "grid",
-            ],
-        "children" : [
-            {
-                "element" : {
-                    "id" : "button-0",
-                    "type" : "button",
-                    "parent" : "window-0",
-                    },
-                "callback" : 
-                    {
-                        "action" : "on-click",
-                        "policy" : "add",
-                        "predicate" : "sudoku(1,1,1)"
-                    }
-            },
-            {
-                ...
-            },
-            ...
-        ]
-
-    },
-    {
-        "element_id" : "window-1",
-        ...
-    }
-]
diff --git a/syntax_discussion/20220707_alex_syntax.lp b/syntax_discussion/20220707_alex_syntax.lp
deleted file mode 100644
index a3c977b0..00000000
--- a/syntax_discussion/20220707_alex_syntax.lp
+++ /dev/null
@@ -1,43 +0,0 @@
-% added feedback from 2022-07-07 meeting
-% Syntax (Extension of Logic-Program):
-
-% element(ID,TYPE,PARENT_ID)
-%   -> Adds an element to the GUI
-%   -> ID       -> Must be unique, alphanumeric
-%   -> TYPE     -> One of:
-%       - WINDOW        - Creates a window
-%       - CONTAINER     - A container (div in HTML, frame in tkinter)
-%       - LABEL         - A line of text
-%       - BUTTON        - A button
-%       - DROPDOWN      - Dropdown menu
-%       - CANVAS        - One can draw whatever one likes, could be ''interesting'' to implement
-%       - ...?
-%   -> PARENT_ID -> Parent of the element to add, for window maybe ''root''?
-
-% -> Discussion if 3 or 4 element attribute
-%   - 3 element -> pretty flexible
-%   - 4 element -> better for tkinter
-% attribute(ELEMENT_ID, ATTRIBUTE_KEY, ATTRIBUTE_VALUE)
-%   -> Defines an attribute of an element
-%   -> ELEMENT_ID       -> The ID of the corresponding element
-%   -> ATTRIBUTE_KEY    -> One of:
-%       - BACKGROUND-COLOR / BC
-%       - FONT-COLOR / FC
-%       - CHILDREN-ORGANISATION
-%       - X/Y 
-%       - SHAPE
-%       - ...
-%   -> ATTRIBUTE_VALUE -> Depends on key:
-%       - BC -> Green,Blue,... (some colors)
-%       - FC -> same as BC
-%       - CHILDREN-ORGANISATION -> grid/canvas/...
-%       - X/Y -> Numeric value (outcome depends on parent-children-organisation)
-%       - SHAPE -> Maybe oval or something like that
-%       - ...
-
-
-% callback(ELEMENT_ID, ACTION, POLICY)
-%   -> ELEMENT_ID       -> The ID of the corresponding element
-%   -> ACTION           -> CLICK,ON-HOVER,... (when the rule fires)
-%   -> POLICY           -> Function in the solver that shall be executed, like ''assume(predicateXYZ)'' (adds an assumption), ''solve'' (solve the LP)
- 
diff --git a/syntax_discussion/20220711_alex_json_format.txt b/syntax_discussion/20220711_alex_json_format.txt
deleted file mode 100644
index efc646f1..00000000
--- a/syntax_discussion/20220711_alex_json_format.txt
+++ /dev/null
@@ -1,45 +0,0 @@
-Included the feedback from the 2022-07-07 meeting
-I would use a more hierarchical approach, as this one can be directly parsed into an object-oriented-programming language:
-
-[
-    {
-        "element" : {
-            "id" : "window-0",
-            "type" : "window",
-            "parent" : "root",
-            },
-        "attributes" : [
-            "background-color" : "gray",
-            "children-organisation" : "grid",
-            "options" : [
-                "1",
-                "2",
-                ...
-                ],
-            ],
-        "children" : [
-            {
-                "element" : {
-                    "id" : "button-0",
-                    "type" : "button",
-                    "parent" : "window-0",
-                    },
-                "callback" : 
-                    {
-                        "action" : "on-click",
-                        "policy" : "add",
-                        "predicate" : "sudoku(1,1,1)"
-                    }
-            },
-            {
-                ...
-            },
-            ...
-        ]
-
-    },
-    {
-        "element_id" : "window-1",
-        ...
-    }
-]
diff --git a/syntax_discussion/20220711_alex_syntax.lp b/syntax_discussion/20220711_alex_syntax.lp
deleted file mode 100644
index f3934fef..00000000
--- a/syntax_discussion/20220711_alex_syntax.lp
+++ /dev/null
@@ -1,45 +0,0 @@
-% added feedback from 2022-07-07 meeting
-% Syntax (Extension of Logic-Program):
-
-% element(ID,TYPE,PARENT_ID)
-%   -> Adds an element to the GUI
-%   -> ID       -> Must be unique, alphanumeric
-%   -> TYPE     -> One of:
-%       - WINDOW        - Creates a window
-%       - CONTAINER     - A container (div in HTML, frame in tkinter)
-%       - LABEL         - A line of text
-%       - BUTTON        - A button
-%       - DROPDOWN      - Dropdown menu
-%       - CANVAS        - One can draw whatever one likes, could be ''interesting'' to implement
-%       - ...?
-%   -> PARENT_ID -> Parent of the element to add, for window maybe ''root''?
-
-% -> Discussion if 3 or 4 element attribute
-%   - 3 element -> pretty flexible
-%   - 4 element -> better for tkinter
-% attribute(ELEMENT_ID, REASONING, ATTRIBUTE_KEY, ATTRIBUTE_VALUE)
-%   -> Defines an attribute of an element
-%   -> ELEMENT_ID       -> The ID of the corresponding element
-%   -> REASONING        -> Either Brave (B,b) OR Cautious (C,c)
-%   -> ATTRIBUTE_KEY    -> One of:
-%       - BACKGROUND-COLOR / BC
-%       - FONT-COLOR / FC
-%       - CHILDREN-ORGANISATION
-%       - X/Y 
-%       - SHAPE
-%       - ...
-%   -> ATTRIBUTE_VALUE -> Depends on key:
-%       - BC -> Green,Blue,... (some colors)
-%       - FC -> same as BC
-%       - CHILDREN-ORGANISATION -> grid/canvas/...
-%       - X/Y -> Numeric value (outcome depends on parent-children-organisation)
-%       - SHAPE -> Maybe oval or something like that
-%       - ...
-
-
-% callback(ELEMENT_ID, REASONING, ACTION, POLICY)
-%   -> ELEMENT_ID       -> The ID of the corresponding element
-%   -> REASONING        -> Either Brave (B,b) OR Cautious (C,c)
-%   -> ACTION           -> CLICK,ON-HOVER,... (when the rule fires)
-%   -> POLICY           -> Function in the solver that shall be executed, like ''assume(predicateXYZ)'' (adds an assumption), ''solve'' (solve the LP)
- 
diff --git a/syntax_discussion/20220711_widgets_1.lp b/syntax_discussion/20220711_widgets_1.lp
deleted file mode 100644
index 3372498d..00000000
--- a/syntax_discussion/20220711_widgets_1.lp
+++ /dev/null
@@ -1,58 +0,0 @@
-% ------------------------------
-% Window setup
-
-element(window, window, root).
-attribute(window, width, 900).
-attribute(window, height, 900).
-attribute(window, title, "Sudoku").
-attribute(window, resizable_height, 0).
-attribute(window, resizable_width, 0).
-
-% NEW:
-attribute(window, children-organisation, grid).
-
-% ------------------------------
-% Make frames to define grid
-
-element(f(X,Y), container, window) :- pos(X,Y).
-
-attribute(f(X,Y), background-color, white).
-attribute(f(X,Y), grid_row, X) :- pos(X,Y).
-attribute(f(X,Y), grid_column, Y) :- pos(X,Y).
-
-attribute(f(X,Y), width, 100) :- pos(X,Y).
-attribute(f(X,Y), height, 100) :- pos(X,Y).
-attribute(f(X,Y), highlightbackground, black) :- pos(X,Y).
-attribute(f(X,Y), highlightthickness, 1) :- pos(X,Y).
-
-attribute(f(X,Y), children-organisation, canvas) :- pos(X,Y).
-
-% ------------------------------
-% Make menu buttons
-
-element(m(X,Y), dropdown, f(X,Y)) :- pos(X,Y).
-
-attribute(m(X,Y), font, "Arial 16") :- pos(X,Y).
-attribute(m(X,Y), width, 30) :- pos(X,Y).
-attribute(m(X,Y), height, 16) :- pos(X,Y).
-attribute(m(X,Y), foreground-color, gray) :- pos(X,Y), initial(X,Y,_).
-attribute(m(X,Y), background-color, white) :- subgrid(X,Y,S), S\2==0.
-
-attribute(m(X,Y), pos_X, 35) :- pos(X,Y). % measured from the left of the parent element
-attribute(m(X,Y), pos_Y, 42) :- pos(X,Y). % measured from the top of the parent element
-attribute(m(X,Y), pad_X, 5)  :- pos(X,Y).
-attribute(m(X,Y), pad_Y, 3)  :- pos(X,Y).
-
-
-% ------------------------------
-% Interactivity part -> Function 
-
-callback(m(X,Y), click, brave, assume(sudoku(X,Y,V))) :- sudoku(X,Y,V). 
-% The function ''assume'' is assumed to be existant in the solver/engine/...
-% Where do we know, which elements m(X,Y) should have? -> Attributes which are solved bravely?
-% Value of dropdown... multiple (brave makes sense), vs. value of button... one (only cautious makes sense?)
-
-
-
-
-
diff --git a/syntax_discussion/20220711_widgets_2.lp b/syntax_discussion/20220711_widgets_2.lp
deleted file mode 100644
index 4b7f27ae..00000000
--- a/syntax_discussion/20220711_widgets_2.lp
+++ /dev/null
@@ -1,60 +0,0 @@
-% ------------------------------
-% Window setup
-
-element(window, window, root).
-attribute(window, c, width, 900).
-attribute(window, c, height, 900).
-attribute(window, c, title, "Sudoku").
-attribute(window, c, resizable_height, 0).
-attribute(window, c, resizable_width, 0).
-
-% NEW:
-attribute(window, c, children-organisation, grid).
-
-% ------------------------------
-% Make frames to define grid
-
-element(f(X,Y), container, window) :- pos(X,Y).
-
-attribute(f(X,Y), c, background-color, white).
-attribute(f(X,Y), c, grid_row, X) :- pos(X,Y).
-attribute(f(X,Y), c, grid_column, Y) :- pos(X,Y).
-
-attribute(f(X,Y), c, width, 100) :- pos(X,Y).
-attribute(f(X,Y), c, height, 100) :- pos(X,Y).
-attribute(f(X,Y), c, highlightbackground, black) :- pos(X,Y).
-attribute(f(X,Y), c, highlightthickness, 1) :- pos(X,Y).
-
-attribute(f(X,Y), c, children-organisation, canvas) :- pos(X,Y).
-
-% ------------------------------
-% Make menu buttons
-
-element(m(X,Y), dropdown, f(X,Y)) :- pos(X,Y).
-
-attribute(m(X,Y), c, font, "Arial 16") :- pos(X,Y).
-attribute(m(X,Y), c, width, 30) :- pos(X,Y).
-attribute(m(X,Y), c, height, 16) :- pos(X,Y).
-attribute(m(X,Y), c, foreground-color, gray) :- pos(X,Y), initial(X,Y,_).
-attribute(m(X,Y), c, background-color, white) :- subgrid(X,Y,S), S\2==0.
-
-attribute(m(X,Y), c, pos_X, 35) :- pos(X,Y). % measured from the left of the parent element
-attribute(m(X,Y), c, pos_Y, 42) :- pos(X,Y). % measured from the top of the parent element
-attribute(m(X,Y), c, pad_X, 5)  :- pos(X,Y).
-attribute(m(X,Y), c, pad_Y, 3)  :- pos(X,Y).
-
-
-% ------------------------------
-% Interactivity part (Brave reasoning)
-
-attribute(m(X,Y), b, option, V) :- sudoku(X,Y,V). 
-callback(m(X,Y), click, b, assume(sudoku(X,Y,V))) :- sudoku(X,Y,V). 
-% The function ''assume'' is assumed to be existant in the solver/engine/...
-% Where do we know, which elements m(X,Y) should have? -> Attributes which are solved bravely?
-
-% Value of dropdown... multiple (brave makes sense), vs. value of button... one (only cautious makes sense?)
-
-
-
-
-
diff --git a/syntax_discussion/20220712_alex_syntax.lp b/syntax_discussion/20220712_alex_syntax.lp
deleted file mode 100644
index 11d77ade..00000000
--- a/syntax_discussion/20220712_alex_syntax.lp
+++ /dev/null
@@ -1,38 +0,0 @@
-% added feedback from 2022-07-11 meeting
-% Syntax (Extension of Logic-Program):
-% This syntax is the syntax used in the Prototype (Simple client server V2)
-
-% element(ID,TYPE,PARENT_ID)
-%   -> Adds an element to the GUI
-%   -> ID       -> Must be unique, alphanumeric
-%   -> TYPE     -> One of:
-%       - WINDOW        - Creates a window
-%       - CONTAINER     - A container (div in HTML, frame in tkinter)
-%       - DROPDOWN      - Dropdown menu
-%       - DROPDOWN-OPTION - An option of the dropdown
-%   -> PARENT_ID -> Parent of the element to add, for window maybe ''root''?
-
-% attribute(ELEMENT_ID, ATTRIBUTE_KEY, ATTRIBUTE_VALUE)
-%   -> Defines an attribute of an element
-%   -> ELEMENT_ID       -> The ID of the corresponding element
-%   -> ATTRIBUTE_KEY    -> One of:
-%       - BACKGROUND-COLOR / BC
-%       - FONT-COLOR / FC
-%       - CHILDREN-ORGANISATION
-%       - X/Y 
-%       - SHAPE
-%       - ...
-%   -> ATTRIBUTE_VALUE -> Depends on key:
-%       - BC -> Green,Blue,... (some colors)
-%       - FC -> same as BC
-%       - CHILDREN-ORGANISATION -> grid/canvas/...
-%       - X/Y -> Numeric value (outcome depends on parent-children-organisation)
-%       - SHAPE -> Maybe oval or something like that
-%       - ...
-
-
-% callback(ELEMENT_ID, ACTION, POLICY)
-%   -> ELEMENT_ID       -> The ID of the corresponding element
-%   -> ACTION           -> CLICK,ON-HOVER,... (when the rule fires)
-%   -> POLICY           -> Function in the solver that shall be executed, like ''assume(predicateXYZ)'' (adds an assumption), ''solve'' (solve the LP)
- 
diff --git a/syntax_discussion/20220714_alex_syntax.lp b/syntax_discussion/20220714_alex_syntax.lp
deleted file mode 100644
index 4d94f892..00000000
--- a/syntax_discussion/20220714_alex_syntax.lp
+++ /dev/null
@@ -1,31 +0,0 @@
-% added feedback from 2022-07-11 meeting
-% Syntax (Extension of Logic-Program):
-% This syntax is the syntax used in the Prototype (Simple client server V2)
-
-% element(ID,TYPE,PARENT_ID)
-%   -> Adds an element to the GUI
-%   -> ID       -> Must be unique, alphanumeric
-%   -> TYPE     -> One of:
-%       - window        - Creates a window
-%       - container     - A container (div in HTML, frame in tkinter)
-%       - dropdownmenu      - Dropdown menu
-%       - dropdownmenuitem - An option of the dropdown
-%   -> PARENT_ID -> Parent of the element to add, for window maybe ''root''?
-
-% attribute(ELEMENT_ID, ATTRIBUTE_KEY, ATTRIBUTE_VALUE)
-%   -> Defines an attribute of an element
-%   -> ELEMENT_ID       -> The ID of the corresponding element
-%   -> ATTRIBUTE_KEY    -> One of:
-%       - backgroundcolor 	-> usable for window and container (anything possible which works for tkinter)
-%	- width 		-> usable for window, container and dropdownmenu (pos. integer)
-%	- height		-> usable for window and container (pos. integer)
-%	- selected		-> usable for the dropdownmenu (must be an ID of a child dropdownmenuitem)
-%	- initially_selected	-> basically like selected, just with a lower priority 
-%	- gridx		-> useable for container (sets the grid position, non-neg. integer)
-%	- gridy		-> useable for container (sets the grid position, non-neg. integer)
-%	- label		-> useable for dropdownmenuitem (if the displayed label should differ from the ID)
-% callback(ELEMENT_ID, ACTION, POLICY)
-%   -> ELEMENT_ID       -> The ID of the corresponding element - currently ONLY works for dropdownmenuitem elements
-%   -> ACTION           -> click (the only thing that works currently)
-%   -> POLICY           -> Function in the solver that shall be executed, like ''assume(predicateXYZ)'' (adds an assumption), ''solve'' (solve the LP)
- 


Test patch:
diff --git a/examples/basic/test_0/empty_source_file.lp b/examples/basic/test_0/empty_source_file.lp
new file mode 100644
index 00000000..e69de29b
diff --git a/examples/basic/test_0/widgets.lp b/examples/basic/test_0/widgets.lp
new file mode 100644
index 00000000..f91e5da4
--- /dev/null
+++ b/examples/basic/test_0/widgets.lp
@@ -0,0 +1,40 @@
+
+element(window, window, root).
+
+h(500).
+w(500).
+
+attribute(window, height, X) :- h(X).
+attribute(window, width, X) :- w(X).
+attribute(window, background_color, black).
+attribute(window, resizable_x, 0).
+attribute(window, child_layout, grid).
+
+amount(5).
+p(0..(R*R-1)) :- amount(R).
+
+element(c(X), container, window) :- p(X).
+attribute(c(X), grid_column, X\R) :- p(X), amount(R).
+attribute(c(X), grid_row, X/R) :- p(X), amount(R).
+attribute(c(X), background_color, gray) :- p(X), X\2 == 1.
+attribute(c(X), background_color, black) :- p(X), X\2 == 0.
+attribute(c(X), height, H/R) :- p(X), h(H), amount(R).
+attribute(c(X), width, W/R) :- p(X), w(W), amount(R).
+attribute(c(X), child_layout, grid) :- p(X).
+
+
+amount2(3).
+q(X,0..(R*R-1)) :- p(X), amount2(R).
+
+element(c(X,Y), container, c(X)) :- q(X,Y).
+attribute(c(X,Y), grid_column, Y\R) :- q(X,Y), amount2(R).
+attribute(c(X,Y), grid_row, Y/R) :- q(X,Y), amount2(R).
+attribute(c(X,Y), background_color, blue) :- q(X,Y), Y\2 == 1, X\2 == 0.
+attribute(c(X,Y), background_color, red) :- q(X,Y), Y\2 == 0, X\2 == 0.
+attribute(c(X,Y), background_color, gray) :- q(X,Y), Y\2 == 1, X\2 == 1.
+attribute(c(X,Y), background_color, white) :- q(X,Y), Y\2 == 0, X\2 == 1.
+attribute(c(X,Y), height, H/(R1 * R2)) :- q(X,Y), h(H), amount(R1), amount2(R2).
+attribute(c(X,Y), width, W/(R1 * R2)) :- q(X,Y), w(W), amount(R1), amount2(R2).
+
+
+
diff --git a/examples/basic/test_1/source_file.lp b/examples/basic/test_1/source_file.lp
new file mode 100644
index 00000000..a2c87751
--- /dev/null
+++ b/examples/basic/test_1/source_file.lp
@@ -0,0 +1,5 @@
+
+p(1) :- not p(2).
+p(2) :- not p(1).
+
+
diff --git a/examples/basic/test_1/widgets.lp b/examples/basic/test_1/widgets.lp
new file mode 100644
index 00000000..7ea49f5c
--- /dev/null
+++ b/examples/basic/test_1/widgets.lp
@@ -0,0 +1,29 @@
+
+element(w, window, root).
+attribute(w, height, 500).
+attribute(w, width, 500).
+attribute(w, background_color, white).
+
+element(c, dropdown_menu, w).
+attribute(c, width, 100).
+attribute(c, height, 50).
+
+attribute(c, on_hover, true).
+attribute(c, on_hover_background_color, blue).
+
+attribute(c, selected, mi(X)) :- _b(p(X)).
+
+element(mi(X), dropdown_menu_item, c) :- _b(p(X)).
+attribute(mi(X), label, X) :- _b(p(X)).
+callback(mi(X), click, add_assumption(p(X))) :- _b(p(X)).
+
+element(c2, container, w).
+attribute(c2, width, 100).
+attribute(c2, height, 50).
+attribute(c2, border_width, 20).
+attribute(c2, border_color, pink).
+attribute(c2, background_color, red).
+
+
+
+
diff --git a/examples/basic/test_2/source_file.lp b/examples/basic/test_2/source_file.lp
new file mode 100644
index 00000000..a2c87751
--- /dev/null
+++ b/examples/basic/test_2/source_file.lp
@@ -0,0 +1,5 @@
+
+p(1) :- not p(2).
+p(2) :- not p(1).
+
+
diff --git a/examples/basic/test_2/widgets.lp b/examples/basic/test_2/widgets.lp
new file mode 100644
index 00000000..1d1c492e
--- /dev/null
+++ b/examples/basic/test_2/widgets.lp
@@ -0,0 +1,20 @@
+
+element(w, window, root).
+attribute(w, height, 500).
+attribute(w, width, 500).
+attribute(w, background_color, black).
+
+element(m, dropdown_menu, w).
+attribute(m, height, 20).
+attribute(m, width, 50).
+attribute(m, selected, X) :- p(X).
+
+element(mi(X), dropdown_menu_item, m) :- _b(p(X)).
+attribute(mi(X), label, X) :- _b(p(X)).
+callback(mi(X), click, add_assumption(p(X))) :- _b(p(X)).
+
+
+
+
+
+
diff --git a/examples/basic/test_3/source_file.lp b/examples/basic/test_3/source_file.lp
new file mode 100644
index 00000000..e08b90c1
--- /dev/null
+++ b/examples/basic/test_3/source_file.lp
@@ -0,0 +1,10 @@
+
+p(1) :- not p(2).
+p(2) :- not p(1).
+
+
+t(1..3).
+r(1..3).
+pos(T,R) :- t(T), r(R).
+
+
diff --git a/examples/basic/test_3/widgets.lp b/examples/basic/test_3/widgets.lp
new file mode 100644
index 00000000..dfebfa19
--- /dev/null
+++ b/examples/basic/test_3/widgets.lp
@@ -0,0 +1,89 @@
+element(w, window, root).
+attribute(w, height, 500).
+attribute(w, width, 500).
+attribute(w, background_color, white).
+attribute(w, child_layout, relstatic).
+
+element(c, container, w).
+attribute(c, width, 250).
+attribute(c, height, 150).
+attribute(c, border_width, 2).
+attribute(c, on_hover, true).
+attribute(c, on_hover_background_color, blue).
+attribute(c, on_hover_border_color, red).
+attribute(c, pos_x, 25).
+attribute(c, pos_y, 0).
+attribute(c, child_layout, absstatic).
+
+element(cc, container, c).
+attribute(cc, width, 100).
+attribute(cc, height, 50).
+attribute(cc, background_color, green).
+attribute(cc, border_width, 2).
+attribute(cc, pos_x, 0).
+attribute(cc, pos_y, 0).
+
+element(m, dropdown_menu, c).
+attribute(m, width, 100).
+attribute(m, height, 50).
+attribute(m, pos_x, 0).
+attribute(m, pos_y, 50).
+attribute(m, background_color, black).
+attribute(m, foreground_color, white).
+attribute(m, on_hover, true).
+attribute(m, on_hover_background_color, white).
+attribute(m, on_hover_foreground_color, black).
+
+element(mi(X), dropdown_menu_item, m) :- _b(p(X)).
+attribute(mi(X), label, X) :- _b(p(X)).
+callback(mi(X), click, add_assumption(p(X))) :- _b(p(X)).
+attribute(m, selected, X) :- p(X).
+
+element(c4, container, c).
+attribute(c4, width, 146).
+attribute(c4, height, 146).
+attribute(c4, background_color, beige).
+attribute(c4, pos_x, 100).
+attribute(c4, pos_y, 0).
+attribute(c4, child_layout, grid).
+
+element(c(X,Y), container, c4) :- pos(X,Y).
+attribute(c(X,Y), width, 48) :- pos(X,Y).
+attribute(c(X,Y), height, 48) :- pos(X,Y).
+attribute(c(X,Y), grid_column, X) :- pos(X,Y).
+attribute(c(X,Y), grid_row, Y) :- pos(X,Y).
+attribute(c(X,Y), background_color, pink) :- pos(X,Y), (X + Y) \ 2 = 0.
+attribute(c(X,Y), background_color, red) :- pos(X,Y), (X + Y) \ 2 = 1.
+
+element(l1, label, w).
+attribute(l1, background_color, blue).
+attribute(l1, foreground_color, brown).
+attribute(l1, label, "Clear!").
+attribute(l1, on_hover, true).
+attribute(l1, on_hover_background_color, gray).
+attribute(l1, on_hover_foreground_color, beige).
+attribute(l1, font_size, 15).
+attribute(l1, font_weight, "i").
+attribute(l1, width, 100).
+attribute(l1, height, 50).
+attribute(l1, pos_x, 40).
+attribute(l1, pos_y, 50).
+callback(l1, click, clear_assumptions).
+
+element(b, button, w).
+attribute(b, background_color, blue).
+attribute(b, foreground_color, brown).
+attribute(b, label, "Clear!").
+attribute(b, on_hover, true).
+attribute(b, on_hover_background_color, gray).
+attribute(b, on_hover_foreground_color, beige).
+attribute(b, font_size, 18).
+attribute(b, font_weight, "bi").
+attribute(b, width, 100).
+attribute(b, height, 50).
+attribute(b, pos_x, 40).
+attribute(b, pos_y, 70).
+
+callback(b, click, clear_assumptions).
+
+
diff --git a/examples/basic/test_4/empty_source_file.lp b/examples/basic/test_4/empty_source_file.lp
new file mode 100644
index 00000000..e69de29b
diff --git a/examples/basic/test_4/widgets.lp b/examples/basic/test_4/widgets.lp
new file mode 100644
index 00000000..662ffab1
--- /dev/null
+++ b/examples/basic/test_4/widgets.lp
@@ -0,0 +1,111 @@
+element(w, window, root).
+attribute(w, height, 500).
+attribute(w, width, 500).
+attribute(w, background_color, white).
+attribute(w, child_layout, relstatic).
+
+% ---------------- MENU BAR -----------------------------
+element(m, menu_bar, w).
+
+element(ms1, menu_bar_section, m).
+attribute(ms1, label, "File").
+
+element(ms1i1, menu_bar_section_item, ms1).
+attribute(ms1i1, label, "Open").
+element(ms1i2, menu_bar_section_item, ms1).
+attribute(ms1i2, label, "Close").
+callback(ms1i2, click, clear_assumptions).
+
+element(ms2, menu_bar_section, m).
+element(ms2i2, menu_bar_section_item, ms2).
+
+% ------------------- TOP ELEMENT(S) ----------------------------------
+
+element(b, button, w).
+attribute(b, background_color, blue).
+attribute(b, foreground_color, brown).
+attribute(b, label, "Clear!").
+attribute(b, on_hover, true).
+attribute(b, on_hover_background_color, gray).
+attribute(b, on_hover_foreground_color, beige).
+attribute(b, font_size, 15).
+
+attribute(b, pos_x, 25).
+attribute(b, pos_y, 0).
+%attribute(b, width, 250).
+%attribute(b, height, 150).
+
+attribute(c, border_width, 2).
+
+
+callback(b, click, clear_assumptions).
+
+% --------------------- BELOW ELEMENT(S) --------------------------------------
+
+element(c2, container, w).
+attribute(c2, width, 180).
+attribute(c2, height, 180).
+attribute(c2, border_width, 2).
+attribute(c2, on_hover, true).
+attribute(c2, on_hover_background_color, blue).
+attribute(c2, on_hover_border_color, red).
+attribute(c2, pos_x, 25).
+attribute(c2, pos_y, 50).
+attribute(c2, child_layout, grid).
+
+element(c20, container, c2).
+attribute(c20, width, 120).
+attribute(c20, height, 60).
+attribute(c20, background_color, "#fff000000").
+attribute(c20, grid_column, 0).
+attribute(c20, grid_row, 0).
+attribute(c20, grid_column_span, 2).
+attribute(c20, grid_row_span, 1).
+
+element(c21, container, c2).
+attribute(c21, width, 60).
+attribute(c21, height, 120).
+attribute(c21, background_color, "#000fff000").
+attribute(c21, grid_column, 2).
+attribute(c21, grid_row, 0).
+attribute(c21, grid_column_span, 1).
+attribute(c21, grid_row_span, 2).
+
+element(c22, container, c2).
+attribute(c22, width, 60).
+attribute(c22, height, 120).
+attribute(c22, background_color, "#000000fff").
+attribute(c22, grid_column, 0).
+attribute(c22, grid_row, 1).
+attribute(c22, grid_column_span, 1).
+attribute(c22, grid_row_span, 2).
+
+element(c23, container, c2).
+attribute(c23, width, 120).
+attribute(c23, height, 60).
+attribute(c23, background_color, "#999999999").
+attribute(c23, grid_column, 1).
+attribute(c23, grid_row, 2).
+attribute(c23, grid_column_span, 2).
+attribute(c23, grid_row_span, 1).
+
+element(c24, container, c2).
+attribute(c24, width, 60).
+attribute(c24, height, 60).
+attribute(c24, background_color, "#000000000").
+attribute(c24, grid_column, 1).
+attribute(c24, grid_row, 1).
+attribute(c24, grid_column_span, 1).
+attribute(c24, grid_row_span, 1).
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/basic/test_5/empty_source_file.lp b/examples/basic/test_5/empty_source_file.lp
new file mode 100644
index 00000000..e69de29b
diff --git a/examples/basic/test_5/widgets.lp b/examples/basic/test_5/widgets.lp
new file mode 100644
index 00000000..f77a3f65
--- /dev/null
+++ b/examples/basic/test_5/widgets.lp
@@ -0,0 +1,26 @@
+element(w, window, root).
+attribute(w, background_color, pink).
+attribute(w, child_layout, grid).
+
+element(c2, container, w).
+attribute(c2, border_width, 3).
+attribute(c2, background_color, "#0f0f0f").
+attribute(c2, grid_column, 0).
+
+element(l2, label, c2).
+attribute(l2, label, "This is a label").
+
+element(l3, label, c2).
+attribute(l3, label, "This is another label").
+
+element(c20, container, c2).
+attribute(c20, background_color, "#00ffff").
+attribute(c20, height, 20).
+attribute(c20, width, 20).
+
+element(c3, container, w).
+attribute(c3, background_color, "#ffff00").
+attribute(c3, grid_column, 1).
+
+element(l33, label, c3).
+attribute(l33, label, "Label 3").
diff --git a/examples/basic/test_6/empty_source_file.lp b/examples/basic/test_6/empty_source_file.lp
new file mode 100644
index 00000000..e69de29b
diff --git a/examples/basic/test_6/widgets_abs_static.lp b/examples/basic/test_6/widgets_abs_static.lp
new file mode 100644
index 00000000..b608db4b
--- /dev/null
+++ b/examples/basic/test_6/widgets_abs_static.lp
@@ -0,0 +1,23 @@
+element(w, window, root).
+attribute(w, background_color, pink).
+attribute(w, child_layout, absstatic).
+
+element(c2, container, w).
+attribute(c2, border_width, 3).
+attribute(c2, background_color, "#0f0f0f").
+attribute(c2, grid_column, 0).
+attribute(c2, width, 200).
+attribute(c2, height, 200).
+attribute(c2, pos_x, 0).
+attribute(c2, pos_y, 0).
+
+element(c3, container, w).
+attribute(c3, border_width, 3).
+attribute(c3, background_color, "#00ff00").
+attribute(c3, grid_column, 0).
+attribute(c3, width, 200).
+attribute(c3, height, 200).
+attribute(c3, pos_x, 0).
+attribute(c3, pos_y, 200).
+
+
diff --git a/examples/basic/test_6/widgets_pack.lp b/examples/basic/test_6/widgets_pack.lp
new file mode 100644
index 00000000..4d3b23f0
--- /dev/null
+++ b/examples/basic/test_6/widgets_pack.lp
@@ -0,0 +1,19 @@
+element(w, window, root).
+attribute(w, background_color, pink).
+attribute(w, child_layout, flex).
+
+element(c2, container, w).
+attribute(c2, border_width, 3).
+attribute(c2, background_color, "#0f0f0f").
+attribute(c2, grid_column, 0).
+attribute(c2, width, 200).
+attribute(c2, height, 200).
+
+element(c3, container, w).
+attribute(c3, border_width, 3).
+attribute(c3, background_color, "#00ff00").
+attribute(c3, grid_column, 0).
+attribute(c3, width, 200).
+attribute(c3, height, 200).
+
+
diff --git a/examples/basic/test_6/widgets_rel_static.lp b/examples/basic/test_6/widgets_rel_static.lp
new file mode 100644
index 00000000..22f2dc8b
--- /dev/null
+++ b/examples/basic/test_6/widgets_rel_static.lp
@@ -0,0 +1,23 @@
+element(w, window, root).
+attribute(w, background_color, pink).
+attribute(w, child_layout, relstatic).
+
+element(c2, container, w).
+attribute(c2, border_width, 3).
+attribute(c2, background_color, "#0f0f0f").
+attribute(c2, grid_column, 0).
+attribute(c2, width, 200).
+attribute(c2, height, 200).
+attribute(c2, pos_x, 0).
+attribute(c2, pos_y, 0).
+
+element(c3, container, w).
+attribute(c3, border_width, 3).
+attribute(c3, background_color, "#00ff00").
+attribute(c3, grid_column, 0).
+attribute(c3, width, 200).
+attribute(c3, height, 200).
+attribute(c3, pos_x, 0).
+attribute(c3, pos_y, 50).
+
+
diff --git a/examples/basic/test_7/README.md b/examples/basic/test_7/README.md
new file mode 100644
index 00000000..1d197482
--- /dev/null
+++ b/examples/basic/test_7/README.md
@@ -0,0 +1,2 @@
+Image license (tommi.jpg): CC-BY-SA - Image taken by Alexander Beiser.
+
diff --git a/examples/basic/test_7/empty_source_file.lp b/examples/basic/test_7/empty_source_file.lp
new file mode 100644
index 00000000..e69de29b
diff --git a/examples/basic/test_7/tommi.jpg b/examples/basic/test_7/tommi.jpg
new file mode 100644
index 00000000..99704af3
Binary files /dev/null and b/examples/basic/test_7/tommi.jpg differ
diff --git a/examples/basic/test_7/ui.lp b/examples/basic/test_7/ui.lp
new file mode 100644
index 00000000..d7b7050c
--- /dev/null
+++ b/examples/basic/test_7/ui.lp
@@ -0,0 +1,13 @@
+element(window, window, root).
+
+attribute(window, height, 1300).
+attribute(window, width, 1000).
+attribute(window, pos_x, 0).
+attribute(window, pos_y, 100).
+
+element(canv, canvas, window).
+attribute(canv, image_path, "./examples/basic/test_7/tommi.jpg").
+attribute(canv, resize, true).
+
+
+
diff --git a/examples/basic/test_8/empty_source_file.lp b/examples/basic/test_8/empty_source_file.lp
new file mode 100644
index 00000000..e69de29b
diff --git a/examples/basic/test_8/ui.lp b/examples/basic/test_8/ui.lp
new file mode 100644
index 00000000..bf7c15a7
--- /dev/null
+++ b/examples/basic/test_8/ui.lp
@@ -0,0 +1,31 @@
+element(window, window, root).
+
+attribute(window, height, 600).
+attribute(window, width, 600).
+attribute(window, child_layout, absstatic).
+
+element(f1, container, window).
+attribute(f1, background_color, "#ff0000").
+
+element(b1, button, f1).
+attribute(b1, label, "My button").
+attribute(b1, background_color, "#00ff00").
+
+element(m1, message, window).
+attribute(m1, type, info).
+attribute(m1, title, "INFO").
+attribute(m1, message, "MESSAGE").
+
+element(m2, message, window).
+attribute(m2, type, error).
+attribute(m2, title, "ERROR").
+attribute(m2, message, "MESSAGE").
+
+element(m3, message, window).
+attribute(m3, type, warning).
+attribute(m3, title, "WARNING").
+attribute(m3, message, "MESSAGE").
+
+
+
+
diff --git a/examples/test_0/widgets.lp b/examples/test_0/widgets.lp
deleted file mode 100644
index 2c7a2559..00000000
--- a/examples/test_0/widgets.lp
+++ /dev/null
@@ -1,40 +0,0 @@
-
-element(window, window, root).
-
-h(500).
-w(500).
-
-attribute(window, height, X) :- h(X).
-attribute(window, width, X) :- w(X).
-attribute(window, backgroundcolor, black).
-attribute(window, resizablex, 0).
-attribute(window, childorg, grid).
-
-amount(5).
-p(0..(R*R-1)) :- amount(R).
-
-element(c(X), container, window) :- p(X).
-attribute(c(X), gridcolumn, X\R) :- p(X), amount(R).
-attribute(c(X), gridrow, X/R) :- p(X), amount(R).
-attribute(c(X), backgroundcolor, gray) :- p(X), X\2 == 1.
-attribute(c(X), backgroundcolor, black) :- p(X), X\2 == 0.
-attribute(c(X), height, H/R) :- p(X), h(H), amount(R).
-attribute(c(X), width, W/R) :- p(X), w(W), amount(R).
-attribute(c(X), childorg, grid) :- p(X).
-
-
-amount2(3).
-q(X,0..(R*R-1)) :- p(X), amount2(R).
-
-element(c(X,Y), container, c(X)) :- q(X,Y).
-attribute(c(X,Y), gridcolumn, Y\R) :- q(X,Y), amount2(R).
-attribute(c(X,Y), gridrow, Y/R) :- q(X,Y), amount2(R).
-attribute(c(X,Y), backgroundcolor, blue) :- q(X,Y), Y\2 == 1, X\2 == 0.
-attribute(c(X,Y), backgroundcolor, red) :- q(X,Y), Y\2 == 0, X\2 == 0.
-attribute(c(X,Y), backgroundcolor, gray) :- q(X,Y), Y\2 == 1, X\2 == 1.
-attribute(c(X,Y), backgroundcolor, white) :- q(X,Y), Y\2 == 0, X\2 == 1.
-attribute(c(X,Y), height, H/(R1 * R2)) :- q(X,Y), h(H), amount(R1), amount2(R2).
-attribute(c(X,Y), width, W/(R1 * R2)) :- q(X,Y), w(W), amount(R1), amount2(R2).
-
-
-
diff --git a/examples/test_1/widgets.lp b/examples/test_1/widgets.lp
deleted file mode 100644
index 689b1738..00000000
--- a/examples/test_1/widgets.lp
+++ /dev/null
@@ -1,33 +0,0 @@
-p(1) :- not p(2).
-p(2) :- not p(1).
-
-element(w, window, root).
-attribute(w, height, 500).
-attribute(w, width, 500).
-attribute(w, backgroundcolor, white).
-
-element(c, container, w).
-attribute(c, width, 100).
-attribute(c, height, 50).
-attribute(c, borderwidth, 2).
-attribute(c, onhover, true).
-attribute(c, onhoverbackgroundcolor, blue).
-attribute(c, onhoverbordercolor, red).
-
-element(m, dropdownmenu, c).
-
-element(mi(X), dropdownmenuitem, m) :- p(X).
-attribute(mi(X), label, X) :- p(X).
-attribute(m, selected, mi(X)) :- p(X).
-callback(mi(X), click, assume(p(X))) :- p(X).
-
-element(c2, container, w).
-attribute(c2, width, 100).
-attribute(c2, height, 50).
-attribute(c2, borderwidth, 20).
-attribute(c2, bordercolor, pink).
-attribute(c2, backgroundcolor, red).
-
-
-
-
diff --git a/examples/test_2/widgets.lp b/examples/test_2/widgets.lp
deleted file mode 100644
index 9643e43e..00000000
--- a/examples/test_2/widgets.lp
+++ /dev/null
@@ -1,22 +0,0 @@
-p(1) :- not p(2).
-p(2) :- not p(1).
-
-element(w, window, root).
-attribute(w, height, 500).
-attribute(w, width, 500).
-attribute(w, backgroundcolor, black).
-
-element(m, dropdownmenu, w).
-attribute(m, height, 20).
-attribute(m, width, 50).
-attribute(m, selected, X) :- p(X).
-
-element(mi(X), dropdownmenuitem, m) :- p(X).
-attribute(mi(X), label, X) :- p(X).
-callback(mi(X), click, assume(p(X))) :- p(X).
-
-
-
-
-
-
diff --git a/examples/test_3/widgets.lp b/examples/test_3/widgets.lp
deleted file mode 100644
index bda30ed2..00000000
--- a/examples/test_3/widgets.lp
+++ /dev/null
@@ -1,126 +0,0 @@
-p(1) :- not p(2).
-p(2) :- not p(1).
-
-element(w, window, root).
-attribute(w, height, 500).
-attribute(w, width, 500).
-attribute(w, backgroundcolor, white).
-attribute(w, childorg, relstatic).
-
-element(c, container, w).
-attribute(c, width, 250).
-attribute(c, height, 150).
-attribute(c, borderwidth, 2).
-attribute(c, onhover, true).
-attribute(c, onhoverbackgroundcolor, blue).
-attribute(c, onhoverbordercolor, red).
-attribute(c, posx, 25).
-attribute(c, posy, 0).
-attribute(c, childorg, absstatic).
-
-element(cc, container, c).
-attribute(cc, width, 100).
-attribute(cc, height, 50).
-attribute(cc, backgroundcolor, green).
-attribute(cc, borderwidth, 2).
-attribute(cc, posx, 0).
-attribute(cc, posy, 0).
-
-element(ccc, container, c).
-attribute(ccc, width, 100).
-attribute(ccc, height, 50).
-attribute(ccc, backgroundcolor, yellow).
-attribute(ccc, borderwidth, 2).
-attribute(ccc, posx, 0).
-attribute(ccc, posy, 50).
-
-element(m, dropdownmenu, ccc).
-attribute(m, backgroundcolor, black).
-attribute(m, foregroundcolor, white).
-attribute(m, onhover, true).
-attribute(m, onhoverbackgroundcolor, white).
-attribute(m, onhoverforegroundcolor, black).
-
-element(mi(X), dropdownmenuitem, m) :- p(X).
-attribute(mi(X), label, X) :- p(X).
-callback(mi(X), click, assume(p(X))) :- p(X).
-attribute(m, selected, X) :- p(X).
-
-element(c4, container, c).
-attribute(c4, width, 146).
-attribute(c4, height, 146).
-attribute(c4, backgroundcolor, beige).
-attribute(c4, posx, 100).
-attribute(c4, posy, 0).
-attribute(c4, childorg, grid).
-
-% Not implemented due to tkinter
-%attribute(c4, padx, 10).
-%attribute(c4, pady, 10).
-
-t(1..3).
-r(1..3).
-pos(T,R) :- t(T), r(R).
-
-element(c(X,Y), container, c4) :- pos(X,Y).
-attribute(c(X,Y), width, 48) :- pos(X,Y).
-attribute(c(X,Y), height, 48) :- pos(X,Y).
-attribute(c(X,Y), gridcolumn, X) :- pos(X,Y).
-attribute(c(X,Y), gridrow, Y) :- pos(X,Y).
-attribute(c(X,Y), backgroundcolor, pink) :- pos(X,Y), (X + Y) \ 2 = 0.
-attribute(c(X,Y), backgroundcolor, red) :- pos(X,Y), (X + Y) \ 2 = 1.
-
-
-
-
-element(c2, container, w).
-attribute(c2, width, 100).
-attribute(c2, height, 50).
-attribute(c2, borderwidth, 1).
-attribute(c2, bordercolor, pink).
-attribute(c2, backgroundcolor, white).
-attribute(c2, posx, 40).
-attribute(c2, posy, 50).
-attribute(c2, onhover, true).
-attribute(c2, onhoverbackgroundcolor, gray).
-callback(c2, click, clear).
-
-
-element(l1, label, c2).
-attribute(l1, backgroundcolor, blue).
-attribute(l1, foregroundcolor, brown).
-attribute(l1, label, "Clear!").
-attribute(l1, onhover, true).
-attribute(l1, onhoverbackgroundcolor, gray).
-attribute(l1, onhoverforegroundcolor, beige).
-attribute(l1, fontsize, 15).
-callback(l1, click, clear).
-
-
-
-
-
-
-element(c3, container, w).
-attribute(c3, width, 100).
-attribute(c3, height, 50).
-attribute(c3, borderwidth, 1).
-attribute(c3, bordercolor, pink).
-attribute(c3, backgroundcolor, white).
-attribute(c3, posx, 40).
-attribute(c3, posy, 80).
-attribute(c3, onhover, true).
-attribute(c3, onhoverbackgroundcolor, gray).
-callback(c3, click, clear).
-
-element(b, button, c3).
-attribute(b, backgroundcolor, blue).
-attribute(b, foregroundcolor, brown).
-attribute(b, label, "Clear!").
-attribute(b, onhover, true).
-attribute(b, onhoverbackgroundcolor, gray).
-attribute(b, onhoverforegroundcolor, beige).
-attribute(b, fontsize, 15).
-callback(b, click, clear).
-
-
diff --git a/examples/test_4/widgets.lp b/examples/test_4/widgets.lp
deleted file mode 100644
index a3e845bd..00000000
--- a/examples/test_4/widgets.lp
+++ /dev/null
@@ -1,108 +0,0 @@
-element(w, window, root).
-attribute(w, height, 500).
-attribute(w, width, 500).
-attribute(w, backgroundcolor, white).
-attribute(w, childorg, relstatic).
-
-element(m, menubar, w).
-
-element(ms1, menubarsection, m).
-attribute(ms1, label, "File").
-
-element(ms1i1, menubarsectionitem, ms1).
-attribute(ms1i1, label, "Open").
-element(ms1i2, menubarsectionitem, ms1).
-attribute(ms1i2, label, "Close").
-callback(ms1i2, click, clear).
-
-element(ms2, menubarsection, m).
-element(ms2i2, menubarsectionitem, ms2).
-
-element(c, container, w).
-attribute(c, width, 250).
-attribute(c, height, 150).
-attribute(c, borderwidth, 2).
-attribute(c, onhover, true).
-attribute(c, onhoverbackgroundcolor, blue).
-attribute(c, onhoverbordercolor, red).
-attribute(c, posx, 25).
-attribute(c, posy, 0).
-attribute(c, childorg, absstatic).
-
-element(b, button, c).
-attribute(b, backgroundcolor, blue).
-attribute(b, foregroundcolor, brown).
-attribute(b, label, "Clear!").
-attribute(b, onhover, true).
-attribute(b, onhoverbackgroundcolor, gray).
-attribute(b, onhoverforegroundcolor, beige).
-attribute(b, fontsize, 15).
-callback(b, click, clear).
-
-element(c2, container, w).
-attribute(c2, width, 180).
-attribute(c2, height, 180).
-attribute(c2, borderwidth, 2).
-attribute(c2, onhover, true).
-attribute(c2, onhoverbackgroundcolor, blue).
-attribute(c2, onhoverbordercolor, red).
-attribute(c2, posx, 25).
-attribute(c2, posy, 50).
-attribute(c2, childorg, grid).
-
-element(c20, container, c2).
-attribute(c20, width, 120).
-attribute(c20, height, 60).
-attribute(c20, backgroundcolor, "#fff000000").
-attribute(c20, gridcolumn, 0).
-attribute(c20, gridrow, 0).
-attribute(c20, gridcolumnspan, 2).
-attribute(c20, gridrowspan, 1).
-
-element(c21, container, c2).
-attribute(c21, width, 60).
-attribute(c21, height, 120).
-attribute(c21, backgroundcolor, "#000fff000").
-attribute(c21, gridcolumn, 2).
-attribute(c21, gridrow, 0).
-attribute(c21, gridcolumnspan, 1).
-attribute(c21, gridrowspan, 2).
-
-element(c22, container, c2).
-attribute(c22, width, 60).
-attribute(c22, height, 120).
-attribute(c22, backgroundcolor, "#000000fff").
-attribute(c22, gridcolumn, 0).
-attribute(c22, gridrow, 1).
-attribute(c22, gridcolumnspan, 1).
-attribute(c22, gridrowspan, 2).
-
-element(c23, container, c2).
-attribute(c23, width, 120).
-attribute(c23, height, 60).
-attribute(c23, backgroundcolor, "#999999999").
-attribute(c23, gridcolumn, 1).
-attribute(c23, gridrow, 2).
-attribute(c23, gridcolumnspan, 2).
-attribute(c23, gridrowspan, 1).
-
-element(c24, container, c2).
-attribute(c24, width, 60).
-attribute(c24, height, 60).
-attribute(c24, backgroundcolor, "#000000000").
-attribute(c24, gridcolumn, 1).
-attribute(c24, gridrow, 1).
-attribute(c24, gridcolumnspan, 1).
-attribute(c24, gridrowspan, 1).
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/examples/test_5/widgets.lp b/examples/test_5/widgets.lp
deleted file mode 100644
index 4a6b7c1d..00000000
--- a/examples/test_5/widgets.lp
+++ /dev/null
@@ -1,17 +0,0 @@
-element(w, window, root).
-attribute(w, height, 500).
-attribute(w, width, 500).
-attribute(w, backgroundcolor, white).
-attribute(w, childorg, relstatic).
-
-element(c, container, w).
-attribute(c, height, 250).
-attribute(c, width, 250).
-attribute(c, borderwidth, 2).
-
-attribute(c, bordercolor, "#fff000000").
-attribute(c, backgroundcolor, "#000000000").
-attribute(c, onhover, true).
-attribute(c, onhoverbackgroundcolor, "#666666666").
-attribute(c, onhoverbordercolor, "#000fff000").
-