diff --git a/.DS_Store b/.DS_Store
new file mode 100644
index 0000000000000000000000000000000000000000..58553b0aaa1ab674beb5e5d81bcfa45299c30a6e
Binary files /dev/null and b/.DS_Store differ
diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000000000000000000000000000000000000..413eaf95a4862852a1601d2febfe734b88291219
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,10 @@
+.git/
+.gitignore
+
+**/__pycache__
+.mypy_cache
+.pytest_cache
+*~
+
+*.code-workspace
+.vscode
diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml
new file mode 100644
index 0000000000000000000000000000000000000000..96934b5574c705386e3e71b26cd55f6827351de5
--- /dev/null
+++ b/.github/workflows/docker-image.yml
@@ -0,0 +1,33 @@
+name: Docker Image CI
+
+on:
+  push:
+    branches: [ "main" ]
+  pull_request:
+    branches: [ "main" ]
+
+jobs:
+
+  build:
+
+    runs-on: ubuntu-latest
+
+    steps:
+    - uses: actions/checkout@v3
+    -
+      name: Login to Docker Hub
+      uses: docker/login-action@v2
+      with:
+        username: ${{ secrets.DOCKERHUB_USERNAME }}
+        password: ${{ secrets.DOCKERHUB_TOKEN }}
+    -
+      name: Set up Docker Buildx
+      uses: docker/setup-buildx-action@v2
+    -
+      name: Build and push
+      uses: docker/build-push-action@v4
+      with:
+        context: .
+        file: ./Dockerfile
+        push: true
+        tags: ${{ secrets.DOCKERHUB_USERNAME }}/doml-model-checker:latest
diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml
new file mode 100644
index 0000000000000000000000000000000000000000..59eb89be2e3ed040f5303fa138d814bd90fcb4d7
--- /dev/null
+++ b/.github/workflows/docs.yml
@@ -0,0 +1,22 @@
+name: Pages
+on:
+  push:
+    branches:
+    - master
+jobs:
+  build:
+    runs-on: ubuntu-latest
+    steps:
+    - uses: actions/setup-python@v2
+    - uses: actions/checkout@master
+      with:
+        fetch-depth: 0 # otherwise, you will failed to push refs to dest repo
+    - name: Build and Commit
+      uses: sphinx-notes/pages@v2
+      with:
+        requirements_path: ./docs/requirements.txt
+    - name: Push changes
+      uses: ad-m/github-push-action@master
+      with:
+        github_token: ${{ secrets.GITHUB_TOKEN }}
+        branch: gh-pages
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index fc6f6f49ab8833ad839524e8eb13e52b9e1e1043..6769e21d99a63338394e47bc4c7d0aba1e88d5a5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,160 @@
-*~
-*__pycache__*
-.vscode
-docs/_build
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+share/python-wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+MANIFEST
+
+# PyInstaller
+#  Usually these files are written by a python script from a template
+#  before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.nox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*.cover
+*.py,cover
+.hypothesis/
+.pytest_cache/
+cover/
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+local_settings.py
+db.sqlite3
+db.sqlite3-journal
+
+# Flask stuff:
+instance/
+.webassets-cache
+
+# Scrapy stuff:
+.scrapy
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+.pybuilder/
+target/
+
+# Jupyter Notebook
+.ipynb_checkpoints
+
+# IPython
+profile_default/
+ipython_config.py
+
+# pyenv
+#   For a library or package, you might want to ignore these files since the code is
+#   intended to run in multiple environments; otherwise, check them in:
+# .python-version
+
+# pipenv
+#   According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
+#   However, in case of collaboration, if having platform-specific dependencies or dependencies
+#   having no cross-platform support, pipenv may install dependencies that don't work, or not
+#   install all needed dependencies.
+#Pipfile.lock
+
+# poetry
+#   Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
+#   This is especially recommended for binary packages to ensure reproducibility, and is more
+#   commonly ignored for libraries.
+#   https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
+#poetry.lock
+
+# pdm
+#   Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
+#pdm.lock
+#   pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
+#   in version control.
+#   https://pdm.fming.dev/#use-with-ide
+.pdm.toml
+
+# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
+__pypackages__/
+
+# Celery stuff
+celerybeat-schedule
+celerybeat.pid
+
+# SageMath parsed files
+*.sage.py
+
+# Environments
+.env
+.venv
+env/
+venv/
+ENV/
+env.bak/
+venv.bak/
+
+# Spyder project settings
+.spyderproject
+.spyproject
+
+# Rope project settings
+.ropeproject
+
+# mkdocs documentation
+/site
+
+# mypy
+.mypy_cache/
+.dmypy.json
+dmypy.json
+
+# Pyre type checker
+.pyre/
+
+# pytype static type analyzer
+.pytype/
+
+# Cython debug symbols
+cython_debug/
+
+# PyCharm
+#  JetBrains specific template is maintained in a separate JetBrains.gitignore that can
+#  be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
+#  and can be added to the global gitignore or merged into this file.  For a more nuclear
+#  option (not recommended) you can uncomment the following to ignore the entire idea folder.
+#.idea/
\ No newline at end of file
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000000000000000000000000000000000000..ec70a1bd1d504f2770f92b4316a7b016964148c1
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,91 @@
+include:
+  - project: piacere/private/t23-ci-setup
+    ref: main
+    file:
+      - gitlab-ci-scripts/utils.gitlab-ci.yml
+
+      # Image tag variables generation job -------------
+      # Stage: variable-generation ---------------------
+      - gitlab-ci-scripts/generate-variables.gitlab-ci.yml
+      
+      # Downstream t23-ci-setup pipeline trigger job ---
+      # Stage: integration-tests-publish-deploy --------
+      - gitlab-ci-scripts/trigger-downstream.gitlab-ci.yml
+
+variables:
+  # ------------------------
+  # Component image tag data
+  # ------------------------
+  COMPONENT_WP: wp4
+  DMC_IMAGE_NAME: dmc
+
+  # ------------------------------------------
+  # Space-separated component image abbreviation list
+  # used to generate image tags and related variables.
+  # It is also passed to the downstream integration tests,
+  # publication and deployment pipeline
+  # ------------------------------------------
+  IMAGE_NAMES: "$DMC_IMAGE_NAME"
+
+stages:
+  - variable-generation
+  - build
+  - security
+  - functional-tests
+  - integration-tests-publish-deploy
+
+# Build jobs ----------------------
+
+build-temp-dmc:
+  stage: build
+  variables:
+    TMP_IMAGE: "$TMP_IMAGE_DMC"
+    DOCKERFILE_PATH: "."
+  trigger: !reference [.trigger-build]
+  rules:
+    - if: $CI_COMMIT_BRANCH =~ /^y3/
+
+# Security job ------------------------
+
+security-trivy-dmc:
+  stage: security
+  variables:
+    TMP_IMAGE: "$TMP_IMAGE_DMC"
+  trigger: !reference [.trigger-security-trivy]
+  needs:
+    - job: build-temp-dmc
+    - job: generate-variables
+      artifacts: true
+  rules:
+    - if: $CI_COMMIT_BRANCH =~ /^y3/
+
+# functional tests job ------------------------
+
+run-functional-tests:
+  image: $DOCKER_IMAGE
+  stage: functional-tests
+  services:
+    - $DOCKER_DIND_IMAGE
+  variables:
+    TESTS_CONTAINER_NAME: functional-tester
+  before_script:
+    - !reference [.artifactory-login]
+  script:
+    # Tests assume port 8080, while the Dockerfile CMD runs the server on port 80.
+    # Thus, we need to override the command so that the server is run on port 8080.
+    - docker run --name $TESTS_CONTAINER_NAME -d -e "UVICORN_PORT=8080" $TMP_IMAGE_DMC
+    # Install everything required for the tests.
+    - docker exec -i $TESTS_CONTAINER_NAME /bin/bash -c
+        "pip install -r requirements.txt"
+    # Run the tests.
+    - docker exec -i $TESTS_CONTAINER_NAME /bin/bash -c "python -m pytest tests/test_mc_openapi.py -n auto"
+    # Stop the tests container.
+    - docker stop $TESTS_CONTAINER_NAME
+  needs:
+    - job: build-temp-dmc
+    - job: generate-variables
+      artifacts: true
+  tags:
+    - docker
+  rules:
+    - if: $CI_COMMIT_BRANCH =~ /^y3/
diff --git a/.gitlab/issue_templates/issue.md b/.gitlab/issue_templates/issue.md
new file mode 100644
index 0000000000000000000000000000000000000000..c681b7c9a99b18734f7b375e6c530a27cac8142d
--- /dev/null
+++ b/.gitlab/issue_templates/issue.md
@@ -0,0 +1,15 @@
+# Issue Title
+
+- [ ] The model is satisfied when it shouldn't (or viceversa)
+- [ ] There's an issue with the model checker
+- [ ] There's an error with the DOMLR (DSL for requirements) 
+
+## Files
+To investigate your issue, I need:
+- The DOML version you're targeting
+- The PIACERE IDE version you are using
+- A link to DOML model in question
+- The error message (screenshot or copy-n-paste it)
+- Any other information you think it's useful
+
+## Description
diff --git a/.python-version b/.python-version
new file mode 100644
index 0000000000000000000000000000000000000000..cc65e73eb882dcfc036c5cda2f27f06747bb1254
--- /dev/null
+++ b/.python-version
@@ -0,0 +1,2 @@
+piacere-dmc
+3.11.6
\ No newline at end of file
diff --git a/.readthedocs.yaml b/.readthedocs.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..a83fae56dc39d959ba8ba3a020cf158ab586b0bd
--- /dev/null
+++ b/.readthedocs.yaml
@@ -0,0 +1,29 @@
+# .readthedocs.yaml
+# Read the Docs configuration file
+# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
+
+# Required
+version: 2
+
+# Set the version of Python and other tools you might need
+build:
+  os: ubuntu-22.04
+  tools:
+    python: "3.11"
+    # You can also specify other tool versions:
+    # nodejs: "19"
+    # rust: "1.64"
+    # golang: "1.19"
+
+# Build documentation in the docs/ directory with Sphinx
+sphinx:
+   configuration: docs/conf.py
+
+# If using Sphinx, optionally build your docs in additional formats such as PDF
+# formats:
+#    - pdf
+
+# Optionally declare the Python requirements required to build your docs
+python:
+   install:
+   - requirements: docs/requirements.txt
\ No newline at end of file
diff --git a/Dockerfile b/Dockerfile
index 3f83f94a033475b1d6d3596ab5926b41ad973b88..8e20c0bcceab6f848cb5eddc60b28db6a8ee34d1 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,11 +1,14 @@
-FROM python:3.9.12-bullseye
+FROM python:3.11.3-buster AS requirements-stage
 
-COPY . /opt/mc_openapi
+WORKDIR /code
 
-RUN useradd -mU mc
-USER mc
-ENV PATH="/home/mc/.local/bin:${PATH}"
-RUN pip install -r /opt/mc_openapi/requirements.txt
-WORKDIR /opt/mc_openapi
+COPY ./requirements.txt /code/requirements.txt
 
-CMD ["uwsgi", "--http", ":80", "--yaml", "uwsgi_config.yaml"]
+RUN pip install --no-cache-dir --upgrade -r /code/requirements.txt
+
+COPY ./mc_openapi /code/mc_openapi
+COPY ./tests /code/tests
+
+EXPOSE 80
+
+CMD ["uvicorn", "mc_openapi.api:app", "--proxy-headers", "--host", "0.0.0.0", "--port", "80"]
diff --git a/README.md b/README.md
index b70a04893e3328e3681c6954da4fcba190484f13..f98b83f477237d5d7631be8c463b9818d36276c9 100644
--- a/README.md
+++ b/README.md
@@ -1,31 +1,46 @@
-# PIACERE Model Checker REST API server
+# DOML Model Checker
+[![Documentation Status](https://readthedocs.org/projects/piacere-model-checker/badge/?version=latest)](https://piacere-model-checker.readthedocs.io/en/latest/?badge=latest)
 
-This project is packaged with [Poetry](https://python-poetry.org/).
+## Description of the component
 
-## Build and Run
+The DOML Model Checker is a component of the [PIACERE](https://www.piacere-project.eu/) framework in charge of checking the correctness and consistency of [DOML](https://www.piacere-doml.deib.polimi.it/) models.
 
-Build with
+It consists of a web server exposing a REST API that receives a DOML model in XMI format (also called DOMLX) and provides as output a result detailing whether the model satisfies a set of internal requirements, and in case of negative results, what elements are in violation and how to fix the issue.
+
+It also bundles a Cloud Service Provider (CSP) Compatibility tool that can provide the compatibility results of a model against common Cloud Service Providers.
+
+## Installation
+
+### Setup
+
+Activate the Python Virtual Environment with:
 ```sh
-poetry install
+source .venv/bin/activate
 ```
-then run with
+Install the required packages with:
 ```sh
-poetry run python -m mc_openapi
+pip install -r requirements.txt
 ```
 
-Run tests with:
+### Run the model checker web server
 ```sh
-poetry run python -m pytest
+python -m mc_openapi
 ```
 
-## Run with uWSGI
+### Run with Uvicorn
+
+The project may be run with [Uvicorn](https://www.uvicorn.org/) as follows:
+```sh
+uvicorn --port 8080 --host 0.0.0.0 --interface wsgi --workers 2 mc_openapi.app_config:app
+```
+### Run tests
 
-The project may be run with [uWSGI](https://uwsgi-docs.readthedocs.io/) as follows:
+Run tests with:
 ```sh
-uwsgi --http :8080 --yaml uwsgi_config.yaml
+python -m pytest
 ```
 
-## Run with Docker
+### Run with Docker
 
 First, build the docker image with the usual
 ```sh
@@ -35,17 +50,33 @@ And then run it with
 ```sh
 docker run -d wp4/dmc
 ```
-The uWSGI server will be running and listening on port 80 of the container.
+The Uvicorn server will be running and listening on port `8080` of the container.
+To use it locally, you may bind it with port `8080` of `localhost`
+by adding `-p 127.0.0.1:8080:8080/tcp` to the `docker run` command.
+
+## Documentation
+You can read the latest version at [readthedocs.io](https://piacere-model-checker.readthedocs.io/en/latest/)
+
+### Building the Documentation
 
+The documentation has been written in [Sphinx](https://www.sphinx-doc.org/)
+and covers both usage through the PIACERE IDE and the REST APIs.
+
+If you want to build the documentation manually, run:
+```sh
+cd docs
+make html
+```
 
-## REST APIs
+The documentation will be generated in `docs/_build`.
 
-The OpenAPI definition of the REST APIs is in `mc_openapi/openapi/model_checker.yaml`.
+## License
+This work is licensed under the Apache License 2.0.
 
-The APIs can also be browsed with [Swagger UI](https://swagger.io/tools/swagger-ui/) by appending `/ui/` to the API HTTP address.
+## Contact
 
-For APIs usage examples, you may look into the tests, in `tests/test_mc_openapi.py`.
-Two DOML examples in XMI format are sent to the server.
-One of them is correct (`tests/doml/nginx-openstack_v2.domlx`), and the server answers with `"sat"` (meaning the requirements are satisfied), and the other one contains an error (`tests/doml/nginx-openstack_v2_wrong.domlx`), so the server answers with `"unsat"`.
+andrea.franchini@polimi.it
 
-**Note:** for the time being, the `model` field of the POST request's body accepts any XML object. This will be changed to the DOML XMI schema when possible.
+## Acknowledgement
+This project has received funding from the European Union’s Horizon 2020 research and innovation programme under Grant 
+Agreement No. 101000162 (PIACERE).
diff --git a/dev-requirements.txt b/dev-requirements.txt
deleted file mode 100644
index 1c35a4f6033527881ced5891a73e4798e0b5c1ad..0000000000000000000000000000000000000000
--- a/dev-requirements.txt
+++ /dev/null
@@ -1,49 +0,0 @@
-appnope==0.1.3 ; python_version >= "3.9" and python_version < "4.0" and platform_system == "Darwin" or python_version >= "3.9" and python_version < "4.0" and sys_platform == "darwin"
-asttokens==2.0.5 ; python_version >= "3.9" and python_version < "4.0"
-atomicwrites==1.4.1 ; python_version >= "3.9" and python_version < "4.0" and sys_platform == "win32"
-attrs==22.1.0 ; python_version >= "3.9" and python_version < "4.0"
-backcall==0.2.0 ; python_version >= "3.9" and python_version < "4.0"
-certifi==2022.6.15 ; python_version >= "3.9" and python_version < "4"
-cffi==1.15.1 ; python_version >= "3.9" and python_version < "4.0" and implementation_name == "pypy"
-charset-normalizer==2.1.0 ; python_version >= "3.9" and python_version < "4"
-colorama==0.4.5 ; python_version >= "3.9" and python_version < "4.0" and sys_platform == "win32" or python_version >= "3.9" and python_version < "4.0" and platform_system == "Windows"
-colorful==0.5.4 ; python_version >= "3.9" and python_version < "4.0"
-debugpy==1.6.2 ; python_version >= "3.9" and python_version < "4.0"
-decorator==5.1.1 ; python_version >= "3.9" and python_version < "4.0"
-entrypoints==0.4 ; python_version >= "3.9" and python_version < "4.0"
-executing==0.9.1 ; python_version >= "3.9" and python_version < "4.0"
-idna==3.3 ; python_version >= "3.9" and python_version < "4"
-iniconfig==1.1.1 ; python_version >= "3.9" and python_version < "4.0"
-ipykernel==6.15.1 ; python_version >= "3.9" and python_version < "4.0"
-ipython==8.4.0 ; python_version >= "3.9" and python_version < "4.0"
-jedi==0.18.1 ; python_version >= "3.9" and python_version < "4.0"
-jupyter-client==7.3.4 ; python_version >= "3.9" and python_version < "4.0"
-jupyter-core==4.11.1 ; python_version >= "3.9" and python_version < "4.0"
-matplotlib-inline==0.1.3 ; python_version >= "3.9" and python_version < "4.0"
-nest-asyncio==1.5.5 ; python_version >= "3.9" and python_version < "4.0"
-packaging==21.3 ; python_version >= "3.9" and python_version < "4.0"
-parso==0.8.3 ; python_version >= "3.9" and python_version < "4.0"
-pexpect==4.8.0 ; python_version >= "3.9" and python_version < "4.0" and sys_platform != "win32"
-pickleshare==0.7.5 ; python_version >= "3.9" and python_version < "4.0"
-pluggy==1.0.0 ; python_version >= "3.9" and python_version < "4.0"
-prettyprinter==0.18.0 ; python_version >= "3.9" and python_version < "4.0"
-prompt-toolkit==3.0.30 ; python_version >= "3.9" and python_version < "4.0"
-psutil==5.9.1 ; python_version >= "3.9" and python_version < "4.0"
-ptyprocess==0.7.0 ; python_version >= "3.9" and python_version < "4.0" and sys_platform != "win32"
-pure-eval==0.2.2 ; python_version >= "3.9" and python_version < "4.0"
-py==1.11.0 ; python_version >= "3.9" and python_version < "4.0"
-pycparser==2.21 ; python_version >= "3.9" and python_version < "4.0" and implementation_name == "pypy"
-pygments==2.12.0 ; python_version >= "3.9" and python_version < "4.0"
-pyparsing==3.0.9 ; python_version >= "3.9" and python_version < "4.0"
-pytest==6.2.5 ; python_version >= "3.9" and python_version < "4.0"
-python-dateutil==2.8.2 ; python_version >= "3.9" and python_version < "4.0"
-pywin32==304 ; sys_platform == "win32" and platform_python_implementation != "PyPy" and python_version >= "3.9" and python_version < "4.0"
-pyzmq==23.2.0 ; python_version >= "3.9" and python_version < "4.0"
-requests==2.28.1 ; python_version >= "3.9" and python_version < "4"
-six==1.16.0 ; python_version >= "3.9" and python_version < "4.0"
-stack-data==0.3.0 ; python_version >= "3.9" and python_version < "4.0"
-toml==0.10.2 ; python_version >= "3.9" and python_version < "4.0"
-tornado==6.2 ; python_version >= "3.9" and python_version < "4.0"
-traitlets==5.3.0 ; python_version >= "3.9" and python_version < "4.0"
-urllib3==1.26.11 ; python_version >= "3.9" and python_version < "4"
-wcwidth==0.2.5 ; python_version >= "3.9" and python_version < "4.0"
diff --git a/docs/PIACERE_logo.png b/docs/PIACERE_logo.png
new file mode 100644
index 0000000000000000000000000000000000000000..8225ccc44d7c081e988f3de5e93695d155e8a919
Binary files /dev/null and b/docs/PIACERE_logo.png differ
diff --git a/docs/conf.py b/docs/conf.py
index a611a3023e830e145b161e91470bd0da8bcc8e47..eef39638ef132ca57af783eaa43e5d5ca024d8b6 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -13,17 +13,17 @@
 # import os
 # import sys
 # sys.path.insert(0, os.path.abspath('.'))
-import sphinx_rtd_theme
+# import sphinx_rtd_theme
 
 
 # -- Project information -----------------------------------------------------
 
 project = 'DOML Model Checker'
-copyright = '2022, Michele Chiari and Michele De Pascalis'
-author = 'Michele Chiari and Michele De Pascalis'
+copyright = '2022, Michele Chiari, Michele De Pascalis, Andrea Franchini'
+author = 'Michele Chiari, Michele De Pascalis, Andrea Franchini'
 
 # The full version, including alpha/beta/rc tags
-release = '1.0.0'
+release = '2.5.2'
 
 
 # -- General configuration ---------------------------------------------------
@@ -32,7 +32,7 @@ release = '1.0.0'
 # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
 # ones.
 extensions = [
-    'sphinx_rtd_theme'
+    # 'sphinx_rtd_theme'
 ]
 
 # Add any paths that contain templates here, relative to this directory.
@@ -41,7 +41,7 @@ templates_path = []
 # 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']
+exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', 'requirements.txt']
 
 
 # -- Options for HTML output -------------------------------------------------
@@ -49,8 +49,9 @@ exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
 # 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 = 'sphinx_rtd_theme'
+html_theme = 'furo'
+html_logo = "PIACERE_logo.png"
 # 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".
diff --git a/docs/index.rst b/docs/index.rst
index ec8ef513ffa8ae204f1b6e2847034e325e90bd0b..61192c2eafb2647b10f088aee325397520e3676e 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -3,7 +3,7 @@
    You can adapt this file completely to your liking, but it should at least
    contain the root `toctree` directive.
 
-DOML Model Checker's documentation
+DOML Model Checker Documentation
 ==================================
 
 The DOML Model Checker is a component of the `PIACERE`_ framework
@@ -15,9 +15,12 @@ in charge of checking the correctness and consistency of `DOML`_ models.
    :caption: Contents:
 
    installation
+   tests
    usage
+   writing-requirements
    requirements
    restapis
+   reference_index
 
 ..
    Indices and tables
@@ -28,8 +31,8 @@ in charge of checking the correctness and consistency of `DOML`_ models.
    * :ref:`search`
 
 
-This project has received funding from the European Union's Horizon 2020
-research and innovation programme under grant agreement No. 101000162.
+*This project has received funding from the European Union's Horizon 2020
+research and innovation programme under grant agreement No. 101000162.*
 
 
 .. _PIACERE: https://www.piacere-project.eu/
diff --git a/docs/installation.rst b/docs/installation.rst
index 623056d937437b2dec0c519733f80da9d76fad28..b06dcae153e8cc0fdcc77c563b58a112b26649b0 100644
--- a/docs/installation.rst
+++ b/docs/installation.rst
@@ -1,44 +1,46 @@
 Installation
-============
+************
 
-The DOML Model Checker receives user inputs through its REST APIs.
-In this guide we illuestrate saveral ways of setting up the server for these APIs.
+The model checker can be run in two configurations, *REST API* and *CLI*.
 
+First, you'll need to install the dependencies to run this tool.
 
-Build and run locally for testing
----------------------------------
+Installing the dependencies
+===========================
+1. Clone/download the model checker repository.
 
-This project is packaged with `Poetry`_, which we assume you have already
-`installed <https://python-poetry.org/docs/#installation>`_ into your system.
+2. Setting up a Python virtual environment is recommended. You can run the following command to create it::
 
+    python -m venv .venv
 
-Build with::
+    # Remember to activate it! e.g.:
+    source .venv/bin/activate
+  
+3. Install the dependencies with::
 
-  poetry install
+    pip install -r requirements.txt
 
-then run with::
+Run locally for testing
+-----------------------
+Run with::
 
-  poetry run python -m mc_openapi
+  python -m mc_openapi
 
-this command serves the APIs through a `Flask`_ instance,
+This command serves the APIs through a `Flask`_ instance,
 which is suitable for testing, but not recommended for production.
-You may read the API specification generated by `Swagger-UI`_ by
-pointing your browser to http://127.0.0.1:8080/ui/.
 
+Run locally with Uvicorn
+------------------------
 
-Then, run tests with::
-
-  poetry run python -m pytest
-
-
-Run locally with uWSGI
-----------------------
-
-The project may be run with `uWSGI`_,
+The project may be run with `Uvicorn`_,
 which is better-suited for production environments, as follows::
 
-  uwsgi --http :8080 -w mc_openapi.app_config -p 4
+  uvicorn --port 8080 --host 0.0.0.0 --interface wsgi --workers 2 mc_openapi.app_config:app
 
+You may also configure Uvicorn using environment variables
+with the prefix ``UVICORN_``.
+For example, if you want to run the server with 4 workers,
+set the environment variable ``UVICORN_WORKERS`` to ``4``.
 
 Run with Docker
 ---------------
@@ -53,19 +55,21 @@ And then run it with::
 
   docker run -d wp4/dmc
 
-The uWSGI server will be running and listening on port 80 of the container.
+The Uvicorn server will be running and listening on port 80 of the container.
+To use it locally, you may e.g. bind it with port 8080 of ``localhost``
+by adding ``-p 127.0.0.1:8080:80/tcp`` to the ``docker run`` command.
 
+REST API Endpoints
+==================
+
+You may read the API specification generated by `Swagger-UI`_ at http://127.0.0.1:8080/ui/.
 
 Building the Documentation
---------------------------
+==========================
 
 The documentation has been written in `Sphinx`_.
 
-To build it, type::
-
-  poetry shell
-
-and then::
+To build it manually, run::
 
   cd docs
   make html
@@ -73,9 +77,8 @@ and then::
 The documentation will be generated in ``docs/_build``.
 
 
-.. _Poetry: https://python-poetry.org/
 .. _Flask: https://flask.palletsprojects.com/
 .. _Swagger-UI: https://swagger.io/tools/swagger-ui/
-.. _uWSGI: https://uwsgi-docs.readthedocs.io/
+.. _Uvicorn: https://www.uvicorn.org/
 .. _Docker: https://www.docker.com/
 .. _Sphinx: https://www.sphinx-doc.org/
diff --git a/docs/reference_index.rst b/docs/reference_index.rst
new file mode 100644
index 0000000000000000000000000000000000000000..2d27fe271987ba543e7a96d578911e3e3fe54f89
--- /dev/null
+++ b/docs/reference_index.rst
@@ -0,0 +1,19 @@
+DOML Reference
+==============
+
+For a comprehensive list of all the classes, attributes and associations supported in the DOML Model Checker and DOMLR, please consult one of the following pages.
+
+:doc:`Reference for DOML v2.0 <reference_v2.0>`
+-----------------------------------------------
+:doc:`Reference for DOML v2.1 <reference_v2.1>`
+-----------------------------------------------
+:doc:`Reference for DOML v2.2 <reference_v2.2>`
+-----------------------------------------------
+:doc:`Reference for DOML v2.2.1 <reference_v2.2.1>`
+---------------------------------------------------
+:doc:`Reference for DOML v2.3 <reference_v2.3>`
+-----------------------------------------------
+:doc:`Reference for DOML v3.0 <reference_v3.0>`
+-----------------------------------------------
+:doc:`Reference for DOML v3.1 <reference_v3.1>`
+-----------------------------------------------
diff --git a/docs/reference_v2.0.rst b/docs/reference_v2.0.rst
new file mode 100644
index 0000000000000000000000000000000000000000..5d59dc06766198c6f51eb611511f6ff1b31ad8e3
--- /dev/null
+++ b/docs/reference_v2.0.rst
@@ -0,0 +1,530 @@
+DOML v2.0 Reference
+=============================
+
+
+commons
+^^^^^^^
+
+.. _v2.0_commons_BProperty:
+
+BProperty
+"""""""""
+*Inherits from* :ref:`Property <v2.0_commons_Property>`
+
+* Attributes:
+	* ``value`` [Boolean]
+
+.. _v2.0_commons_Configuration:
+
+Configuration
+"""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.0_commons_DOMLElement>`
+
+* Associations:
+	* ``deployments`` → Deployment [0..*]
+
+.. _v2.0_commons_DOMLElement:
+
+DOMLElement
+"""""""""""
+* Associations:
+	* ``annotations`` → Property [0..*]
+* Attributes:
+	* ``name`` [String]
+	* ``description`` [String]
+
+.. _v2.0_commons_Deployment:
+
+Deployment
+""""""""""
+* Associations:
+	* ``component`` → ApplicationComponent [1..1]
+	* ``node`` → InfrastructureElement [1..1]
+
+.. _v2.0_commons_FProperty:
+
+FProperty
+"""""""""
+*Inherits from* :ref:`Property <v2.0_commons_Property>`
+
+* Attributes:
+	* ``value`` [String]
+
+.. _v2.0_commons_IProperty:
+
+IProperty
+"""""""""
+*Inherits from* :ref:`Property <v2.0_commons_Property>`
+
+* Attributes:
+	* ``value`` [Integer]
+
+.. _v2.0_commons_Property:
+
+Property
+""""""""
+* Associations:
+	* ``reference`` → DOMLElement [0..1]
+* Attributes:
+	* ``key`` [String]
+
+.. _v2.0_commons_SProperty:
+
+SProperty
+"""""""""
+*Inherits from* :ref:`Property <v2.0_commons_Property>`
+
+* Attributes:
+	* ``value`` [String]
+
+application
+^^^^^^^^^^^
+
+.. _v2.0_application_ApplicationComponent:
+
+ApplicationComponent
+""""""""""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.0_commons_DOMLElement>`
+
+
+.. _v2.0_application_ApplicationLayer:
+
+ApplicationLayer
+""""""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.0_commons_DOMLElement>`
+
+* Associations:
+	* ``components`` → ApplicationComponent [0..*]
+
+.. _v2.0_application_DBMS:
+
+DBMS
+""""
+*Inherits from* :ref:`SoftwareComponent <v2.0_application_SoftwareComponent>`
+
+
+.. _v2.0_application_SaaS:
+
+SaaS
+""""
+*Inherits from* :ref:`ApplicationComponent <v2.0_application_ApplicationComponent>`
+
+* Associations:
+	* ``exposedInterfaces`` → SoftwareInterface [0..*]
+* Attributes:
+	* ``licenseCost`` [String]
+
+.. _v2.0_application_SaaSDBMS:
+
+SaaSDBMS
+""""""""
+*Inherits from* :ref:`SaaS <v2.0_application_SaaS>`
+
+
+.. _v2.0_application_SoftwareComponent:
+
+SoftwareComponent
+"""""""""""""""""
+*Inherits from* :ref:`ApplicationComponent <v2.0_application_ApplicationComponent>`
+
+* Associations:
+	* ``exposedInterfaces`` → SoftwareInterface [0..*]
+	* ``consumedInterfaces`` → SoftwareInterface [0..*]
+* Attributes:
+	* ``isPersistent`` [Boolean]
+	* ``licenseCost`` [String]
+	* ``configFile`` [String]
+
+.. _v2.0_application_SoftwareInterface:
+
+SoftwareInterface
+"""""""""""""""""
+*Inherits from* :ref:`ApplicationComponent <v2.0_application_ApplicationComponent>`
+
+* Attributes:
+	* ``endPoint`` [String]
+
+infrastructure
+^^^^^^^^^^^^^^
+
+.. _v2.0_infrastructure_AutoScalingGroup:
+
+AutoScalingGroup
+""""""""""""""""
+*Inherits from* :ref:`ComputingGroup <v2.0_infrastructure_ComputingGroup>`
+
+* Associations:
+	* ``machineDefinition`` → VirtualMachine [1..1]
+	* ``deploymentNetwork`` → Network [0..1]
+	* ``securityGroup`` → SecurityGroup [0..1]
+* Attributes:
+	* ``min`` [Integer]
+	* ``max`` [Integer]
+	* ``loadBalancer`` [String]
+
+.. _v2.0_infrastructure_ComputingGroup:
+
+ComputingGroup
+""""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.0_commons_DOMLElement>`
+
+* Associations:
+	* ``groupedNodes`` → ComputingNode [0..*]
+
+.. _v2.0_infrastructure_ComputingNode:
+
+ComputingNode
+"""""""""""""
+*Inherits from* :ref:`InfrastructureElement <v2.0_infrastructure_InfrastructureElement>`
+
+* Associations:
+	* ``ifaces`` → NetworkInterface [0..*]
+	* ``location`` → Location [0..1]
+	* ``credentials`` → Credentials [0..1]
+	* ``group`` → ComputingGroup [0..1]
+* Attributes:
+	* ``architecture`` [String]
+	* ``os`` [String]
+	* ``memory_mb`` [Integer]
+	* ``memory_kb`` [Integer]
+	* ``storage`` [String]
+	* ``cpu_count`` [Integer]
+	* ``cost`` [Integer]
+
+.. _v2.0_infrastructure_ComputingNodeGenerator:
+
+ComputingNodeGenerator
+""""""""""""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.0_commons_DOMLElement>`
+
+* Attributes:
+	* ``uri`` [String]
+	* ``kind`` [GeneratorKind]
+
+.. _v2.0_infrastructure_Container:
+
+Container
+"""""""""
+*Inherits from* :ref:`ComputingNode <v2.0_infrastructure_ComputingNode>`
+
+* Associations:
+	* ``generatedFrom`` → ContainerImage [0..1]
+	* ``hosts`` → ComputingNode [0..*]
+
+.. _v2.0_infrastructure_ContainerImage:
+
+ContainerImage
+""""""""""""""
+*Inherits from* :ref:`ComputingNodeGenerator <v2.0_infrastructure_ComputingNodeGenerator>`
+
+* Associations:
+	* ``generatedContainers`` → Container [0..*]
+
+.. _v2.0_infrastructure_Credentials:
+
+Credentials
+"""""""""""
+*Inherits from* :ref:`DOMLElement <v2.0_commons_DOMLElement>`
+
+
+.. _v2.0_infrastructure_ExtInfrastructureElement:
+
+ExtInfrastructureElement
+""""""""""""""""""""""""
+*Inherits from* :ref:`InfrastructureElement <v2.0_infrastructure_InfrastructureElement>`
+
+
+.. _v2.0_infrastructure_FunctionAsAService:
+
+FunctionAsAService
+""""""""""""""""""
+*Inherits from* :ref:`InfrastructureElement <v2.0_infrastructure_InfrastructureElement>`
+
+* Associations:
+	* ``ifaces`` → NetworkInterface [0..*]
+* Attributes:
+	* ``cost`` [Integer]
+
+.. _v2.0_infrastructure_InfrastructureElement:
+
+InfrastructureElement
+"""""""""""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.0_commons_DOMLElement>`
+
+
+.. _v2.0_infrastructure_InfrastructureLayer:
+
+InfrastructureLayer
+"""""""""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.0_commons_DOMLElement>`
+
+* Associations:
+	* ``nodes`` → ComputingNode [0..*]
+	* ``generators`` → ComputingNodeGenerator [0..*]
+	* ``storages`` → Storage [0..*]
+	* ``faas`` → FunctionAsAService [0..*]
+	* ``credentials`` → Credentials [0..*]
+	* ``groups`` → ComputingGroup [0..*]
+	* ``securityGroups`` → SecurityGroup [0..*]
+	* ``networks`` → Network [0..*]
+
+.. _v2.0_infrastructure_InternetGateway:
+
+InternetGateway
+"""""""""""""""
+*Inherits from* :ref:`NetworkInterface <v2.0_infrastructure_NetworkInterface>`
+
+
+.. _v2.0_infrastructure_KeyPair:
+
+KeyPair
+"""""""
+*Inherits from* :ref:`Credentials <v2.0_infrastructure_Credentials>`
+
+* Attributes:
+	* ``user`` [String]
+	* ``keyfile`` [String]
+	* ``algorithm`` [String]
+	* ``bits`` [Integer]
+
+.. _v2.0_infrastructure_Location:
+
+Location
+""""""""
+*Inherits from* :ref:`DOMLElement <v2.0_commons_DOMLElement>`
+
+* Attributes:
+	* ``region`` [String]
+	* ``zone`` [String]
+
+.. _v2.0_infrastructure_Network:
+
+Network
+"""""""
+*Inherits from* :ref:`DOMLElement <v2.0_commons_DOMLElement>`
+
+* Associations:
+	* ``connectedIfaces`` → NetworkInterface [0..*]
+	* ``igws`` → InternetGateway [0..*]
+	* ``subnets`` → Subnet [0..*]
+* Attributes:
+	* ``protocol`` [String]
+	* ``address_lb`` [Integer]
+	* ``address_ub`` [Integer]
+
+.. _v2.0_infrastructure_NetworkInterface:
+
+NetworkInterface
+""""""""""""""""
+*Inherits from* :ref:`InfrastructureElement <v2.0_infrastructure_InfrastructureElement>`
+
+* Associations:
+	* ``belongsTo`` → Network [0..1]
+	* ``associated`` → SecurityGroup [0..1]
+* Attributes:
+	* ``endPoint`` [Integer]
+	* ``speed`` [String]
+
+.. _v2.0_infrastructure_PhysicalComputingNode:
+
+PhysicalComputingNode
+"""""""""""""""""""""
+*Inherits from* :ref:`ComputingNode <v2.0_infrastructure_ComputingNode>`
+
+
+.. _v2.0_infrastructure_Rule:
+
+Rule
+""""
+*Inherits from* :ref:`DOMLElement <v2.0_commons_DOMLElement>`
+
+* Attributes:
+	* ``kind`` [String]
+	* ``protocol`` [String]
+	* ``fromPort`` [Integer]
+	* ``toPort`` [Integer]
+	* ``cidr`` [String]
+
+.. _v2.0_infrastructure_SecurityGroup:
+
+SecurityGroup
+"""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.0_commons_DOMLElement>`
+
+* Associations:
+	* ``rules`` → Rule [0..*]
+	* ``ifaces`` → NetworkInterface [0..*]
+
+.. _v2.0_infrastructure_Storage:
+
+Storage
+"""""""
+*Inherits from* :ref:`InfrastructureElement <v2.0_infrastructure_InfrastructureElement>`
+
+* Associations:
+	* ``ifaces`` → NetworkInterface [0..*]
+* Attributes:
+	* ``label`` [String]
+	* ``size_gb`` [Integer]
+	* ``cost`` [Integer]
+
+.. _v2.0_infrastructure_Subnet:
+
+Subnet
+""""""
+*Inherits from* :ref:`Network <v2.0_infrastructure_Network>`
+
+* Associations:
+	* ``connectedTo`` → Network [0..1]
+
+.. _v2.0_infrastructure_Swarm:
+
+Swarm
+"""""
+*Inherits from* :ref:`ComputingGroup <v2.0_infrastructure_ComputingGroup>`
+
+* Associations:
+	* ``roles`` → SwarmRole [0..*]
+
+.. _v2.0_infrastructure_SwarmRole:
+
+SwarmRole
+"""""""""
+*Inherits from* :ref:`DOMLElement <v2.0_commons_DOMLElement>`
+
+* Associations:
+	* ``nodes`` → ComputingNode [0..*]
+* Attributes:
+	* ``kind`` [String]
+
+.. _v2.0_infrastructure_UserPass:
+
+UserPass
+""""""""
+*Inherits from* :ref:`Credentials <v2.0_infrastructure_Credentials>`
+
+* Attributes:
+	* ``username`` [String]
+	* ``password`` [String]
+
+.. _v2.0_infrastructure_VMImage:
+
+VMImage
+"""""""
+*Inherits from* :ref:`ComputingNodeGenerator <v2.0_infrastructure_ComputingNodeGenerator>`
+
+* Associations:
+	* ``generatedVMs`` → VirtualMachine [0..*]
+
+.. _v2.0_infrastructure_VirtualMachine:
+
+VirtualMachine
+""""""""""""""
+*Inherits from* :ref:`ComputingNode <v2.0_infrastructure_ComputingNode>`
+
+* Associations:
+	* ``generatedFrom`` → VMImage [0..1]
+* Attributes:
+	* ``sizeDescription`` [String]
+
+concrete
+^^^^^^^^
+
+.. _v2.0_concrete_ComputingGroup:
+
+ComputingGroup
+""""""""""""""
+*Inherits from* :ref:`ConcreteElement <v2.0_concrete_ConcreteElement>`
+
+* Associations:
+	* ``maps`` → ComputingGroup [1..1]
+
+.. _v2.0_concrete_ConcreteElement:
+
+ConcreteElement
+"""""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.0_commons_DOMLElement>`
+
+* Attributes:
+	* ``configurationScript`` [String]
+
+.. _v2.0_concrete_ConcreteInfrastructure:
+
+ConcreteInfrastructure
+""""""""""""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.0_commons_DOMLElement>`
+
+* Associations:
+	* ``providers`` → RuntimeProvider [0..*]
+
+.. _v2.0_concrete_ContainerImage:
+
+ContainerImage
+""""""""""""""
+*Inherits from* :ref:`ConcreteElement <v2.0_concrete_ConcreteElement>`
+
+* Associations:
+	* ``maps`` → ContainerImage [0..1]
+
+.. _v2.0_concrete_FunctionAsAService:
+
+FunctionAsAService
+""""""""""""""""""
+*Inherits from* :ref:`ConcreteElement <v2.0_concrete_ConcreteElement>`
+
+* Associations:
+	* ``maps`` → FunctionAsAService [0..1]
+
+.. _v2.0_concrete_Network:
+
+Network
+"""""""
+*Inherits from* :ref:`ConcreteElement <v2.0_concrete_ConcreteElement>`
+
+* Associations:
+	* ``maps`` → Network [0..1]
+
+.. _v2.0_concrete_RuntimeProvider:
+
+RuntimeProvider
+"""""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.0_commons_DOMLElement>`
+
+* Associations:
+	* ``vms`` → VirtualMachine [0..*]
+	* ``vmImages`` → VMImage [0..*]
+	* ``containerImages`` → ContainerImage [0..*]
+	* ``networks`` → Network [0..*]
+	* ``storages`` → Storage [0..*]
+	* ``faas`` → FunctionAsAService [0..*]
+	* ``group`` → ComputingGroup [0..*]
+
+.. _v2.0_concrete_Storage:
+
+Storage
+"""""""
+*Inherits from* :ref:`ConcreteElement <v2.0_concrete_ConcreteElement>`
+
+* Associations:
+	* ``maps`` → Storage [0..1]
+
+.. _v2.0_concrete_VMImage:
+
+VMImage
+"""""""
+*Inherits from* :ref:`ConcreteElement <v2.0_concrete_ConcreteElement>`
+
+* Associations:
+	* ``maps`` → VMImage [0..1]
+
+.. _v2.0_concrete_VirtualMachine:
+
+VirtualMachine
+""""""""""""""
+*Inherits from* :ref:`ConcreteElement <v2.0_concrete_ConcreteElement>`
+
+* Associations:
+	* ``maps`` → VirtualMachine [0..1]
+
+
+
diff --git a/docs/reference_v2.1.rst b/docs/reference_v2.1.rst
new file mode 100644
index 0000000000000000000000000000000000000000..ec6b8d8453142bb870d15d7f9f161b382319f832
--- /dev/null
+++ b/docs/reference_v2.1.rst
@@ -0,0 +1,544 @@
+DOML v2.1 Reference
+=============================
+
+
+commons
+^^^^^^^
+
+.. _v2.1_commons_BProperty:
+
+BProperty
+"""""""""
+*Inherits from* :ref:`Property <v2.1_commons_Property>`
+
+* Attributes:
+	* ``value`` [Boolean]
+
+.. _v2.1_commons_Configuration:
+
+Configuration
+"""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.1_commons_DOMLElement>`
+
+* Associations:
+	* ``deployments`` → Deployment [0..*]
+
+.. _v2.1_commons_DOMLElement:
+
+DOMLElement
+"""""""""""
+* Associations:
+	* ``annotations`` → Property [0..*]
+* Attributes:
+	* ``name`` [String]
+	* ``description`` [String]
+
+.. _v2.1_commons_Deployment:
+
+Deployment
+""""""""""
+* Associations:
+	* ``component`` → ApplicationComponent [1..1]
+	* ``node`` → InfrastructureElement [1..1]
+
+.. _v2.1_commons_FProperty:
+
+FProperty
+"""""""""
+*Inherits from* :ref:`Property <v2.1_commons_Property>`
+
+* Attributes:
+	* ``value`` [String]
+
+.. _v2.1_commons_IProperty:
+
+IProperty
+"""""""""
+*Inherits from* :ref:`Property <v2.1_commons_Property>`
+
+* Attributes:
+	* ``value`` [Integer]
+
+.. _v2.1_commons_Property:
+
+Property
+""""""""
+* Associations:
+	* ``reference`` → DOMLElement [0..1]
+* Attributes:
+	* ``key`` [String]
+
+.. _v2.1_commons_SProperty:
+
+SProperty
+"""""""""
+*Inherits from* :ref:`Property <v2.1_commons_Property>`
+
+* Attributes:
+	* ``value`` [String]
+
+application
+^^^^^^^^^^^
+
+.. _v2.1_application_ApplicationComponent:
+
+ApplicationComponent
+""""""""""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.1_commons_DOMLElement>`
+
+
+.. _v2.1_application_ApplicationLayer:
+
+ApplicationLayer
+""""""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.1_commons_DOMLElement>`
+
+* Associations:
+	* ``components`` → ApplicationComponent [0..*]
+
+.. _v2.1_application_DBMS:
+
+DBMS
+""""
+*Inherits from* :ref:`SoftwareComponent <v2.1_application_SoftwareComponent>`
+
+
+.. _v2.1_application_SaaS:
+
+SaaS
+""""
+*Inherits from* :ref:`ApplicationComponent <v2.1_application_ApplicationComponent>`
+
+* Associations:
+	* ``exposedInterfaces`` → SoftwareInterface [0..*]
+* Attributes:
+	* ``licenseCost`` [String]
+
+.. _v2.1_application_SaaSDBMS:
+
+SaaSDBMS
+""""""""
+*Inherits from* :ref:`SaaS <v2.1_application_SaaS>`
+
+
+.. _v2.1_application_SoftwareComponent:
+
+SoftwareComponent
+"""""""""""""""""
+*Inherits from* :ref:`ApplicationComponent <v2.1_application_ApplicationComponent>`
+
+* Associations:
+	* ``exposedInterfaces`` → SoftwareInterface [0..*]
+	* ``consumedInterfaces`` → SoftwareInterface [0..*]
+* Attributes:
+	* ``isPersistent`` [Boolean]
+	* ``licenseCost`` [String]
+	* ``configFile`` [String]
+
+.. _v2.1_application_SoftwareInterface:
+
+SoftwareInterface
+"""""""""""""""""
+*Inherits from* :ref:`ApplicationComponent <v2.1_application_ApplicationComponent>`
+
+* Attributes:
+	* ``endPoint`` [String]
+
+infrastructure
+^^^^^^^^^^^^^^
+
+.. _v2.1_infrastructure_AutoScalingGroup:
+
+AutoScalingGroup
+""""""""""""""""
+*Inherits from* :ref:`ComputingGroup <v2.1_infrastructure_ComputingGroup>`
+
+* Associations:
+	* ``machineDefinition`` → VirtualMachine [1..1]
+	* ``securityGroup`` → SecurityGroup [0..1]
+* Attributes:
+	* ``min`` [Integer]
+	* ``max`` [Integer]
+	* ``loadBalancer`` [String]
+
+.. _v2.1_infrastructure_ComputingGroup:
+
+ComputingGroup
+""""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.1_commons_DOMLElement>`
+
+* Associations:
+	* ``groupedNodes`` → ComputingNode [0..*]
+
+.. _v2.1_infrastructure_ComputingNode:
+
+ComputingNode
+"""""""""""""
+*Inherits from* :ref:`InfrastructureElement <v2.1_infrastructure_InfrastructureElement>`
+
+* Associations:
+	* ``ifaces`` → NetworkInterface [0..*]
+	* ``location`` → Location [0..1]
+	* ``credentials`` → Credentials [0..1]
+	* ``group`` → ComputingGroup [0..1]
+* Attributes:
+	* ``architecture`` [String]
+	* ``os`` [String]
+	* ``memory_mb`` [Integer]
+	* ``memory_kb`` [Integer]
+	* ``storage`` [String]
+	* ``cpu_count`` [Integer]
+	* ``cost`` [Integer]
+
+.. _v2.1_infrastructure_ComputingNodeGenerator:
+
+ComputingNodeGenerator
+""""""""""""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.1_commons_DOMLElement>`
+
+* Attributes:
+	* ``uri`` [String]
+	* ``kind`` [GeneratorKind]
+
+.. _v2.1_infrastructure_Container:
+
+Container
+"""""""""
+*Inherits from* :ref:`ComputingNode <v2.1_infrastructure_ComputingNode>`
+
+* Associations:
+	* ``generatedFrom`` → ContainerImage [0..1]
+	* ``configs`` → ContainerConfig [0..*]
+
+.. _v2.1_infrastructure_ContainerConfig:
+
+ContainerConfig
+"""""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.1_commons_DOMLElement>`
+
+* Associations:
+	* ``host`` → ComputingNode [0..1]
+	* ``iface`` → NetworkInterface [0..1]
+* Attributes:
+	* ``container_port`` [Integer]
+	* ``vm_port`` [Integer]
+
+.. _v2.1_infrastructure_ContainerImage:
+
+ContainerImage
+""""""""""""""
+*Inherits from* :ref:`ComputingNodeGenerator <v2.1_infrastructure_ComputingNodeGenerator>`
+
+* Associations:
+	* ``generatedContainers`` → Container [0..*]
+
+.. _v2.1_infrastructure_Credentials:
+
+Credentials
+"""""""""""
+*Inherits from* :ref:`DOMLElement <v2.1_commons_DOMLElement>`
+
+
+.. _v2.1_infrastructure_ExtInfrastructureElement:
+
+ExtInfrastructureElement
+""""""""""""""""""""""""
+*Inherits from* :ref:`InfrastructureElement <v2.1_infrastructure_InfrastructureElement>`
+
+
+.. _v2.1_infrastructure_FunctionAsAService:
+
+FunctionAsAService
+""""""""""""""""""
+*Inherits from* :ref:`InfrastructureElement <v2.1_infrastructure_InfrastructureElement>`
+
+* Associations:
+	* ``ifaces`` → NetworkInterface [0..*]
+* Attributes:
+	* ``cost`` [Integer]
+
+.. _v2.1_infrastructure_InfrastructureElement:
+
+InfrastructureElement
+"""""""""""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.1_commons_DOMLElement>`
+
+
+.. _v2.1_infrastructure_InfrastructureLayer:
+
+InfrastructureLayer
+"""""""""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.1_commons_DOMLElement>`
+
+* Associations:
+	* ``nodes`` → ComputingNode [0..*]
+	* ``generators`` → ComputingNodeGenerator [0..*]
+	* ``storages`` → Storage [0..*]
+	* ``faas`` → FunctionAsAService [0..*]
+	* ``credentials`` → Credentials [0..*]
+	* ``groups`` → ComputingGroup [0..*]
+	* ``securityGroups`` → SecurityGroup [0..*]
+	* ``networks`` → Network [0..*]
+
+.. _v2.1_infrastructure_InternetGateway:
+
+InternetGateway
+"""""""""""""""
+*Inherits from* :ref:`NetworkInterface <v2.1_infrastructure_NetworkInterface>`
+
+
+.. _v2.1_infrastructure_KeyPair:
+
+KeyPair
+"""""""
+*Inherits from* :ref:`Credentials <v2.1_infrastructure_Credentials>`
+
+* Attributes:
+	* ``user`` [String]
+	* ``keyfile`` [String]
+	* ``algorithm`` [String]
+	* ``bits`` [Integer]
+
+.. _v2.1_infrastructure_Location:
+
+Location
+""""""""
+*Inherits from* :ref:`DOMLElement <v2.1_commons_DOMLElement>`
+
+* Attributes:
+	* ``region`` [String]
+	* ``zone`` [String]
+
+.. _v2.1_infrastructure_Network:
+
+Network
+"""""""
+*Inherits from* :ref:`DOMLElement <v2.1_commons_DOMLElement>`
+
+* Associations:
+	* ``connectedIfaces`` → NetworkInterface [0..*]
+	* ``igws`` → InternetGateway [0..*]
+	* ``subnets`` → Subnet [0..*]
+* Attributes:
+	* ``protocol`` [String]
+	* ``addressRange`` [String]
+	* ``cidr`` [Integer]
+
+.. _v2.1_infrastructure_NetworkInterface:
+
+NetworkInterface
+""""""""""""""""
+*Inherits from* :ref:`InfrastructureElement <v2.1_infrastructure_InfrastructureElement>`
+
+* Associations:
+	* ``belongsTo`` → Network [0..1]
+	* ``associated`` → SecurityGroup [0..1]
+* Attributes:
+	* ``endPoint`` [Integer]
+	* ``speed`` [String]
+
+.. _v2.1_infrastructure_PhysicalComputingNode:
+
+PhysicalComputingNode
+"""""""""""""""""""""
+*Inherits from* :ref:`ComputingNode <v2.1_infrastructure_ComputingNode>`
+
+
+.. _v2.1_infrastructure_Rule:
+
+Rule
+""""
+*Inherits from* :ref:`DOMLElement <v2.1_commons_DOMLElement>`
+
+* Attributes:
+	* ``kind`` [String]
+	* ``protocol`` [String]
+	* ``fromPort`` [Integer]
+	* ``toPort`` [Integer]
+	* ``cidr`` [String]
+
+.. _v2.1_infrastructure_SecurityGroup:
+
+SecurityGroup
+"""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.1_commons_DOMLElement>`
+
+* Associations:
+	* ``rules`` → Rule [0..*]
+	* ``ifaces`` → NetworkInterface [0..*]
+
+.. _v2.1_infrastructure_Storage:
+
+Storage
+"""""""
+*Inherits from* :ref:`InfrastructureElement <v2.1_infrastructure_InfrastructureElement>`
+
+* Associations:
+	* ``ifaces`` → NetworkInterface [0..*]
+* Attributes:
+	* ``label`` [String]
+	* ``size_gb`` [Integer]
+	* ``cost`` [Integer]
+
+.. _v2.1_infrastructure_Subnet:
+
+Subnet
+""""""
+*Inherits from* :ref:`Network <v2.1_infrastructure_Network>`
+
+* Associations:
+	* ``connectedTo`` → Network [0..1]
+
+.. _v2.1_infrastructure_Swarm:
+
+Swarm
+"""""
+*Inherits from* :ref:`ComputingGroup <v2.1_infrastructure_ComputingGroup>`
+
+* Associations:
+	* ``roles`` → SwarmRole [0..*]
+
+.. _v2.1_infrastructure_SwarmRole:
+
+SwarmRole
+"""""""""
+*Inherits from* :ref:`DOMLElement <v2.1_commons_DOMLElement>`
+
+* Associations:
+	* ``nodes`` → ComputingNode [0..*]
+* Attributes:
+	* ``kind`` [String]
+
+.. _v2.1_infrastructure_UserPass:
+
+UserPass
+""""""""
+*Inherits from* :ref:`Credentials <v2.1_infrastructure_Credentials>`
+
+* Attributes:
+	* ``username`` [String]
+	* ``password`` [String]
+
+.. _v2.1_infrastructure_VMImage:
+
+VMImage
+"""""""
+*Inherits from* :ref:`ComputingNodeGenerator <v2.1_infrastructure_ComputingNodeGenerator>`
+
+* Associations:
+	* ``generatedVMs`` → VirtualMachine [0..*]
+
+.. _v2.1_infrastructure_VirtualMachine:
+
+VirtualMachine
+""""""""""""""
+*Inherits from* :ref:`ComputingNode <v2.1_infrastructure_ComputingNode>`
+
+* Associations:
+	* ``generatedFrom`` → VMImage [0..1]
+* Attributes:
+	* ``sizeDescription`` [String]
+
+concrete
+^^^^^^^^
+
+.. _v2.1_concrete_ComputingGroup:
+
+ComputingGroup
+""""""""""""""
+*Inherits from* :ref:`ConcreteElement <v2.1_concrete_ConcreteElement>`
+
+* Associations:
+	* ``maps`` → ComputingGroup [1..1]
+
+.. _v2.1_concrete_ConcreteElement:
+
+ConcreteElement
+"""""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.1_commons_DOMLElement>`
+
+* Attributes:
+	* ``configurationScript`` [String]
+
+.. _v2.1_concrete_ConcreteInfrastructure:
+
+ConcreteInfrastructure
+""""""""""""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.1_commons_DOMLElement>`
+
+* Associations:
+	* ``providers`` → RuntimeProvider [0..*]
+
+.. _v2.1_concrete_ContainerImage:
+
+ContainerImage
+""""""""""""""
+*Inherits from* :ref:`ConcreteElement <v2.1_concrete_ConcreteElement>`
+
+* Associations:
+	* ``maps`` → ContainerImage [0..1]
+
+.. _v2.1_concrete_FunctionAsAService:
+
+FunctionAsAService
+""""""""""""""""""
+*Inherits from* :ref:`ConcreteElement <v2.1_concrete_ConcreteElement>`
+
+* Associations:
+	* ``maps`` → FunctionAsAService [0..1]
+
+.. _v2.1_concrete_Network:
+
+Network
+"""""""
+*Inherits from* :ref:`ConcreteElement <v2.1_concrete_ConcreteElement>`
+
+* Associations:
+	* ``maps`` → Network [0..1]
+* Attributes:
+	* ``address`` [Integer]
+
+.. _v2.1_concrete_RuntimeProvider:
+
+RuntimeProvider
+"""""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.1_commons_DOMLElement>`
+
+* Associations:
+	* ``vms`` → VirtualMachine [0..*]
+	* ``vmImages`` → VMImage [0..*]
+	* ``containerImages`` → ContainerImage [0..*]
+	* ``networks`` → Network [0..*]
+	* ``storages`` → Storage [0..*]
+	* ``faas`` → FunctionAsAService [0..*]
+	* ``group`` → ComputingGroup [0..*]
+
+.. _v2.1_concrete_Storage:
+
+Storage
+"""""""
+*Inherits from* :ref:`ConcreteElement <v2.1_concrete_ConcreteElement>`
+
+* Associations:
+	* ``maps`` → Storage [0..1]
+
+.. _v2.1_concrete_VMImage:
+
+VMImage
+"""""""
+*Inherits from* :ref:`ConcreteElement <v2.1_concrete_ConcreteElement>`
+
+* Associations:
+	* ``maps`` → VMImage [0..1]
+
+.. _v2.1_concrete_VirtualMachine:
+
+VirtualMachine
+""""""""""""""
+*Inherits from* :ref:`ConcreteElement <v2.1_concrete_ConcreteElement>`
+
+* Associations:
+	* ``maps`` → VirtualMachine [0..1]
+
+
+
diff --git a/docs/reference_v2.2.1.rst b/docs/reference_v2.2.1.rst
new file mode 100644
index 0000000000000000000000000000000000000000..3fe713a1e1d66ec784453e6ad46317cd86b6d6ac
--- /dev/null
+++ b/docs/reference_v2.2.1.rst
@@ -0,0 +1,588 @@
+DOML v2.2.1 Reference
+=============================
+
+
+commons
+^^^^^^^
+
+.. _v2.2.1_commons_BProperty:
+
+BProperty
+"""""""""
+*Inherits from* :ref:`Property <v2.2.1_commons_Property>`
+
+* Attributes:
+	* ``value`` [Boolean]
+
+.. _v2.2.1_commons_Configuration:
+
+Configuration
+"""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.2.1_commons_DOMLElement>`
+
+* Associations:
+	* ``deployments`` → Deployment [0..*]
+
+.. _v2.2.1_commons_Credentials:
+
+Credentials
+"""""""""""
+*Inherits from* :ref:`DOMLElement <v2.2.1_commons_DOMLElement>`
+
+
+.. _v2.2.1_commons_DOMLElement:
+
+DOMLElement
+"""""""""""
+* Associations:
+	* ``annotations`` → Property [0..*]
+* Attributes:
+	* ``name`` [String]
+	* ``description`` [String]
+
+.. _v2.2.1_commons_DeployableElement:
+
+DeployableElement
+"""""""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.2.1_commons_DOMLElement>`
+
+
+.. _v2.2.1_commons_Deployment:
+
+Deployment
+""""""""""
+* Associations:
+	* ``component`` → DeployableElement [1..1]
+	* ``node`` → InfrastructureElement [1..1]
+
+.. _v2.2.1_commons_FProperty:
+
+FProperty
+"""""""""
+*Inherits from* :ref:`Property <v2.2.1_commons_Property>`
+
+* Attributes:
+	* ``value`` [String]
+
+.. _v2.2.1_commons_IProperty:
+
+IProperty
+"""""""""
+*Inherits from* :ref:`Property <v2.2.1_commons_Property>`
+
+* Attributes:
+	* ``value`` [Integer]
+
+.. _v2.2.1_commons_KeyPair:
+
+KeyPair
+"""""""
+*Inherits from* :ref:`Credentials <v2.2.1_commons_Credentials>`
+
+* Attributes:
+	* ``user`` [String]
+	* ``keyfile`` [String]
+	* ``algorithm`` [String]
+	* ``bits`` [Integer]
+
+.. _v2.2.1_commons_Property:
+
+Property
+""""""""
+* Associations:
+	* ``reference`` → DOMLElement [0..1]
+* Attributes:
+	* ``key`` [String]
+
+.. _v2.2.1_commons_SProperty:
+
+SProperty
+"""""""""
+*Inherits from* :ref:`Property <v2.2.1_commons_Property>`
+
+* Attributes:
+	* ``value`` [String]
+
+.. _v2.2.1_commons_Source:
+
+Source
+""""""
+*Inherits from* :ref:`DOMLElement <v2.2.1_commons_DOMLElement>`
+
+* Attributes:
+	* ``entry`` [String]
+	* ``backend`` [String]
+
+.. _v2.2.1_commons_UserPass:
+
+UserPass
+""""""""
+*Inherits from* :ref:`Credentials <v2.2.1_commons_Credentials>`
+
+* Attributes:
+	* ``username`` [String]
+	* ``password`` [String]
+
+application
+^^^^^^^^^^^
+
+.. _v2.2.1_application_ApplicationComponent:
+
+ApplicationComponent
+""""""""""""""""""""
+*Inherits from* :ref:`DeployableElement <v2.2.1_commons_DeployableElement>`
+
+
+.. _v2.2.1_application_ApplicationLayer:
+
+ApplicationLayer
+""""""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.2.1_commons_DOMLElement>`
+
+* Associations:
+	* ``components`` → ApplicationComponent [0..*]
+
+.. _v2.2.1_application_DBMS:
+
+DBMS
+""""
+*Inherits from* :ref:`SoftwareComponent <v2.2.1_application_SoftwareComponent>`
+
+
+.. _v2.2.1_application_SaaS:
+
+SaaS
+""""
+*Inherits from* :ref:`ApplicationComponent <v2.2.1_application_ApplicationComponent>`
+
+* Associations:
+	* ``exposedInterfaces`` → SoftwareInterface [0..*]
+* Attributes:
+	* ``licenseCost`` [String]
+
+.. _v2.2.1_application_SaaSDBMS:
+
+SaaSDBMS
+""""""""
+*Inherits from* :ref:`SaaS <v2.2.1_application_SaaS>`
+
+
+.. _v2.2.1_application_SoftwareComponent:
+
+SoftwareComponent
+"""""""""""""""""
+*Inherits from* :ref:`ApplicationComponent <v2.2.1_application_ApplicationComponent>`
+
+* Associations:
+	* ``exposedInterfaces`` → SoftwareInterface [0..*]
+	* ``consumedInterfaces`` → SoftwareInterface [0..*]
+	* ``src`` → Source [0..1]
+* Attributes:
+	* ``isPersistent`` [Boolean]
+	* ``licenseCost`` [String]
+
+.. _v2.2.1_application_SoftwareInterface:
+
+SoftwareInterface
+"""""""""""""""""
+*Inherits from* :ref:`ApplicationComponent <v2.2.1_application_ApplicationComponent>`
+
+* Attributes:
+	* ``endPoint`` [String]
+
+infrastructure
+^^^^^^^^^^^^^^
+
+.. _v2.2.1_infrastructure_AutoScalingGroup:
+
+AutoScalingGroup
+""""""""""""""""
+*Inherits from* :ref:`ComputingGroup <v2.2.1_infrastructure_ComputingGroup>`
+
+* Associations:
+	* ``machineDefinition`` → VirtualMachine [1..1]
+	* ``securityGroup`` → SecurityGroup [0..1]
+* Attributes:
+	* ``min`` [Integer]
+	* ``max`` [Integer]
+	* ``loadBalancer`` [String]
+
+.. _v2.2.1_infrastructure_ComputingGroup:
+
+ComputingGroup
+""""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.2.1_commons_DOMLElement>`
+
+* Associations:
+	* ``groupedNodes`` → ComputingNode [0..*]
+
+.. _v2.2.1_infrastructure_ComputingNode:
+
+ComputingNode
+"""""""""""""
+*Inherits from* :ref:`InfrastructureElement <v2.2.1_infrastructure_InfrastructureElement>`
+
+* Associations:
+	* ``ifaces`` → NetworkInterface [0..*]
+	* ``location`` → Location [0..1]
+	* ``credentials`` → Credentials [0..1]
+	* ``group`` → ComputingGroup [0..1]
+* Attributes:
+	* ``architecture`` [String]
+	* ``os`` [String]
+	* ``memory_mb`` [Integer]
+	* ``memory_kb`` [Integer]
+	* ``storage`` [String]
+	* ``cpu_count`` [Integer]
+	* ``cost`` [Integer]
+	* ``disabledMonitorings`` [String]
+
+.. _v2.2.1_infrastructure_ComputingNodeGenerator:
+
+ComputingNodeGenerator
+""""""""""""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.2.1_commons_DOMLElement>`
+
+* Attributes:
+	* ``uri`` [String]
+	* ``kind`` [GeneratorKind]
+
+.. _v2.2.1_infrastructure_Container:
+
+Container
+"""""""""
+*Inherits from* :ref:`ComputingNode <v2.2.1_infrastructure_ComputingNode>`
+
+* Associations:
+	* ``generatedFrom`` → ContainerImage [0..1]
+	* ``configs`` → ContainerConfig [0..*]
+
+.. _v2.2.1_infrastructure_ContainerConfig:
+
+ContainerConfig
+"""""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.2.1_commons_DOMLElement>`
+
+* Associations:
+	* ``host`` → ComputingNode [0..1]
+	* ``iface`` → NetworkInterface [0..1]
+* Attributes:
+	* ``container_port`` [Integer]
+	* ``vm_port`` [Integer]
+
+.. _v2.2.1_infrastructure_ContainerImage:
+
+ContainerImage
+""""""""""""""
+*Inherits from* :ref:`ComputingNodeGenerator <v2.2.1_infrastructure_ComputingNodeGenerator>`
+
+* Associations:
+	* ``generatedContainers`` → Container [0..*]
+
+.. _v2.2.1_infrastructure_ExtInfrastructureElement:
+
+ExtInfrastructureElement
+""""""""""""""""""""""""
+*Inherits from* :ref:`InfrastructureElement <v2.2.1_infrastructure_InfrastructureElement>`
+
+
+.. _v2.2.1_infrastructure_FunctionAsAService:
+
+FunctionAsAService
+""""""""""""""""""
+*Inherits from* :ref:`InfrastructureElement <v2.2.1_infrastructure_InfrastructureElement>`
+
+* Associations:
+	* ``ifaces`` → NetworkInterface [0..*]
+* Attributes:
+	* ``cost`` [Integer]
+
+.. _v2.2.1_infrastructure_InfrastructureElement:
+
+InfrastructureElement
+"""""""""""""""""""""
+*Inherits from* :ref:`DeployableElement <v2.2.1_commons_DeployableElement>`
+
+
+.. _v2.2.1_infrastructure_InfrastructureLayer:
+
+InfrastructureLayer
+"""""""""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.2.1_commons_DOMLElement>`
+
+* Associations:
+	* ``nodes`` → ComputingNode [0..*]
+	* ``generators`` → ComputingNodeGenerator [0..*]
+	* ``storages`` → Storage [0..*]
+	* ``faas`` → FunctionAsAService [0..*]
+	* ``credentials`` → Credentials [0..*]
+	* ``groups`` → ComputingGroup [0..*]
+	* ``securityGroups`` → SecurityGroup [0..*]
+	* ``networks`` → Network [0..*]
+	* ``rules`` → MonitoringRule [0..*]
+
+.. _v2.2.1_infrastructure_InternetGateway:
+
+InternetGateway
+"""""""""""""""
+*Inherits from* :ref:`NetworkInterface <v2.2.1_infrastructure_NetworkInterface>`
+
+* Attributes:
+	* ``address`` [String]
+
+.. _v2.2.1_infrastructure_Location:
+
+Location
+""""""""
+*Inherits from* :ref:`DOMLElement <v2.2.1_commons_DOMLElement>`
+
+* Attributes:
+	* ``region`` [String]
+	* ``zone`` [String]
+
+.. _v2.2.1_infrastructure_MonitoringRule:
+
+MonitoringRule
+""""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.2.1_commons_DOMLElement>`
+
+* Attributes:
+	* ``condition`` [String]
+	* ``strategy`` [String]
+	* ``strategyConfigurationString`` [String]
+
+.. _v2.2.1_infrastructure_Network:
+
+Network
+"""""""
+*Inherits from* :ref:`DOMLElement <v2.2.1_commons_DOMLElement>`
+
+* Associations:
+	* ``connectedIfaces`` → NetworkInterface [0..*]
+	* ``gateways`` → InternetGateway [0..*]
+	* ``subnets`` → Subnet [0..*]
+* Attributes:
+	* ``protocol`` [String]
+	* ``addressRange`` [String]
+	* ``cidr`` [Integer]
+
+.. _v2.2.1_infrastructure_NetworkInterface:
+
+NetworkInterface
+""""""""""""""""
+*Inherits from* :ref:`InfrastructureElement <v2.2.1_infrastructure_InfrastructureElement>`
+
+* Associations:
+	* ``belongsTo`` → Network [0..1]
+	* ``associated`` → SecurityGroup [0..1]
+* Attributes:
+	* ``endPoint`` [Integer]
+	* ``speed`` [String]
+
+.. _v2.2.1_infrastructure_PhysicalComputingNode:
+
+PhysicalComputingNode
+"""""""""""""""""""""
+*Inherits from* :ref:`ComputingNode <v2.2.1_infrastructure_ComputingNode>`
+
+
+.. _v2.2.1_infrastructure_Rule:
+
+Rule
+""""
+*Inherits from* :ref:`DOMLElement <v2.2.1_commons_DOMLElement>`
+
+* Attributes:
+	* ``kind`` [String]
+	* ``protocol`` [String]
+	* ``fromPort`` [Integer]
+	* ``toPort`` [Integer]
+	* ``cidr`` [String]
+
+.. _v2.2.1_infrastructure_SecurityGroup:
+
+SecurityGroup
+"""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.2.1_commons_DOMLElement>`
+
+* Associations:
+	* ``rules`` → Rule [0..*]
+	* ``ifaces`` → NetworkInterface [0..*]
+
+.. _v2.2.1_infrastructure_Storage:
+
+Storage
+"""""""
+*Inherits from* :ref:`InfrastructureElement <v2.2.1_infrastructure_InfrastructureElement>`
+
+* Associations:
+	* ``ifaces`` → NetworkInterface [0..*]
+* Attributes:
+	* ``label`` [String]
+	* ``size_gb`` [Integer]
+	* ``cost`` [Integer]
+
+.. _v2.2.1_infrastructure_Subnet:
+
+Subnet
+""""""
+*Inherits from* :ref:`Network <v2.2.1_infrastructure_Network>`
+
+* Associations:
+	* ``connectedTo`` → Network [0..*]
+
+.. _v2.2.1_infrastructure_Swarm:
+
+Swarm
+"""""
+*Inherits from* :ref:`ComputingGroup <v2.2.1_infrastructure_ComputingGroup>`
+
+* Associations:
+	* ``roles`` → SwarmRole [0..*]
+
+.. _v2.2.1_infrastructure_SwarmRole:
+
+SwarmRole
+"""""""""
+*Inherits from* :ref:`DOMLElement <v2.2.1_commons_DOMLElement>`
+
+* Associations:
+	* ``nodes`` → ComputingNode [0..*]
+* Attributes:
+	* ``kind`` [String]
+
+.. _v2.2.1_infrastructure_VMImage:
+
+VMImage
+"""""""
+*Inherits from* :ref:`ComputingNodeGenerator <v2.2.1_infrastructure_ComputingNodeGenerator>`
+
+* Associations:
+	* ``generatedVMs`` → VirtualMachine [0..*]
+
+.. _v2.2.1_infrastructure_VirtualMachine:
+
+VirtualMachine
+""""""""""""""
+*Inherits from* :ref:`ComputingNode <v2.2.1_infrastructure_ComputingNode>`
+
+* Associations:
+	* ``generatedFrom`` → VMImage [0..1]
+* Attributes:
+	* ``sizeDescription`` [String]
+
+concrete
+^^^^^^^^
+
+.. _v2.2.1_concrete_ComputingGroup:
+
+ComputingGroup
+""""""""""""""
+*Inherits from* :ref:`ConcreteElement <v2.2.1_concrete_ConcreteElement>`
+
+* Associations:
+	* ``maps`` → ComputingGroup [1..1]
+
+.. _v2.2.1_concrete_ConcreteElement:
+
+ConcreteElement
+"""""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.2.1_commons_DOMLElement>`
+
+* Associations:
+	* ``refs`` → ConcreteElement [0..*]
+* Attributes:
+	* ``configurationScript`` [String]
+	* ``preexisting`` [Boolean]
+
+.. _v2.2.1_concrete_ConcreteInfrastructure:
+
+ConcreteInfrastructure
+""""""""""""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.2.1_commons_DOMLElement>`
+
+* Associations:
+	* ``providers`` → RuntimeProvider [0..*]
+
+.. _v2.2.1_concrete_ContainerImage:
+
+ContainerImage
+""""""""""""""
+*Inherits from* :ref:`ConcreteElement <v2.2.1_concrete_ConcreteElement>`
+
+* Associations:
+	* ``maps`` → ContainerImage [0..1]
+
+.. _v2.2.1_concrete_FunctionAsAService:
+
+FunctionAsAService
+""""""""""""""""""
+*Inherits from* :ref:`ConcreteElement <v2.2.1_concrete_ConcreteElement>`
+
+* Associations:
+	* ``maps`` → FunctionAsAService [0..1]
+
+.. _v2.2.1_concrete_GenericResource:
+
+GenericResource
+"""""""""""""""
+*Inherits from* :ref:`ConcreteElement <v2.2.1_concrete_ConcreteElement>`
+
+* Attributes:
+	* ``type`` [String]
+	* ``gname`` [String]
+
+.. _v2.2.1_concrete_Network:
+
+Network
+"""""""
+*Inherits from* :ref:`ConcreteElement <v2.2.1_concrete_ConcreteElement>`
+
+* Associations:
+	* ``maps`` → Network [0..1]
+
+.. _v2.2.1_concrete_RuntimeProvider:
+
+RuntimeProvider
+"""""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.2.1_commons_DOMLElement>`
+
+* Associations:
+	* ``resources`` → GenericResource [0..*]
+	* ``vms`` → VirtualMachine [0..*]
+	* ``vmImages`` → VMImage [0..*]
+	* ``containerImages`` → ContainerImage [0..*]
+	* ``networks`` → Network [0..*]
+	* ``storages`` → Storage [0..*]
+	* ``faas`` → FunctionAsAService [0..*]
+	* ``group`` → ComputingGroup [0..*]
+
+.. _v2.2.1_concrete_Storage:
+
+Storage
+"""""""
+*Inherits from* :ref:`ConcreteElement <v2.2.1_concrete_ConcreteElement>`
+
+* Associations:
+	* ``maps`` → Storage [0..1]
+
+.. _v2.2.1_concrete_VMImage:
+
+VMImage
+"""""""
+*Inherits from* :ref:`ConcreteElement <v2.2.1_concrete_ConcreteElement>`
+
+* Associations:
+	* ``maps`` → VMImage [0..1]
+
+.. _v2.2.1_concrete_VirtualMachine:
+
+VirtualMachine
+""""""""""""""
+*Inherits from* :ref:`ConcreteElement <v2.2.1_concrete_ConcreteElement>`
+
+* Associations:
+	* ``maps`` → VirtualMachine [0..1]
+
+
+
diff --git a/docs/reference_v2.2.rst b/docs/reference_v2.2.rst
new file mode 100644
index 0000000000000000000000000000000000000000..8fd6ec64526f4792d54f5572a2b670d8afd3122f
--- /dev/null
+++ b/docs/reference_v2.2.rst
@@ -0,0 +1,573 @@
+DOML v2.2 Reference
+=============================
+
+
+commons
+^^^^^^^
+
+.. _v2.2_commons_BProperty:
+
+BProperty
+"""""""""
+*Inherits from* :ref:`Property <v2.2_commons_Property>`
+
+* Attributes:
+	* ``value`` [Boolean]
+
+.. _v2.2_commons_Configuration:
+
+Configuration
+"""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.2_commons_DOMLElement>`
+
+* Associations:
+	* ``deployments`` → Deployment [0..*]
+
+.. _v2.2_commons_Credentials:
+
+Credentials
+"""""""""""
+*Inherits from* :ref:`DOMLElement <v2.2_commons_DOMLElement>`
+
+
+.. _v2.2_commons_DOMLElement:
+
+DOMLElement
+"""""""""""
+* Associations:
+	* ``annotations`` → Property [0..*]
+* Attributes:
+	* ``name`` [String]
+	* ``description`` [String]
+
+.. _v2.2_commons_DeployableElement:
+
+DeployableElement
+"""""""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.2_commons_DOMLElement>`
+
+
+.. _v2.2_commons_Deployment:
+
+Deployment
+""""""""""
+* Associations:
+	* ``component`` → DeployableElement [1..1]
+	* ``node`` → InfrastructureElement [1..1]
+
+.. _v2.2_commons_FProperty:
+
+FProperty
+"""""""""
+*Inherits from* :ref:`Property <v2.2_commons_Property>`
+
+* Attributes:
+	* ``value`` [String]
+
+.. _v2.2_commons_IProperty:
+
+IProperty
+"""""""""
+*Inherits from* :ref:`Property <v2.2_commons_Property>`
+
+* Attributes:
+	* ``value`` [Integer]
+
+.. _v2.2_commons_KeyPair:
+
+KeyPair
+"""""""
+*Inherits from* :ref:`Credentials <v2.2_commons_Credentials>`
+
+* Attributes:
+	* ``user`` [String]
+	* ``keyfile`` [String]
+	* ``algorithm`` [String]
+	* ``bits`` [Integer]
+
+.. _v2.2_commons_Property:
+
+Property
+""""""""
+* Associations:
+	* ``reference`` → DOMLElement [0..1]
+* Attributes:
+	* ``key`` [String]
+
+.. _v2.2_commons_SProperty:
+
+SProperty
+"""""""""
+*Inherits from* :ref:`Property <v2.2_commons_Property>`
+
+* Attributes:
+	* ``value`` [String]
+
+.. _v2.2_commons_Source:
+
+Source
+""""""
+*Inherits from* :ref:`DOMLElement <v2.2_commons_DOMLElement>`
+
+* Attributes:
+	* ``entry`` [String]
+	* ``backend`` [String]
+
+.. _v2.2_commons_UserPass:
+
+UserPass
+""""""""
+*Inherits from* :ref:`Credentials <v2.2_commons_Credentials>`
+
+* Attributes:
+	* ``username`` [String]
+	* ``password`` [String]
+
+application
+^^^^^^^^^^^
+
+.. _v2.2_application_ApplicationComponent:
+
+ApplicationComponent
+""""""""""""""""""""
+*Inherits from* :ref:`DeployableElement <v2.2_commons_DeployableElement>`
+
+
+.. _v2.2_application_ApplicationLayer:
+
+ApplicationLayer
+""""""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.2_commons_DOMLElement>`
+
+* Associations:
+	* ``components`` → ApplicationComponent [0..*]
+
+.. _v2.2_application_DBMS:
+
+DBMS
+""""
+*Inherits from* :ref:`SoftwareComponent <v2.2_application_SoftwareComponent>`
+
+
+.. _v2.2_application_SaaS:
+
+SaaS
+""""
+*Inherits from* :ref:`ApplicationComponent <v2.2_application_ApplicationComponent>`
+
+* Associations:
+	* ``exposedInterfaces`` → SoftwareInterface [0..*]
+* Attributes:
+	* ``licenseCost`` [String]
+
+.. _v2.2_application_SaaSDBMS:
+
+SaaSDBMS
+""""""""
+*Inherits from* :ref:`SaaS <v2.2_application_SaaS>`
+
+
+.. _v2.2_application_SoftwareComponent:
+
+SoftwareComponent
+"""""""""""""""""
+*Inherits from* :ref:`ApplicationComponent <v2.2_application_ApplicationComponent>`
+
+* Associations:
+	* ``exposedInterfaces`` → SoftwareInterface [0..*]
+	* ``consumedInterfaces`` → SoftwareInterface [0..*]
+	* ``src`` → Source [0..1]
+* Attributes:
+	* ``isPersistent`` [Boolean]
+	* ``licenseCost`` [String]
+
+.. _v2.2_application_SoftwareInterface:
+
+SoftwareInterface
+"""""""""""""""""
+*Inherits from* :ref:`ApplicationComponent <v2.2_application_ApplicationComponent>`
+
+* Attributes:
+	* ``endPoint`` [String]
+
+infrastructure
+^^^^^^^^^^^^^^
+
+.. _v2.2_infrastructure_AutoScalingGroup:
+
+AutoScalingGroup
+""""""""""""""""
+*Inherits from* :ref:`ComputingGroup <v2.2_infrastructure_ComputingGroup>`
+
+* Associations:
+	* ``machineDefinition`` → VirtualMachine [1..1]
+	* ``securityGroup`` → SecurityGroup [0..1]
+* Attributes:
+	* ``min`` [Integer]
+	* ``max`` [Integer]
+	* ``loadBalancer`` [String]
+
+.. _v2.2_infrastructure_ComputingGroup:
+
+ComputingGroup
+""""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.2_commons_DOMLElement>`
+
+* Associations:
+	* ``groupedNodes`` → ComputingNode [0..*]
+
+.. _v2.2_infrastructure_ComputingNode:
+
+ComputingNode
+"""""""""""""
+*Inherits from* :ref:`InfrastructureElement <v2.2_infrastructure_InfrastructureElement>`
+
+* Associations:
+	* ``ifaces`` → NetworkInterface [0..*]
+	* ``location`` → Location [0..1]
+	* ``credentials`` → Credentials [0..1]
+	* ``group`` → ComputingGroup [0..1]
+* Attributes:
+	* ``architecture`` [String]
+	* ``os`` [String]
+	* ``memory_mb`` [Integer]
+	* ``memory_kb`` [Integer]
+	* ``storage`` [String]
+	* ``cpu_count`` [Integer]
+	* ``cost`` [Integer]
+	* ``disabledMonitorings`` [String]
+
+.. _v2.2_infrastructure_ComputingNodeGenerator:
+
+ComputingNodeGenerator
+""""""""""""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.2_commons_DOMLElement>`
+
+* Attributes:
+	* ``uri`` [String]
+	* ``kind`` [GeneratorKind]
+
+.. _v2.2_infrastructure_Container:
+
+Container
+"""""""""
+*Inherits from* :ref:`ComputingNode <v2.2_infrastructure_ComputingNode>`
+
+* Associations:
+	* ``generatedFrom`` → ContainerImage [0..1]
+	* ``configs`` → ContainerConfig [0..*]
+
+.. _v2.2_infrastructure_ContainerConfig:
+
+ContainerConfig
+"""""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.2_commons_DOMLElement>`
+
+* Associations:
+	* ``host`` → ComputingNode [0..1]
+	* ``iface`` → NetworkInterface [0..1]
+* Attributes:
+	* ``container_port`` [Integer]
+	* ``vm_port`` [Integer]
+
+.. _v2.2_infrastructure_ContainerImage:
+
+ContainerImage
+""""""""""""""
+*Inherits from* :ref:`ComputingNodeGenerator <v2.2_infrastructure_ComputingNodeGenerator>`
+
+* Associations:
+	* ``generatedContainers`` → Container [0..*]
+
+.. _v2.2_infrastructure_ExtInfrastructureElement:
+
+ExtInfrastructureElement
+""""""""""""""""""""""""
+*Inherits from* :ref:`InfrastructureElement <v2.2_infrastructure_InfrastructureElement>`
+
+
+.. _v2.2_infrastructure_FunctionAsAService:
+
+FunctionAsAService
+""""""""""""""""""
+*Inherits from* :ref:`InfrastructureElement <v2.2_infrastructure_InfrastructureElement>`
+
+* Associations:
+	* ``ifaces`` → NetworkInterface [0..*]
+* Attributes:
+	* ``cost`` [Integer]
+
+.. _v2.2_infrastructure_InfrastructureElement:
+
+InfrastructureElement
+"""""""""""""""""""""
+*Inherits from* :ref:`DeployableElement <v2.2_commons_DeployableElement>`
+
+
+.. _v2.2_infrastructure_InfrastructureLayer:
+
+InfrastructureLayer
+"""""""""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.2_commons_DOMLElement>`
+
+* Associations:
+	* ``nodes`` → ComputingNode [0..*]
+	* ``generators`` → ComputingNodeGenerator [0..*]
+	* ``storages`` → Storage [0..*]
+	* ``faas`` → FunctionAsAService [0..*]
+	* ``credentials`` → Credentials [0..*]
+	* ``groups`` → ComputingGroup [0..*]
+	* ``securityGroups`` → SecurityGroup [0..*]
+	* ``networks`` → Network [0..*]
+	* ``rules`` → MonitoringRule [0..*]
+
+.. _v2.2_infrastructure_InternetGateway:
+
+InternetGateway
+"""""""""""""""
+*Inherits from* :ref:`NetworkInterface <v2.2_infrastructure_NetworkInterface>`
+
+
+.. _v2.2_infrastructure_Location:
+
+Location
+""""""""
+*Inherits from* :ref:`DOMLElement <v2.2_commons_DOMLElement>`
+
+* Attributes:
+	* ``region`` [String]
+	* ``zone`` [String]
+
+.. _v2.2_infrastructure_MonitoringRule:
+
+MonitoringRule
+""""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.2_commons_DOMLElement>`
+
+* Attributes:
+	* ``condition`` [String]
+	* ``strategy`` [String]
+	* ``strategyConfigurationString`` [String]
+
+.. _v2.2_infrastructure_Network:
+
+Network
+"""""""
+*Inherits from* :ref:`DOMLElement <v2.2_commons_DOMLElement>`
+
+* Associations:
+	* ``connectedIfaces`` → NetworkInterface [0..*]
+	* ``igws`` → InternetGateway [0..*]
+	* ``subnets`` → Subnet [0..*]
+* Attributes:
+	* ``protocol`` [String]
+	* ``addressRange`` [String]
+	* ``cidr`` [Integer]
+
+.. _v2.2_infrastructure_NetworkInterface:
+
+NetworkInterface
+""""""""""""""""
+*Inherits from* :ref:`InfrastructureElement <v2.2_infrastructure_InfrastructureElement>`
+
+* Associations:
+	* ``belongsTo`` → Network [0..1]
+	* ``associated`` → SecurityGroup [0..1]
+* Attributes:
+	* ``endPoint`` [Integer]
+	* ``speed`` [String]
+
+.. _v2.2_infrastructure_PhysicalComputingNode:
+
+PhysicalComputingNode
+"""""""""""""""""""""
+*Inherits from* :ref:`ComputingNode <v2.2_infrastructure_ComputingNode>`
+
+
+.. _v2.2_infrastructure_Rule:
+
+Rule
+""""
+*Inherits from* :ref:`DOMLElement <v2.2_commons_DOMLElement>`
+
+* Attributes:
+	* ``kind`` [String]
+	* ``protocol`` [String]
+	* ``fromPort`` [Integer]
+	* ``toPort`` [Integer]
+	* ``cidr`` [String]
+
+.. _v2.2_infrastructure_SecurityGroup:
+
+SecurityGroup
+"""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.2_commons_DOMLElement>`
+
+* Associations:
+	* ``rules`` → Rule [0..*]
+	* ``ifaces`` → NetworkInterface [0..*]
+
+.. _v2.2_infrastructure_Storage:
+
+Storage
+"""""""
+*Inherits from* :ref:`InfrastructureElement <v2.2_infrastructure_InfrastructureElement>`
+
+* Associations:
+	* ``ifaces`` → NetworkInterface [0..*]
+* Attributes:
+	* ``label`` [String]
+	* ``size_gb`` [Integer]
+	* ``cost`` [Integer]
+
+.. _v2.2_infrastructure_Subnet:
+
+Subnet
+""""""
+*Inherits from* :ref:`Network <v2.2_infrastructure_Network>`
+
+* Associations:
+	* ``connectedTo`` → Network [0..*]
+
+.. _v2.2_infrastructure_Swarm:
+
+Swarm
+"""""
+*Inherits from* :ref:`ComputingGroup <v2.2_infrastructure_ComputingGroup>`
+
+* Associations:
+	* ``roles`` → SwarmRole [0..*]
+
+.. _v2.2_infrastructure_SwarmRole:
+
+SwarmRole
+"""""""""
+*Inherits from* :ref:`DOMLElement <v2.2_commons_DOMLElement>`
+
+* Associations:
+	* ``nodes`` → ComputingNode [0..*]
+* Attributes:
+	* ``kind`` [String]
+
+.. _v2.2_infrastructure_VMImage:
+
+VMImage
+"""""""
+*Inherits from* :ref:`ComputingNodeGenerator <v2.2_infrastructure_ComputingNodeGenerator>`
+
+* Associations:
+	* ``generatedVMs`` → VirtualMachine [0..*]
+
+.. _v2.2_infrastructure_VirtualMachine:
+
+VirtualMachine
+""""""""""""""
+*Inherits from* :ref:`ComputingNode <v2.2_infrastructure_ComputingNode>`
+
+* Associations:
+	* ``generatedFrom`` → VMImage [0..1]
+* Attributes:
+	* ``sizeDescription`` [String]
+
+concrete
+^^^^^^^^
+
+.. _v2.2_concrete_ComputingGroup:
+
+ComputingGroup
+""""""""""""""
+*Inherits from* :ref:`ConcreteElement <v2.2_concrete_ConcreteElement>`
+
+* Associations:
+	* ``maps`` → ComputingGroup [1..1]
+
+.. _v2.2_concrete_ConcreteElement:
+
+ConcreteElement
+"""""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.2_commons_DOMLElement>`
+
+* Attributes:
+	* ``configurationScript`` [String]
+	* ``preexisting`` [Boolean]
+
+.. _v2.2_concrete_ConcreteInfrastructure:
+
+ConcreteInfrastructure
+""""""""""""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.2_commons_DOMLElement>`
+
+* Associations:
+	* ``providers`` → RuntimeProvider [0..*]
+
+.. _v2.2_concrete_ContainerImage:
+
+ContainerImage
+""""""""""""""
+*Inherits from* :ref:`ConcreteElement <v2.2_concrete_ConcreteElement>`
+
+* Associations:
+	* ``maps`` → ContainerImage [0..1]
+
+.. _v2.2_concrete_FunctionAsAService:
+
+FunctionAsAService
+""""""""""""""""""
+*Inherits from* :ref:`ConcreteElement <v2.2_concrete_ConcreteElement>`
+
+* Associations:
+	* ``maps`` → FunctionAsAService [0..1]
+
+.. _v2.2_concrete_Network:
+
+Network
+"""""""
+*Inherits from* :ref:`ConcreteElement <v2.2_concrete_ConcreteElement>`
+
+* Associations:
+	* ``maps`` → Network [0..1]
+
+.. _v2.2_concrete_RuntimeProvider:
+
+RuntimeProvider
+"""""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.2_commons_DOMLElement>`
+
+* Associations:
+	* ``vms`` → VirtualMachine [0..*]
+	* ``vmImages`` → VMImage [0..*]
+	* ``containerImages`` → ContainerImage [0..*]
+	* ``networks`` → Network [0..*]
+	* ``storages`` → Storage [0..*]
+	* ``faas`` → FunctionAsAService [0..*]
+	* ``group`` → ComputingGroup [0..*]
+
+.. _v2.2_concrete_Storage:
+
+Storage
+"""""""
+*Inherits from* :ref:`ConcreteElement <v2.2_concrete_ConcreteElement>`
+
+* Associations:
+	* ``maps`` → Storage [0..1]
+
+.. _v2.2_concrete_VMImage:
+
+VMImage
+"""""""
+*Inherits from* :ref:`ConcreteElement <v2.2_concrete_ConcreteElement>`
+
+* Associations:
+	* ``maps`` → VMImage [0..1]
+
+.. _v2.2_concrete_VirtualMachine:
+
+VirtualMachine
+""""""""""""""
+*Inherits from* :ref:`ConcreteElement <v2.2_concrete_ConcreteElement>`
+
+* Associations:
+	* ``maps`` → VirtualMachine [0..1]
+
+
+
diff --git a/docs/reference_v2.3.rst b/docs/reference_v2.3.rst
new file mode 100644
index 0000000000000000000000000000000000000000..bf2031e2447840584c72ed2a4ebe30c73bf740b3
--- /dev/null
+++ b/docs/reference_v2.3.rst
@@ -0,0 +1,594 @@
+DOML v2.3 Reference
+=============================
+
+
+commons
+^^^^^^^
+
+.. _v2.3_commons_BProperty:
+
+BProperty
+"""""""""
+*Inherits from* :ref:`Property <v2.3_commons_Property>`
+
+* Attributes:
+	* ``value`` [Boolean]
+
+.. _v2.3_commons_Configuration:
+
+Configuration
+"""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.3_commons_DOMLElement>`
+
+* Associations:
+	* ``deployments`` → Deployment [0..*]
+
+.. _v2.3_commons_Credentials:
+
+Credentials
+"""""""""""
+*Inherits from* :ref:`DOMLElement <v2.3_commons_DOMLElement>`
+
+
+.. _v2.3_commons_DOMLElement:
+
+DOMLElement
+"""""""""""
+* Associations:
+	* ``annotations`` → Property [0..*]
+* Attributes:
+	* ``name`` [String]
+	* ``description`` [String]
+
+.. _v2.3_commons_DeployableElement:
+
+DeployableElement
+"""""""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.3_commons_DOMLElement>`
+
+
+.. _v2.3_commons_Deployment:
+
+Deployment
+""""""""""
+* Associations:
+	* ``component`` → DeployableElement [1..1]
+	* ``node`` → InfrastructureElement [1..1]
+
+.. _v2.3_commons_FProperty:
+
+FProperty
+"""""""""
+*Inherits from* :ref:`Property <v2.3_commons_Property>`
+
+* Attributes:
+	* ``value`` [String]
+
+.. _v2.3_commons_IProperty:
+
+IProperty
+"""""""""
+*Inherits from* :ref:`Property <v2.3_commons_Property>`
+
+* Attributes:
+	* ``value`` [Integer]
+
+.. _v2.3_commons_KeyPair:
+
+KeyPair
+"""""""
+*Inherits from* :ref:`Credentials <v2.3_commons_Credentials>`
+
+* Attributes:
+	* ``user`` [String]
+	* ``keyfile`` [String]
+	* ``algorithm`` [String]
+	* ``bits`` [Integer]
+
+.. _v2.3_commons_Property:
+
+Property
+""""""""
+* Associations:
+	* ``reference`` → DOMLElement [0..1]
+* Attributes:
+	* ``key`` [String]
+
+.. _v2.3_commons_SProperty:
+
+SProperty
+"""""""""
+*Inherits from* :ref:`Property <v2.3_commons_Property>`
+
+* Attributes:
+	* ``value`` [String]
+
+.. _v2.3_commons_Source:
+
+Source
+""""""
+*Inherits from* :ref:`DOMLElement <v2.3_commons_DOMLElement>`
+
+* Attributes:
+	* ``entry`` [String]
+	* ``backend`` [String]
+
+.. _v2.3_commons_UserPass:
+
+UserPass
+""""""""
+*Inherits from* :ref:`Credentials <v2.3_commons_Credentials>`
+
+* Attributes:
+	* ``username`` [String]
+	* ``password`` [String]
+
+application
+^^^^^^^^^^^
+
+.. _v2.3_application_ApplicationComponent:
+
+ApplicationComponent
+""""""""""""""""""""
+*Inherits from* :ref:`DeployableElement <v2.3_commons_DeployableElement>`
+
+
+.. _v2.3_application_ApplicationLayer:
+
+ApplicationLayer
+""""""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.3_commons_DOMLElement>`
+
+* Associations:
+	* ``components`` → ApplicationComponent [0..*]
+
+.. _v2.3_application_DBMS:
+
+DBMS
+""""
+*Inherits from* :ref:`SoftwareComponent <v2.3_application_SoftwareComponent>`
+
+
+.. _v2.3_application_SaaS:
+
+SaaS
+""""
+*Inherits from* :ref:`ApplicationComponent <v2.3_application_ApplicationComponent>`
+
+* Associations:
+	* ``exposedInterfaces`` → SoftwareInterface [0..*]
+* Attributes:
+	* ``licenseCost`` [String]
+
+.. _v2.3_application_SaaSDBMS:
+
+SaaSDBMS
+""""""""
+*Inherits from* :ref:`SaaS <v2.3_application_SaaS>`
+
+
+.. _v2.3_application_SoftwareComponent:
+
+SoftwareComponent
+"""""""""""""""""
+*Inherits from* :ref:`ApplicationComponent <v2.3_application_ApplicationComponent>`
+
+* Associations:
+	* ``exposedInterfaces`` → SoftwareInterface [0..*]
+	* ``consumedInterfaces`` → SoftwareInterface [0..*]
+	* ``src`` → Source [0..1]
+* Attributes:
+	* ``isPersistent`` [Boolean]
+	* ``licenseCost`` [String]
+
+.. _v2.3_application_SoftwareInterface:
+
+SoftwareInterface
+"""""""""""""""""
+*Inherits from* :ref:`ApplicationComponent <v2.3_application_ApplicationComponent>`
+
+* Attributes:
+	* ``endPoint`` [String]
+
+infrastructure
+^^^^^^^^^^^^^^
+
+.. _v2.3_infrastructure_AutoScalingGroup:
+
+AutoScalingGroup
+""""""""""""""""
+*Inherits from* :ref:`ComputingGroup <v2.3_infrastructure_ComputingGroup>`
+
+* Associations:
+	* ``machineDefinition`` → VirtualMachine [1..1]
+	* ``securityGroup`` → SecurityGroup [0..1]
+* Attributes:
+	* ``min`` [Integer]
+	* ``max`` [Integer]
+	* ``loadBalancer`` [String]
+
+.. _v2.3_infrastructure_ComputingGroup:
+
+ComputingGroup
+""""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.3_commons_DOMLElement>`
+
+* Associations:
+	* ``groupedNodes`` → ComputingNode [0..*]
+
+.. _v2.3_infrastructure_ComputingNode:
+
+ComputingNode
+"""""""""""""
+*Inherits from* :ref:`Node <v2.3_infrastructure_Node>`
+
+* Associations:
+	* ``location`` → Location [0..1]
+	* ``credentials`` → Credentials [0..1]
+	* ``group`` → ComputingGroup [0..1]
+* Attributes:
+	* ``architecture`` [String]
+	* ``os`` [String]
+	* ``memory_mb`` [Integer]
+	* ``memory_kb`` [Integer]
+	* ``storage`` [String]
+	* ``cpu_count`` [Integer]
+	* ``cost`` [Integer]
+	* ``disabledMonitorings`` [String]
+
+.. _v2.3_infrastructure_ComputingNodeGenerator:
+
+ComputingNodeGenerator
+""""""""""""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.3_commons_DOMLElement>`
+
+* Attributes:
+	* ``uri`` [String]
+	* ``kind`` [GeneratorKind]
+
+.. _v2.3_infrastructure_Container:
+
+Container
+"""""""""
+*Inherits from* :ref:`ComputingNode <v2.3_infrastructure_ComputingNode>`
+
+* Associations:
+	* ``generatedFrom`` → ContainerImage [0..1]
+	* ``configs`` → ContainerConfig [0..*]
+
+.. _v2.3_infrastructure_ContainerConfig:
+
+ContainerConfig
+"""""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.3_commons_DOMLElement>`
+
+* Associations:
+	* ``host`` → ComputingNode [0..1]
+	* ``iface`` → NetworkInterface [0..1]
+* Attributes:
+	* ``container_port`` [Integer]
+	* ``vm_port`` [Integer]
+
+.. _v2.3_infrastructure_ContainerImage:
+
+ContainerImage
+""""""""""""""
+*Inherits from* :ref:`ComputingNodeGenerator <v2.3_infrastructure_ComputingNodeGenerator>`
+
+* Associations:
+	* ``generatedContainers`` → Container [0..*]
+
+.. _v2.3_infrastructure_ExtInfrastructureElement:
+
+ExtInfrastructureElement
+""""""""""""""""""""""""
+*Inherits from* :ref:`InfrastructureElement <v2.3_infrastructure_InfrastructureElement>`
+
+
+.. _v2.3_infrastructure_FunctionAsAService:
+
+FunctionAsAService
+""""""""""""""""""
+*Inherits from* :ref:`InfrastructureElement <v2.3_infrastructure_InfrastructureElement>`
+
+* Attributes:
+	* ``cost`` [Integer]
+
+.. _v2.3_infrastructure_InfrastructureElement:
+
+InfrastructureElement
+"""""""""""""""""""""
+*Inherits from* :ref:`DeployableElement <v2.3_commons_DeployableElement>`
+
+
+.. _v2.3_infrastructure_InfrastructureLayer:
+
+InfrastructureLayer
+"""""""""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.3_commons_DOMLElement>`
+
+* Associations:
+	* ``nodes`` → ComputingNode [0..*]
+	* ``generators`` → ComputingNodeGenerator [0..*]
+	* ``storages`` → Storage [0..*]
+	* ``faas`` → FunctionAsAService [0..*]
+	* ``credentials`` → Credentials [0..*]
+	* ``groups`` → ComputingGroup [0..*]
+	* ``securityGroups`` → SecurityGroup [0..*]
+	* ``networks`` → Network [0..*]
+	* ``rules`` → MonitoringRule [0..*]
+
+.. _v2.3_infrastructure_InternetGateway:
+
+InternetGateway
+"""""""""""""""
+*Inherits from* :ref:`Node <v2.3_infrastructure_Node>`
+
+* Attributes:
+	* ``address`` [String]
+
+.. _v2.3_infrastructure_Location:
+
+Location
+""""""""
+*Inherits from* :ref:`DOMLElement <v2.3_commons_DOMLElement>`
+
+* Attributes:
+	* ``region`` [String]
+	* ``zone`` [String]
+
+.. _v2.3_infrastructure_MonitoringRule:
+
+MonitoringRule
+""""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.3_commons_DOMLElement>`
+
+* Attributes:
+	* ``condition`` [String]
+	* ``strategy`` [String]
+	* ``strategyConfigurationString`` [String]
+
+.. _v2.3_infrastructure_Network:
+
+Network
+"""""""
+*Inherits from* :ref:`DOMLElement <v2.3_commons_DOMLElement>`
+
+* Associations:
+	* ``connectedIfaces`` → NetworkInterface [0..*]
+	* ``gateways`` → InternetGateway [0..*]
+	* ``subnets`` → Subnet [0..*]
+* Attributes:
+	* ``protocol`` [String]
+	* ``addressRange`` [String]
+	* ``cidr`` [Integer]
+
+.. _v2.3_infrastructure_NetworkInterface:
+
+NetworkInterface
+""""""""""""""""
+*Inherits from* :ref:`InfrastructureElement <v2.3_infrastructure_InfrastructureElement>`
+
+* Associations:
+	* ``belongsTo`` → Network [0..1]
+	* ``associated`` → SecurityGroup [0..1]
+* Attributes:
+	* ``endPoint`` [Integer]
+	* ``speed`` [String]
+
+.. _v2.3_infrastructure_Node:
+
+Node
+""""
+*Inherits from* :ref:`InfrastructureElement <v2.3_infrastructure_InfrastructureElement>`
+
+* Associations:
+	* ``ifaces`` → NetworkInterface [0..*]
+
+.. _v2.3_infrastructure_PhysicalComputingNode:
+
+PhysicalComputingNode
+"""""""""""""""""""""
+*Inherits from* :ref:`ComputingNode <v2.3_infrastructure_ComputingNode>`
+
+
+.. _v2.3_infrastructure_Rule:
+
+Rule
+""""
+*Inherits from* :ref:`DOMLElement <v2.3_commons_DOMLElement>`
+
+* Attributes:
+	* ``kind`` [String]
+	* ``protocol`` [String]
+	* ``fromPort`` [Integer]
+	* ``toPort`` [Integer]
+	* ``cidr`` [String]
+
+.. _v2.3_infrastructure_SecurityGroup:
+
+SecurityGroup
+"""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.3_commons_DOMLElement>`
+
+* Associations:
+	* ``rules`` → Rule [0..*]
+	* ``ifaces`` → NetworkInterface [0..*]
+
+.. _v2.3_infrastructure_Storage:
+
+Storage
+"""""""
+*Inherits from* :ref:`Node <v2.3_infrastructure_Node>`
+
+* Attributes:
+	* ``label`` [String]
+	* ``size_gb`` [Integer]
+	* ``cost`` [Integer]
+
+.. _v2.3_infrastructure_Subnet:
+
+Subnet
+""""""
+*Inherits from* :ref:`Network <v2.3_infrastructure_Network>`
+
+* Associations:
+	* ``connectedTo`` → Network [0..*]
+
+.. _v2.3_infrastructure_Swarm:
+
+Swarm
+"""""
+*Inherits from* :ref:`ComputingGroup <v2.3_infrastructure_ComputingGroup>`
+
+* Associations:
+	* ``roles`` → SwarmRole [0..*]
+
+.. _v2.3_infrastructure_SwarmRole:
+
+SwarmRole
+"""""""""
+*Inherits from* :ref:`DOMLElement <v2.3_commons_DOMLElement>`
+
+* Associations:
+	* ``nodes`` → ComputingNode [0..*]
+* Attributes:
+	* ``kind`` [String]
+
+.. _v2.3_infrastructure_VMImage:
+
+VMImage
+"""""""
+*Inherits from* :ref:`ComputingNodeGenerator <v2.3_infrastructure_ComputingNodeGenerator>`
+
+* Associations:
+	* ``generatedVMs`` → VirtualMachine [0..*]
+
+.. _v2.3_infrastructure_VirtualMachine:
+
+VirtualMachine
+""""""""""""""
+*Inherits from* :ref:`ComputingNode <v2.3_infrastructure_ComputingNode>`
+
+* Associations:
+	* ``generatedFrom`` → VMImage [0..1]
+* Attributes:
+	* ``sizeDescription`` [String]
+
+concrete
+^^^^^^^^
+
+.. _v2.3_concrete_ComputingGroup:
+
+ComputingGroup
+""""""""""""""
+*Inherits from* :ref:`ConcreteElement <v2.3_concrete_ConcreteElement>`
+
+* Associations:
+	* ``maps`` → ComputingGroup [1..1]
+
+.. _v2.3_concrete_ConcreteElement:
+
+ConcreteElement
+"""""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.3_commons_DOMLElement>`
+
+* Associations:
+	* ``refs`` → ConcreteElement [0..*]
+* Attributes:
+	* ``configurationScript`` [String]
+	* ``preexisting`` [Boolean]
+
+.. _v2.3_concrete_ConcreteInfrastructure:
+
+ConcreteInfrastructure
+""""""""""""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.3_commons_DOMLElement>`
+
+* Associations:
+	* ``providers`` → RuntimeProvider [0..*]
+
+.. _v2.3_concrete_ContainerImage:
+
+ContainerImage
+""""""""""""""
+*Inherits from* :ref:`ConcreteElement <v2.3_concrete_ConcreteElement>`
+
+* Associations:
+	* ``maps`` → ContainerImage [0..1]
+
+.. _v2.3_concrete_FunctionAsAService:
+
+FunctionAsAService
+""""""""""""""""""
+*Inherits from* :ref:`ConcreteElement <v2.3_concrete_ConcreteElement>`
+
+* Associations:
+	* ``maps`` → FunctionAsAService [0..1]
+
+.. _v2.3_concrete_GenericResource:
+
+GenericResource
+"""""""""""""""
+*Inherits from* :ref:`ConcreteElement <v2.3_concrete_ConcreteElement>`
+
+* Attributes:
+	* ``type`` [String]
+	* ``gname`` [String]
+
+.. _v2.3_concrete_Network:
+
+Network
+"""""""
+*Inherits from* :ref:`ConcreteElement <v2.3_concrete_ConcreteElement>`
+
+* Associations:
+	* ``maps`` → Network [0..1]
+
+.. _v2.3_concrete_RuntimeProvider:
+
+RuntimeProvider
+"""""""""""""""
+*Inherits from* :ref:`DOMLElement <v2.3_commons_DOMLElement>`
+
+* Associations:
+	* ``resources`` → GenericResource [0..*]
+	* ``vms`` → VirtualMachine [0..*]
+	* ``vmImages`` → VMImage [0..*]
+	* ``containerImages`` → ContainerImage [0..*]
+	* ``networks`` → Network [0..*]
+	* ``storages`` → Storage [0..*]
+	* ``faas`` → FunctionAsAService [0..*]
+	* ``group`` → ComputingGroup [0..*]
+
+.. _v2.3_concrete_Storage:
+
+Storage
+"""""""
+*Inherits from* :ref:`ConcreteElement <v2.3_concrete_ConcreteElement>`
+
+* Associations:
+	* ``maps`` → Storage [0..1]
+
+.. _v2.3_concrete_VMImage:
+
+VMImage
+"""""""
+*Inherits from* :ref:`ConcreteElement <v2.3_concrete_ConcreteElement>`
+
+* Associations:
+	* ``maps`` → VMImage [0..1]
+* Attributes:
+	* ``image_name`` [String]
+
+.. _v2.3_concrete_VirtualMachine:
+
+VirtualMachine
+""""""""""""""
+*Inherits from* :ref:`ConcreteElement <v2.3_concrete_ConcreteElement>`
+
+* Associations:
+	* ``maps`` → VirtualMachine [0..1]
+
+
+
diff --git a/docs/reference_v3.0.rst b/docs/reference_v3.0.rst
new file mode 100644
index 0000000000000000000000000000000000000000..096c738f9709f24e21b5a6089dc8c737d712d575
--- /dev/null
+++ b/docs/reference_v3.0.rst
@@ -0,0 +1,595 @@
+DOML v3.0 Reference
+=============================
+
+
+commons
+^^^^^^^
+
+.. _v3.0_commons_BProperty:
+
+BProperty
+"""""""""
+*Inherits from* :ref:`Property <v3.0_commons_Property>`
+
+* Attributes:
+	* ``value`` [Boolean]
+
+.. _v3.0_commons_Configuration:
+
+Configuration
+"""""""""""""
+*Inherits from* :ref:`DOMLElement <v3.0_commons_DOMLElement>`
+
+* Associations:
+	* ``deployments`` → Deployment [0..*]
+
+.. _v3.0_commons_Credentials:
+
+Credentials
+"""""""""""
+*Inherits from* :ref:`DOMLElement <v3.0_commons_DOMLElement>`
+
+
+.. _v3.0_commons_DOMLElement:
+
+DOMLElement
+"""""""""""
+* Associations:
+	* ``annotations`` → Property [0..*]
+* Attributes:
+	* ``name`` [String]
+	* ``description`` [String]
+
+.. _v3.0_commons_DeployableElement:
+
+DeployableElement
+"""""""""""""""""
+*Inherits from* :ref:`DOMLElement <v3.0_commons_DOMLElement>`
+
+
+.. _v3.0_commons_Deployment:
+
+Deployment
+""""""""""
+* Associations:
+	* ``component`` → DeployableElement [1..1]
+	* ``node`` → InfrastructureElement [1..1]
+
+.. _v3.0_commons_FProperty:
+
+FProperty
+"""""""""
+*Inherits from* :ref:`Property <v3.0_commons_Property>`
+
+* Attributes:
+	* ``value`` [String]
+
+.. _v3.0_commons_IProperty:
+
+IProperty
+"""""""""
+*Inherits from* :ref:`Property <v3.0_commons_Property>`
+
+* Attributes:
+	* ``value`` [Integer]
+
+.. _v3.0_commons_KeyPair:
+
+KeyPair
+"""""""
+*Inherits from* :ref:`Credentials <v3.0_commons_Credentials>`
+
+* Attributes:
+	* ``user`` [String]
+	* ``keyfile`` [String]
+	* ``algorithm`` [String]
+	* ``bits`` [Integer]
+
+.. _v3.0_commons_Property:
+
+Property
+""""""""
+* Associations:
+	* ``reference`` → DOMLElement [0..1]
+* Attributes:
+	* ``key`` [String]
+
+.. _v3.0_commons_SProperty:
+
+SProperty
+"""""""""
+*Inherits from* :ref:`Property <v3.0_commons_Property>`
+
+* Attributes:
+	* ``value`` [String]
+
+.. _v3.0_commons_Source:
+
+Source
+""""""
+*Inherits from* :ref:`DOMLElement <v3.0_commons_DOMLElement>`
+
+* Attributes:
+	* ``entry`` [String]
+	* ``backend`` [String]
+
+.. _v3.0_commons_UserPass:
+
+UserPass
+""""""""
+*Inherits from* :ref:`Credentials <v3.0_commons_Credentials>`
+
+* Attributes:
+	* ``username`` [String]
+	* ``password`` [String]
+
+application
+^^^^^^^^^^^
+
+.. _v3.0_application_ApplicationComponent:
+
+ApplicationComponent
+""""""""""""""""""""
+*Inherits from* :ref:`DeployableElement <v3.0_commons_DeployableElement>`
+
+
+.. _v3.0_application_ApplicationLayer:
+
+ApplicationLayer
+""""""""""""""""
+*Inherits from* :ref:`DOMLElement <v3.0_commons_DOMLElement>`
+
+* Associations:
+	* ``components`` → ApplicationComponent [0..*]
+
+.. _v3.0_application_DBMS:
+
+DBMS
+""""
+*Inherits from* :ref:`SoftwareComponent <v3.0_application_SoftwareComponent>`
+
+
+.. _v3.0_application_SaaS:
+
+SaaS
+""""
+*Inherits from* :ref:`ApplicationComponent <v3.0_application_ApplicationComponent>`
+
+* Associations:
+	* ``exposedInterfaces`` → SoftwareInterface [0..*]
+* Attributes:
+	* ``licenseCost`` [String]
+
+.. _v3.0_application_SaaSDBMS:
+
+SaaSDBMS
+""""""""
+*Inherits from* :ref:`SaaS <v3.0_application_SaaS>`
+
+
+.. _v3.0_application_SoftwareComponent:
+
+SoftwareComponent
+"""""""""""""""""
+*Inherits from* :ref:`ApplicationComponent <v3.0_application_ApplicationComponent>`
+
+* Associations:
+	* ``exposedInterfaces`` → SoftwareInterface [0..*]
+	* ``consumedInterfaces`` → SoftwareInterface [0..*]
+	* ``src`` → Source [0..1]
+* Attributes:
+	* ``isPersistent`` [Boolean]
+	* ``licenseCost`` [String]
+
+.. _v3.0_application_SoftwareInterface:
+
+SoftwareInterface
+"""""""""""""""""
+*Inherits from* :ref:`ApplicationComponent <v3.0_application_ApplicationComponent>`
+
+* Attributes:
+	* ``endPoint`` [String]
+
+infrastructure
+^^^^^^^^^^^^^^
+
+.. _v3.0_infrastructure_AutoScalingGroup:
+
+AutoScalingGroup
+""""""""""""""""
+*Inherits from* :ref:`ComputingGroup <v3.0_infrastructure_ComputingGroup>`
+
+* Associations:
+	* ``machineDefinition`` → VirtualMachine [1..1]
+	* ``securityGroup`` → SecurityGroup [0..1]
+* Attributes:
+	* ``min`` [Integer]
+	* ``max`` [Integer]
+	* ``loadBalancer`` [String]
+
+.. _v3.0_infrastructure_ComputingGroup:
+
+ComputingGroup
+""""""""""""""
+*Inherits from* :ref:`DOMLElement <v3.0_commons_DOMLElement>`
+
+* Associations:
+	* ``groupedNodes`` → ComputingNode [0..*]
+
+.. _v3.0_infrastructure_ComputingNode:
+
+ComputingNode
+"""""""""""""
+*Inherits from* :ref:`Node <v3.0_infrastructure_Node>`
+
+* Associations:
+	* ``location`` → Location [0..1]
+	* ``credentials`` → Credentials [0..1]
+	* ``group`` → ComputingGroup [0..1]
+	* ``nodeSpecificMonitoring`` → MonitoringRule [0..1]
+* Attributes:
+	* ``architecture`` [String]
+	* ``os`` [String]
+	* ``memory_mb`` [Integer]
+	* ``memory_kb`` [Integer]
+	* ``storage`` [String]
+	* ``cpu_count`` [Integer]
+	* ``cost`` [Integer]
+	* ``disabledMonitorings`` [String]
+
+.. _v3.0_infrastructure_ComputingNodeGenerator:
+
+ComputingNodeGenerator
+""""""""""""""""""""""
+*Inherits from* :ref:`DOMLElement <v3.0_commons_DOMLElement>`
+
+* Attributes:
+	* ``uri`` [String]
+	* ``kind`` [GeneratorKind]
+
+.. _v3.0_infrastructure_Container:
+
+Container
+"""""""""
+*Inherits from* :ref:`ComputingNode <v3.0_infrastructure_ComputingNode>`
+
+* Associations:
+	* ``generatedFrom`` → ContainerImage [0..1]
+	* ``configs`` → ContainerConfig [0..*]
+
+.. _v3.0_infrastructure_ContainerConfig:
+
+ContainerConfig
+"""""""""""""""
+*Inherits from* :ref:`DOMLElement <v3.0_commons_DOMLElement>`
+
+* Associations:
+	* ``host`` → ComputingNode [0..1]
+	* ``iface`` → NetworkInterface [0..1]
+* Attributes:
+	* ``container_port`` [Integer]
+	* ``vm_port`` [Integer]
+
+.. _v3.0_infrastructure_ContainerImage:
+
+ContainerImage
+""""""""""""""
+*Inherits from* :ref:`ComputingNodeGenerator <v3.0_infrastructure_ComputingNodeGenerator>`
+
+* Associations:
+	* ``generatedContainers`` → Container [0..*]
+
+.. _v3.0_infrastructure_ExtInfrastructureElement:
+
+ExtInfrastructureElement
+""""""""""""""""""""""""
+*Inherits from* :ref:`InfrastructureElement <v3.0_infrastructure_InfrastructureElement>`
+
+
+.. _v3.0_infrastructure_FunctionAsAService:
+
+FunctionAsAService
+""""""""""""""""""
+*Inherits from* :ref:`InfrastructureElement <v3.0_infrastructure_InfrastructureElement>`
+
+* Attributes:
+	* ``cost`` [Integer]
+
+.. _v3.0_infrastructure_InfrastructureElement:
+
+InfrastructureElement
+"""""""""""""""""""""
+*Inherits from* :ref:`DeployableElement <v3.0_commons_DeployableElement>`
+
+
+.. _v3.0_infrastructure_InfrastructureLayer:
+
+InfrastructureLayer
+"""""""""""""""""""
+*Inherits from* :ref:`DOMLElement <v3.0_commons_DOMLElement>`
+
+* Associations:
+	* ``nodes`` → ComputingNode [0..*]
+	* ``generators`` → ComputingNodeGenerator [0..*]
+	* ``storages`` → Storage [0..*]
+	* ``faas`` → FunctionAsAService [0..*]
+	* ``credentials`` → Credentials [0..*]
+	* ``groups`` → ComputingGroup [0..*]
+	* ``securityGroups`` → SecurityGroup [0..*]
+	* ``networks`` → Network [0..*]
+	* ``rules`` → MonitoringRule [0..*]
+
+.. _v3.0_infrastructure_InternetGateway:
+
+InternetGateway
+"""""""""""""""
+*Inherits from* :ref:`Node <v3.0_infrastructure_Node>`
+
+* Attributes:
+	* ``address`` [String]
+
+.. _v3.0_infrastructure_Location:
+
+Location
+""""""""
+*Inherits from* :ref:`DOMLElement <v3.0_commons_DOMLElement>`
+
+* Attributes:
+	* ``region`` [String]
+	* ``zone`` [String]
+
+.. _v3.0_infrastructure_MonitoringRule:
+
+MonitoringRule
+""""""""""""""
+*Inherits from* :ref:`DOMLElement <v3.0_commons_DOMLElement>`
+
+* Attributes:
+	* ``condition`` [String]
+	* ``strategy`` [String]
+	* ``strategyConfigurationString`` [String]
+
+.. _v3.0_infrastructure_Network:
+
+Network
+"""""""
+*Inherits from* :ref:`DOMLElement <v3.0_commons_DOMLElement>`
+
+* Associations:
+	* ``connectedIfaces`` → NetworkInterface [0..*]
+	* ``gateways`` → InternetGateway [0..*]
+	* ``subnets`` → Subnet [0..*]
+* Attributes:
+	* ``protocol`` [String]
+	* ``addressRange`` [String]
+	* ``cidr`` [Integer]
+
+.. _v3.0_infrastructure_NetworkInterface:
+
+NetworkInterface
+""""""""""""""""
+*Inherits from* :ref:`InfrastructureElement <v3.0_infrastructure_InfrastructureElement>`
+
+* Associations:
+	* ``belongsTo`` → Network [0..1]
+	* ``associated`` → SecurityGroup [0..1]
+* Attributes:
+	* ``endPoint`` [Integer]
+	* ``speed`` [String]
+
+.. _v3.0_infrastructure_Node:
+
+Node
+""""
+*Inherits from* :ref:`InfrastructureElement <v3.0_infrastructure_InfrastructureElement>`
+
+* Associations:
+	* ``ifaces`` → NetworkInterface [0..*]
+
+.. _v3.0_infrastructure_PhysicalComputingNode:
+
+PhysicalComputingNode
+"""""""""""""""""""""
+*Inherits from* :ref:`ComputingNode <v3.0_infrastructure_ComputingNode>`
+
+
+.. _v3.0_infrastructure_Rule:
+
+Rule
+""""
+*Inherits from* :ref:`DOMLElement <v3.0_commons_DOMLElement>`
+
+* Attributes:
+	* ``kind`` [String]
+	* ``protocol`` [String]
+	* ``fromPort`` [Integer]
+	* ``toPort`` [Integer]
+	* ``cidr`` [String]
+
+.. _v3.0_infrastructure_SecurityGroup:
+
+SecurityGroup
+"""""""""""""
+*Inherits from* :ref:`DOMLElement <v3.0_commons_DOMLElement>`
+
+* Associations:
+	* ``rules`` → Rule [0..*]
+	* ``ifaces`` → NetworkInterface [0..*]
+
+.. _v3.0_infrastructure_Storage:
+
+Storage
+"""""""
+*Inherits from* :ref:`Node <v3.0_infrastructure_Node>`
+
+* Attributes:
+	* ``label`` [String]
+	* ``size_gb`` [Integer]
+	* ``cost`` [Integer]
+
+.. _v3.0_infrastructure_Subnet:
+
+Subnet
+""""""
+*Inherits from* :ref:`Network <v3.0_infrastructure_Network>`
+
+* Associations:
+	* ``connectedTo`` → Network [0..*]
+
+.. _v3.0_infrastructure_Swarm:
+
+Swarm
+"""""
+*Inherits from* :ref:`ComputingGroup <v3.0_infrastructure_ComputingGroup>`
+
+* Associations:
+	* ``roles`` → SwarmRole [0..*]
+
+.. _v3.0_infrastructure_SwarmRole:
+
+SwarmRole
+"""""""""
+*Inherits from* :ref:`DOMLElement <v3.0_commons_DOMLElement>`
+
+* Associations:
+	* ``nodes`` → ComputingNode [0..*]
+* Attributes:
+	* ``kind`` [String]
+
+.. _v3.0_infrastructure_VMImage:
+
+VMImage
+"""""""
+*Inherits from* :ref:`ComputingNodeGenerator <v3.0_infrastructure_ComputingNodeGenerator>`
+
+* Associations:
+	* ``generatedVMs`` → VirtualMachine [0..*]
+
+.. _v3.0_infrastructure_VirtualMachine:
+
+VirtualMachine
+""""""""""""""
+*Inherits from* :ref:`ComputingNode <v3.0_infrastructure_ComputingNode>`
+
+* Associations:
+	* ``generatedFrom`` → VMImage [0..1]
+* Attributes:
+	* ``sizeDescription`` [String]
+
+concrete
+^^^^^^^^
+
+.. _v3.0_concrete_ComputingGroup:
+
+ComputingGroup
+""""""""""""""
+*Inherits from* :ref:`ConcreteElement <v3.0_concrete_ConcreteElement>`
+
+* Associations:
+	* ``maps`` → ComputingGroup [1..1]
+
+.. _v3.0_concrete_ConcreteElement:
+
+ConcreteElement
+"""""""""""""""
+*Inherits from* :ref:`DOMLElement <v3.0_commons_DOMLElement>`
+
+* Associations:
+	* ``refs`` → ConcreteElement [0..*]
+* Attributes:
+	* ``configurationScript`` [String]
+	* ``preexisting`` [Boolean]
+
+.. _v3.0_concrete_ConcreteInfrastructure:
+
+ConcreteInfrastructure
+""""""""""""""""""""""
+*Inherits from* :ref:`DOMLElement <v3.0_commons_DOMLElement>`
+
+* Associations:
+	* ``providers`` → RuntimeProvider [0..*]
+
+.. _v3.0_concrete_ContainerImage:
+
+ContainerImage
+""""""""""""""
+*Inherits from* :ref:`ConcreteElement <v3.0_concrete_ConcreteElement>`
+
+* Associations:
+	* ``maps`` → ContainerImage [0..1]
+
+.. _v3.0_concrete_FunctionAsAService:
+
+FunctionAsAService
+""""""""""""""""""
+*Inherits from* :ref:`ConcreteElement <v3.0_concrete_ConcreteElement>`
+
+* Associations:
+	* ``maps`` → FunctionAsAService [0..1]
+
+.. _v3.0_concrete_GenericResource:
+
+GenericResource
+"""""""""""""""
+*Inherits from* :ref:`ConcreteElement <v3.0_concrete_ConcreteElement>`
+
+* Attributes:
+	* ``type`` [String]
+	* ``gname`` [String]
+
+.. _v3.0_concrete_Network:
+
+Network
+"""""""
+*Inherits from* :ref:`ConcreteElement <v3.0_concrete_ConcreteElement>`
+
+* Associations:
+	* ``maps`` → Network [0..1]
+
+.. _v3.0_concrete_RuntimeProvider:
+
+RuntimeProvider
+"""""""""""""""
+*Inherits from* :ref:`DOMLElement <v3.0_commons_DOMLElement>`
+
+* Associations:
+	* ``resources`` → GenericResource [0..*]
+	* ``vms`` → VirtualMachine [0..*]
+	* ``vmImages`` → VMImage [0..*]
+	* ``containerImages`` → ContainerImage [0..*]
+	* ``networks`` → Network [0..*]
+	* ``storages`` → Storage [0..*]
+	* ``faas`` → FunctionAsAService [0..*]
+	* ``group`` → ComputingGroup [0..*]
+
+.. _v3.0_concrete_Storage:
+
+Storage
+"""""""
+*Inherits from* :ref:`ConcreteElement <v3.0_concrete_ConcreteElement>`
+
+* Associations:
+	* ``maps`` → Storage [0..1]
+
+.. _v3.0_concrete_VMImage:
+
+VMImage
+"""""""
+*Inherits from* :ref:`ConcreteElement <v3.0_concrete_ConcreteElement>`
+
+* Associations:
+	* ``maps`` → VMImage [0..1]
+* Attributes:
+	* ``image_name`` [String]
+
+.. _v3.0_concrete_VirtualMachine:
+
+VirtualMachine
+""""""""""""""
+*Inherits from* :ref:`ConcreteElement <v3.0_concrete_ConcreteElement>`
+
+* Associations:
+	* ``maps`` → VirtualMachine [0..1]
+
+
+
diff --git a/docs/reference_v3.1.rst b/docs/reference_v3.1.rst
new file mode 100644
index 0000000000000000000000000000000000000000..5fcd3814cd7eb584c3ce417cee2d80ca39d517b2
--- /dev/null
+++ b/docs/reference_v3.1.rst
@@ -0,0 +1,696 @@
+DOML v3.1 Reference
+=============================
+
+
+commons
+^^^^^^^
+
+.. _v3.1_commons_BProperty:
+
+BProperty
+"""""""""
+*Inherits from* :ref:`Property <v3.1_commons_Property>`
+
+* Attributes:
+	* ``value`` [Boolean]
+
+.. _v3.1_commons_Configuration:
+
+Configuration
+"""""""""""""
+*Inherits from* :ref:`DOMLElement <v3.1_commons_DOMLElement>`
+
+* Associations:
+	* ``deployments`` → Deployment [0..*]
+
+.. _v3.1_commons_Credentials:
+
+Credentials
+"""""""""""
+*Inherits from* :ref:`DOMLElement <v3.1_commons_DOMLElement>`
+
+
+.. _v3.1_commons_DOMLElement:
+
+DOMLElement
+"""""""""""
+* Associations:
+	* ``annotations`` → Property [0..*]
+* Attributes:
+	* ``name`` [String]
+	* ``description`` [String]
+
+.. _v3.1_commons_DeployableElement:
+
+DeployableElement
+"""""""""""""""""
+*Inherits from* :ref:`DOMLElement <v3.1_commons_DOMLElement>`
+
+
+.. _v3.1_commons_Deployment:
+
+Deployment
+""""""""""
+* Associations:
+	* ``component`` → DeployableElement [1..1]
+	* ``node`` → InfrastructureElement [1..1]
+
+.. _v3.1_commons_FProperty:
+
+FProperty
+"""""""""
+*Inherits from* :ref:`Property <v3.1_commons_Property>`
+
+* Attributes:
+	* ``value`` [String]
+
+.. _v3.1_commons_IProperty:
+
+IProperty
+"""""""""
+*Inherits from* :ref:`Property <v3.1_commons_Property>`
+
+* Attributes:
+	* ``value`` [Integer]
+
+.. _v3.1_commons_KeyPair:
+
+KeyPair
+"""""""
+*Inherits from* :ref:`Credentials <v3.1_commons_Credentials>`
+
+* Attributes:
+	* ``user`` [String]
+	* ``key`` [String]
+	* ``algorithm`` [String]
+	* ``bits`` [Integer]
+
+.. _v3.1_commons_ListProperty:
+
+ListProperty
+""""""""""""
+*Inherits from* :ref:`Property <v3.1_commons_Property>`
+
+* Associations:
+	* ``values`` → Property [0..*]
+
+.. _v3.1_commons_Property:
+
+Property
+""""""""
+* Associations:
+	* ``reference`` → DOMLElement [0..1]
+* Attributes:
+	* ``key`` [String]
+
+.. _v3.1_commons_SProperty:
+
+SProperty
+"""""""""
+*Inherits from* :ref:`Property <v3.1_commons_Property>`
+
+* Attributes:
+	* ``value`` [String]
+
+.. _v3.1_commons_Source:
+
+Source
+""""""
+*Inherits from* :ref:`DOMLElement <v3.1_commons_DOMLElement>`
+
+* Attributes:
+	* ``entry`` [String]
+	* ``inventory`` [String]
+	* ``backend`` [String]
+
+.. _v3.1_commons_UserPass:
+
+UserPass
+""""""""
+*Inherits from* :ref:`Credentials <v3.1_commons_Credentials>`
+
+* Attributes:
+	* ``username`` [String]
+	* ``password`` [String]
+
+application
+^^^^^^^^^^^
+
+.. _v3.1_application_ApplicationComponent:
+
+ApplicationComponent
+""""""""""""""""""""
+*Inherits from* :ref:`DeployableElement <v3.1_commons_DeployableElement>`
+
+
+.. _v3.1_application_ApplicationLayer:
+
+ApplicationLayer
+""""""""""""""""
+*Inherits from* :ref:`DOMLElement <v3.1_commons_DOMLElement>`
+
+* Associations:
+	* ``components`` → ApplicationComponent [0..*]
+
+.. _v3.1_application_DBMS:
+
+DBMS
+""""
+*Inherits from* :ref:`SoftwareComponent <v3.1_application_SoftwareComponent>`
+
+
+.. _v3.1_application_SaaS:
+
+SaaS
+""""
+*Inherits from* :ref:`ApplicationComponent <v3.1_application_ApplicationComponent>`
+
+* Associations:
+	* ``exposedInterfaces`` → SoftwareInterface [0..*]
+* Attributes:
+	* ``licenseCost`` [String]
+
+.. _v3.1_application_SaaSDBMS:
+
+SaaSDBMS
+""""""""
+*Inherits from* :ref:`SaaS <v3.1_application_SaaS>`
+
+* Attributes:
+	* ``databaseName`` [String]
+	* ``engine`` [String]
+	* ``engineVersion`` [String]
+
+.. _v3.1_application_SoftwareComponent:
+
+SoftwareComponent
+"""""""""""""""""
+*Inherits from* :ref:`ApplicationComponent <v3.1_application_ApplicationComponent>`
+
+* Associations:
+	* ``exposedInterfaces`` → SoftwareInterface [0..*]
+	* ``consumedInterfaces`` → SoftwareInterface [0..*]
+	* ``src`` → Source [0..1]
+* Attributes:
+	* ``isPersistent`` [Boolean]
+	* ``licenseCost`` [String]
+
+.. _v3.1_application_SoftwareInterface:
+
+SoftwareInterface
+"""""""""""""""""
+*Inherits from* :ref:`ApplicationComponent <v3.1_application_ApplicationComponent>`
+
+* Attributes:
+	* ``endPoint`` [String]
+
+infrastructure
+^^^^^^^^^^^^^^
+
+.. _v3.1_infrastructure_AutoScalingGroup:
+
+AutoScalingGroup
+""""""""""""""""
+*Inherits from* :ref:`ComputingGroup <v3.1_infrastructure_ComputingGroup>`
+
+* Associations:
+	* ``machineDefinition`` → VirtualMachine [1..1]
+* Attributes:
+	* ``min`` [Integer]
+	* ``max`` [Integer]
+	* ``loadBalancer`` [String]
+
+.. _v3.1_infrastructure_ComputingGroup:
+
+ComputingGroup
+""""""""""""""
+*Inherits from* :ref:`DOMLElement <v3.1_commons_DOMLElement>`
+
+* Associations:
+	* ``groupedNodes`` → ComputingNode [0..*]
+
+.. _v3.1_infrastructure_ComputingNode:
+
+ComputingNode
+"""""""""""""
+*Inherits from* :ref:`Node <v3.1_infrastructure_Node>`
+
+* Associations:
+	* ``location`` → Location [0..1]
+	* ``credentials`` → Credentials [0..1]
+	* ``group`` → ComputingGroup [0..1]
+	* ``nodeSpecificMonitoring`` → MonitoringRule [0..1]
+* Attributes:
+	* ``architecture`` [String]
+	* ``os`` [String]
+	* ``memory_mb`` [Integer]
+	* ``memory_kb`` [Integer]
+	* ``storage`` [Integer]
+	* ``cpu_count`` [Integer]
+	* ``cost`` [Integer]
+	* ``disabledMonitorings`` [String]
+
+.. _v3.1_infrastructure_ComputingNodeGenerator:
+
+ComputingNodeGenerator
+""""""""""""""""""""""
+*Inherits from* :ref:`DOMLElement <v3.1_commons_DOMLElement>`
+
+* Attributes:
+	* ``uri`` [String]
+	* ``kind`` [GeneratorKind]
+
+.. _v3.1_infrastructure_Container:
+
+Container
+"""""""""
+*Inherits from* :ref:`ComputingNode <v3.1_infrastructure_ComputingNode>`
+
+* Associations:
+	* ``generatedFrom`` → ContainerImage [0..1]
+	* ``hostConfigs`` → ContainerHostConfig [0..*]
+	* ``networks`` → ContainerNetwork [0..*]
+	* ``volumes`` → ContainerVolume [0..*]
+	* ``dependsOn`` → Container [0..*]
+
+.. _v3.1_infrastructure_ContainerConfig:
+
+ContainerConfig
+"""""""""""""""
+*Inherits from* :ref:`DOMLElement <v3.1_commons_DOMLElement>`
+
+* Associations:
+	* ``iface`` → NetworkInterface [0..1]
+* Attributes:
+	* ``container_port`` [Integer]
+	* ``vm_port`` [Integer]
+
+.. _v3.1_infrastructure_ContainerGroup:
+
+ContainerGroup
+""""""""""""""
+*Inherits from* :ref:`ComputingGroup <v3.1_infrastructure_ComputingGroup>`
+
+* Associations:
+	* ``services`` → Container [1..*]
+	* ``networks`` → ContainerNetwork [0..*]
+	* ``volumes`` → ContainerVolume [0..*]
+
+.. _v3.1_infrastructure_ContainerHostConfig:
+
+ContainerHostConfig
+"""""""""""""""""""
+*Inherits from* :ref:`DOMLElement <v3.1_commons_DOMLElement>`
+
+* Associations:
+	* ``environment_variables`` → SProperty [0..*]
+	* ``host`` → ComputingNode [0..1]
+	* ``configurations`` → ContainerConfig [0..*]
+
+.. _v3.1_infrastructure_ContainerImage:
+
+ContainerImage
+""""""""""""""
+*Inherits from* :ref:`ComputingNodeGenerator <v3.1_infrastructure_ComputingNodeGenerator>`
+
+* Associations:
+	* ``generatedContainers`` → Container [0..*]
+
+.. _v3.1_infrastructure_ContainerNetwork:
+
+ContainerNetwork
+""""""""""""""""
+*Inherits from* :ref:`DOMLElement <v3.1_commons_DOMLElement>`
+
+* Attributes:
+	* ``containerNetworkName`` [String]
+
+.. _v3.1_infrastructure_ContainerVolume:
+
+ContainerVolume
+"""""""""""""""
+*Inherits from* :ref:`DOMLElement <v3.1_commons_DOMLElement>`
+
+* Attributes:
+	* ``containerVolumeName`` [String]
+	* ``path`` [String]
+
+.. _v3.1_infrastructure_ExecutionEnvironment:
+
+ExecutionEnvironment
+""""""""""""""""""""
+*Inherits from* :ref:`InfrastructureElement <v3.1_infrastructure_InfrastructureElement>`
+
+* Associations:
+	* ``location`` → Location [0..1]
+	* ``network`` → Network [0..1]
+	* ``securityGroups`` → SecurityGroup [0..*]
+* Attributes:
+	* ``size`` [Integer]
+	* ``maxSize`` [Integer]
+
+.. _v3.1_infrastructure_ExtInfrastructureElement:
+
+ExtInfrastructureElement
+""""""""""""""""""""""""
+*Inherits from* :ref:`InfrastructureElement <v3.1_infrastructure_InfrastructureElement>`
+
+
+.. _v3.1_infrastructure_FunctionAsAService:
+
+FunctionAsAService
+""""""""""""""""""
+*Inherits from* :ref:`InfrastructureElement <v3.1_infrastructure_InfrastructureElement>`
+
+* Attributes:
+	* ``cost`` [Integer]
+
+.. _v3.1_infrastructure_InfrastructureElement:
+
+InfrastructureElement
+"""""""""""""""""""""
+*Inherits from* :ref:`DeployableElement <v3.1_commons_DeployableElement>`
+
+
+.. _v3.1_infrastructure_InfrastructureLayer:
+
+InfrastructureLayer
+"""""""""""""""""""
+*Inherits from* :ref:`DOMLElement <v3.1_commons_DOMLElement>`
+
+* Associations:
+	* ``nodes`` → ComputingNode [0..*]
+	* ``generators`` → ComputingNodeGenerator [0..*]
+	* ``storages`` → Storage [0..*]
+	* ``faas`` → FunctionAsAService [0..*]
+	* ``credentials`` → Credentials [0..*]
+	* ``groups`` → ComputingGroup [0..*]
+	* ``securityGroups`` → SecurityGroup [0..*]
+	* ``networks`` → Network [0..*]
+	* ``rules`` → MonitoringRule [0..*]
+	* ``executionEnvironments`` → ExecutionEnvironment [0..*]
+
+.. _v3.1_infrastructure_InternetGateway:
+
+InternetGateway
+"""""""""""""""
+*Inherits from* :ref:`Node <v3.1_infrastructure_Node>`
+
+* Attributes:
+	* ``address`` [String]
+
+.. _v3.1_infrastructure_Location:
+
+Location
+""""""""
+*Inherits from* :ref:`DOMLElement <v3.1_commons_DOMLElement>`
+
+* Attributes:
+	* ``region`` [String]
+	* ``zone`` [String]
+
+.. _v3.1_infrastructure_MonitoringRule:
+
+MonitoringRule
+""""""""""""""
+*Inherits from* :ref:`DOMLElement <v3.1_commons_DOMLElement>`
+
+* Attributes:
+	* ``condition`` [String]
+	* ``strategy`` [String]
+	* ``strategyConfigurationString`` [String]
+
+.. _v3.1_infrastructure_Network:
+
+Network
+"""""""
+*Inherits from* :ref:`DOMLElement <v3.1_commons_DOMLElement>`
+
+* Associations:
+	* ``connectedIfaces`` → NetworkInterface [0..*]
+	* ``gateways`` → InternetGateway [0..*]
+	* ``subnets`` → Subnet [0..*]
+* Attributes:
+	* ``protocol`` [String]
+	* ``cidr`` [Integer]
+
+.. _v3.1_infrastructure_NetworkInterface:
+
+NetworkInterface
+""""""""""""""""
+*Inherits from* :ref:`InfrastructureElement <v3.1_infrastructure_InfrastructureElement>`
+
+* Associations:
+	* ``belongsTo`` → Network [0..1]
+	* ``associated`` → SecurityGroup [0..1]
+* Attributes:
+	* ``endPoint`` [Integer]
+	* ``speed`` [String]
+
+.. _v3.1_infrastructure_Node:
+
+Node
+""""
+*Inherits from* :ref:`InfrastructureElement <v3.1_infrastructure_InfrastructureElement>`
+
+* Associations:
+	* ``ifaces`` → NetworkInterface [0..*]
+
+.. _v3.1_infrastructure_PhysicalComputingNode:
+
+PhysicalComputingNode
+"""""""""""""""""""""
+*Inherits from* :ref:`ComputingNode <v3.1_infrastructure_ComputingNode>`
+
+* Associations:
+	* ``configInterface`` → NetworkInterface [0..1]
+
+.. _v3.1_infrastructure_Rule:
+
+Rule
+""""
+*Inherits from* :ref:`DOMLElement <v3.1_commons_DOMLElement>`
+
+* Attributes:
+	* ``kind`` [String]
+	* ``protocol`` [String]
+	* ``fromPort`` [Integer]
+	* ``toPort`` [Integer]
+	* ``cidr`` [String]
+
+.. _v3.1_infrastructure_SecurityGroup:
+
+SecurityGroup
+"""""""""""""
+*Inherits from* :ref:`DOMLElement <v3.1_commons_DOMLElement>`
+
+* Associations:
+	* ``rules`` → Rule [0..*]
+	* ``ifaces`` → NetworkInterface [0..*]
+
+.. _v3.1_infrastructure_Storage:
+
+Storage
+"""""""
+*Inherits from* :ref:`Node <v3.1_infrastructure_Node>`
+
+* Attributes:
+	* ``label`` [String]
+	* ``size_gb`` [Integer]
+	* ``cost`` [Integer]
+
+.. _v3.1_infrastructure_Subnet:
+
+Subnet
+""""""
+*Inherits from* :ref:`Network <v3.1_infrastructure_Network>`
+
+* Associations:
+	* ``connectedTo`` → Network [0..*]
+
+.. _v3.1_infrastructure_Swarm:
+
+Swarm
+"""""
+*Inherits from* :ref:`ComputingGroup <v3.1_infrastructure_ComputingGroup>`
+
+* Associations:
+	* ``roles`` → SwarmRole [0..*]
+
+.. _v3.1_infrastructure_SwarmRole:
+
+SwarmRole
+"""""""""
+*Inherits from* :ref:`DOMLElement <v3.1_commons_DOMLElement>`
+
+* Associations:
+	* ``nodes`` → ComputingNode [0..*]
+* Attributes:
+	* ``kind`` [String]
+
+.. _v3.1_infrastructure_VMImage:
+
+VMImage
+"""""""
+*Inherits from* :ref:`ComputingNodeGenerator <v3.1_infrastructure_ComputingNodeGenerator>`
+
+* Associations:
+	* ``generatedVMs`` → VirtualMachine [0..*]
+
+.. _v3.1_infrastructure_VirtualMachine:
+
+VirtualMachine
+""""""""""""""
+*Inherits from* :ref:`ComputingNode <v3.1_infrastructure_ComputingNode>`
+
+* Associations:
+	* ``generatedFrom`` → VMImage [0..1]
+	* ``configInterface`` → NetworkInterface [0..1]
+* Attributes:
+	* ``sizeDescription`` [String]
+
+concrete
+^^^^^^^^
+
+.. _v3.1_concrete_AutoScalingGroup:
+
+AutoScalingGroup
+""""""""""""""""
+*Inherits from* :ref:`ConcreteElement <v3.1_concrete_ConcreteElement>`
+
+* Associations:
+	* ``maps`` → AutoScalingGroup [0..1]
+* Attributes:
+	* ``vm_type`` [String]
+
+.. _v3.1_concrete_ConcreteElement:
+
+ConcreteElement
+"""""""""""""""
+*Inherits from* :ref:`DOMLElement <v3.1_commons_DOMLElement>`
+
+* Associations:
+	* ``refs`` → ConcreteElement [0..*]
+* Attributes:
+	* ``resourceName`` [String]
+	* ``configurationScript`` [String]
+	* ``preexisting`` [Boolean]
+
+.. _v3.1_concrete_ConcreteInfrastructure:
+
+ConcreteInfrastructure
+""""""""""""""""""""""
+*Inherits from* :ref:`DOMLElement <v3.1_commons_DOMLElement>`
+
+* Associations:
+	* ``providers`` → RuntimeProvider [0..*]
+
+.. _v3.1_concrete_ContainerImage:
+
+ContainerImage
+""""""""""""""
+*Inherits from* :ref:`ConcreteElement <v3.1_concrete_ConcreteElement>`
+
+* Associations:
+	* ``maps`` → ContainerImage [0..1]
+
+.. _v3.1_concrete_ExecutionEnvironment:
+
+ExecutionEnvironment
+""""""""""""""""""""
+*Inherits from* :ref:`ConcreteElement <v3.1_concrete_ConcreteElement>`
+
+* Associations:
+	* ``maps`` → ExecutionEnvironment [0..1]
+* Attributes:
+	* ``instance_type`` [String]
+	* ``storage_type`` [String]
+
+.. _v3.1_concrete_FunctionAsAService:
+
+FunctionAsAService
+""""""""""""""""""
+*Inherits from* :ref:`ConcreteElement <v3.1_concrete_ConcreteElement>`
+
+* Associations:
+	* ``maps`` → FunctionAsAService [0..1]
+
+.. _v3.1_concrete_GenericResource:
+
+GenericResource
+"""""""""""""""
+*Inherits from* :ref:`ConcreteElement <v3.1_concrete_ConcreteElement>`
+
+* Attributes:
+	* ``type`` [String]
+
+.. _v3.1_concrete_Network:
+
+Network
+"""""""
+*Inherits from* :ref:`ConcreteElement <v3.1_concrete_ConcreteElement>`
+
+* Associations:
+	* ``subnets`` → Subnet [0..*]
+	* ``maps`` → Network [0..1]
+* Attributes:
+	* ``protocol`` [String]
+	* ``addressRange`` [String]
+
+.. _v3.1_concrete_RuntimeProvider:
+
+RuntimeProvider
+"""""""""""""""
+*Inherits from* :ref:`DOMLElement <v3.1_commons_DOMLElement>`
+
+* Associations:
+	* ``resources`` → GenericResource [0..*]
+	* ``vms`` → VirtualMachine [0..*]
+	* ``executionEnvironments`` → ExecutionEnvironment [0..*]
+	* ``vmImages`` → VMImage [0..*]
+	* ``containerImages`` → ContainerImage [0..*]
+	* ``networks`` → Network [0..*]
+	* ``storages`` → Storage [0..*]
+	* ``faas`` → FunctionAsAService [0..*]
+	* ``autoScalingGroups`` → AutoScalingGroup [0..*]
+
+.. _v3.1_concrete_Storage:
+
+Storage
+"""""""
+*Inherits from* :ref:`ConcreteElement <v3.1_concrete_ConcreteElement>`
+
+* Associations:
+	* ``maps`` → Storage [0..1]
+
+.. _v3.1_concrete_Subnet:
+
+Subnet
+""""""
+*Inherits from* :ref:`Network <v3.1_concrete_Network>`
+
+
+.. _v3.1_concrete_VMImage:
+
+VMImage
+"""""""
+*Inherits from* :ref:`ConcreteElement <v3.1_concrete_ConcreteElement>`
+
+* Associations:
+	* ``maps`` → VMImage [0..1]
+* Attributes:
+	* ``image_name`` [String]
+
+.. _v3.1_concrete_VirtualMachine:
+
+VirtualMachine
+""""""""""""""
+*Inherits from* :ref:`ConcreteElement <v3.1_concrete_ConcreteElement>`
+
+* Associations:
+	* ``maps`` → VirtualMachine [0..1]
+* Attributes:
+	* ``vm_type`` [String]
+
+
+
diff --git a/docs/requirements.rst b/docs/requirements.rst
index f5197401f11658bfe1162dc45eecfd9751506c16..913bbc05e493da6f30c9852d9a5fb3a131caaf4f 100644
--- a/docs/requirements.rst
+++ b/docs/requirements.rst
@@ -1,16 +1,20 @@
-Checked Requirements
-====================
+Built-in Requirements
+=====================
 
 The DOML Model Checker verifies DOML models against a collection of requirements
 devised to highlight the most common mistakes made by users when specifying cloud deployments.
 Here we list and describe such requirements.
 
+You may find examples of violations for each one of these requirements under the ``tests/doml`` directory.
+
 
 VM Network Interfaces
 ---------------------
 
   All virtual machines must be connected to at least one network interface.
 
+ID: ``vm_has_iface``
+
 Virtual machines can communicate with other components of a deployment or with external clients
 only through an appropriately configured network.
 this check makes sure no virtual machines are isolated.
@@ -21,6 +25,8 @@ Concretization of Software Interfaces
 
   All software packages can see the interfaces they need through a common network.
 
+ID: ``software_package_iface_net``
+
 This check makes sure all exposed and consumed software interfaces at the application layer level
 have been actually concretized through a network connection that allows the involved components
 to communicate.
@@ -31,7 +37,9 @@ Duplicated Interfaces
 
   There are no duplicated interfaces.
 
-Checks whether two or more interfaces have been assigned the same IP address in the same network.
+ID: ``iface_uniq``
+
+Checks whether two or more interfaces have been assigned the same IP address.
 
 
 Deployed Software Components
@@ -39,6 +47,8 @@ Deployed Software Components
 
   All software components have been deployed to some node.
 
+ID: ``all_software_components_deployed``
+
 Makes sure that all software components specified in the application layer have been
 associated to at least one node in the abstract infrastructure layer
 through the currently active deployment.
@@ -49,4 +59,57 @@ Concretization of Abstract Infrastructure
 
   All abstract infrastructure elements are mapped to an element in the active concretization.
 
-Makes sure all abstract infrastructure are concretized by the currently active concretization layer.
+ID: ``all_infrastructure_elements_deployed``
+
+Makes sure all abstract infrastructure nodes are concretized by the currently active concretization layer.
+
+
+Concrete Infrastructure Elements have a maps Association
+--------------------------------------------------------
+
+  All elements in the active concretization are mapped to some abstract infrastructure element.
+
+ID: ``all_concrete_map_something``
+
+Makes sure each concrete infrastructure element is mapped to a node in the Abstract Infrastructure Layer.
+
+
+Network Interfaces belong to a Security Group
+---------------------------------------------
+
+  All network interfaces belong to a security group.
+
+ID: ``security_group_must_have_iface``
+
+Makes sure all network interfaces have been configured to belong to a security group.
+This way, the user will be reminded to configure adequate rules for each network.
+
+
+Virtual Machines in AutoScaleGroup should not be present in Concretization
+--------------------------------------------------------------------------
+
+ID: ``concrete_asg_no_vm``
+
+*Available from DOML v2.2+*
+
+Makes sure a VM present inside an AutoScaleGroup in the Infrastructure Layer is not present
+and mapped in the Concretization layer.
+
+Virtual Machines that host a container need an OS
+-------------------------------------------------
+
+*Available from DOML v2.2+*
+
+Makes sure a VM hosting a container has the OS field present.
+
+.. Deprecated
+
+.. External Services are reached through HTTPS
+.. -------------------------------------------
+
+..   All external SaaS can be reached only through a secure connection.
+
+.. ID: ``external_services_must_have_https``
+
+.. Makes sure that an HTTPS rule is enforced for a Network Interface of a Software Component that interfaces with a SaaS.
+
diff --git a/docs/requirements.txt b/docs/requirements.txt
new file mode 100644
index 0000000000000000000000000000000000000000..9e279e79d32427f119426d5f3ec50ce026c4daa9
--- /dev/null
+++ b/docs/requirements.txt
@@ -0,0 +1 @@
+furo
\ No newline at end of file
diff --git a/docs/tests.rst b/docs/tests.rst
new file mode 100644
index 0000000000000000000000000000000000000000..e212c3790a33ad7c99dbee46c21feda903846461
--- /dev/null
+++ b/docs/tests.rst
@@ -0,0 +1,12 @@
+Testing
+=======
+
+To run the tests with *PyTest* you'll need to setup the server::
+  
+  python -m mc_openapi
+
+and then run separately::
+
+  python -m pytest
+
+Currently, a few tests are run for each supported DOML version.
\ No newline at end of file
diff --git a/docs/usage.rst b/docs/usage.rst
index 0b9c29f39340dc9a2f19c0f639740bd4c4f8000e..0d0478bd24785447bd89fe271474f2acb7e8ff39 100644
--- a/docs/usage.rst
+++ b/docs/usage.rst
@@ -1,9 +1,9 @@
-Usage through the PIACERE IDE
-=============================
+Usage
+*****
 
 
-Invoking the DOML Model Checker from the PIACERE IDE
------------------------------------------------------
+Through the PIACERE IDE
+=======================
 
 The DOML Model Checker is usually invoked from the PIACERE IDE.
 It expects a DOML file in XMI format as its input,
@@ -48,3 +48,62 @@ and then choose *Piacere* -> *Model Checker Preferences*.
 
 Here you may enter the endpoint address and port, which is useful in case you want to
 run the DOML Model Checker locally, instead of using the official deployment.
+
+Through the Command Line Interface
+==================================
+
+Another way to use the model checker is through the CLI.
+It provides additional options that are not available in the IDE at
+the moment, such as support for a separate user requirement file
+and synthesis of DOMLX.
+
+You can run it with::
+
+  python -m mc_openapi [options]
+
+To display all the available flags, run::
+
+  python -m mc_openapi -h
+
+Options
+-------
+
+Please note that not all flags work with eachother. In most cases, some won't have
+any effect in certain CLI flags combinations.
+
+There are **3 Modes** in which the CLI can run:
+
+- REST API (**R**)
+- Model Checker (**C**)
+- Model Synthesis (**S**)
+
+======  =========================  =========  =================
+Flags                              Mode       Description
+---------------------------------  ---------  -----------------
+Short   Long         
+======  =========================  =========  =================
+``-h``  ``--help``                 C, S, R    Print the all the available flags with an explanation
+``-v``  ``--verbose``              C, S, R    Print a detailed human-readable output of everything going on. Helpful for debugging
+``-p``  ``--port``                 R          The port that will expose the REST API (default: 8080)
+``-d``  ``--doml``                 C, S       The DOMLX file to check with the model checker
+``-V``  ``--doml-version``         C, S       The DOML version in which the DOMLX file is written in
+``-r``  ``--requirements``         C, S       A text file containing the user-defined requirements written in :doc:`DOMLR <writing-requirements>`.
+``-S``  ``--skip-common-checks``   C          Skips :doc:`build-in requirements <requirements>` checks
+``-c``  ``--check-consistency``    C          Perform additional consistency checks (legacy)
+``-t``  ``--threads``              C, R       The number of threads used by the model checker (default: 2)
+``-s``  ``--synth``                S          Synthetize a new DOMLX file from requirements
+``-m``  ``--max-tries``            S          Max number of tries to solve a model during synthesis (default: 10)
+======  =========================  =========  =================
+
+*If you do not provide the ``--doml`` option or the ``--synth`` option it will start the web server hosting the REST API!*
+
+Examples
+--------
+
+To check a DOMLX file with user-provided custom requirements, you may run::
+
+  python -m mc_openapi -d ./path/to/myModel.domlx -r ./path/to/myRequirements.domlr -V V2_0
+
+To synthetize a new DOMLX file with 4 threads and a maximum of 15 tries, you may run::
+
+  python -m mc_openapi -d ./path/to/myModel.domlx --synth -m 15
\ No newline at end of file
diff --git a/docs/writing-requirements.rst b/docs/writing-requirements.rst
new file mode 100644
index 0000000000000000000000000000000000000000..a9d87d7493bf4a0a9e21816be1decf89f10e390b
--- /dev/null
+++ b/docs/writing-requirements.rst
@@ -0,0 +1,191 @@
+Writing Requirements
+********************
+
+A feature of the DOML Model Checker is a Domain Specific Language (DSL)
+called **DOMLR** (the R stands for requirements).
+
+It will be integrated in the DOML in a future release.
+For now, it can be provided to the Model Checker through the CLI.
+
+Getting Started
+===============
+
+At the moment, you can integrate the requirements inside DOML using the ``functional_requirements`` field::
+
+    functional_requirements {
+        req_group_1 ```
+        # Your DOMLR goes here.
+        ```;
+        req_group_2 ```
+        # Other set of requirements
+        ```;
+    }
+
+
+If you want to write a snippet of DOMLR using VS Code, there's a `Syntax Highlight`_ extension for it.
+
+Every DOMLR piece of code is a list of requirement::
+
+    + "All Virtual Machines have a Interface and at least 4 cpu cores"
+    forall vm (
+        vm is class abstract.VirtualMachine
+        implies
+        exists iface (
+            vm has abstract.ComputingNode.ifaces iface
+            and
+            vm has abstract.ComputingNode.cpu_count >= 4 
+        )
+    )
+    error: "A vm lacks an associated interface or has less than 4 CPUs"
+
+Rules in 1 minute
+-----------------
+
+The language is *case-sensitive* but it's not indentation-based, so you are free to write it as you prefer.
+
+1.  A requirement must **start** with a ``+`` or ``-`` character.
+
+    -   ``+`` means that the requirement is in **positive form**: the requirement is satisfied when its logic expression is satisfied.
+
+    -   ``-`` means that the requirement is in **negative form**: the requirement is satisfied when its logic expression **is not** satisfied.
+
+2.  After the ``+`` or ``-`` there's the **name** of the requirement, which is a string between double quotes ``"..."``.
+    Single quotes ``'...'`` won't work.
+
+3.  Following the requirement name, there's the **logic expression** which is the core of the requirement.
+    It is written in `First Order Logic`_, so it will evaluate to either true or false. See the `Syntax`_ for details.
+
+4.  Last, following ``error:``, there is the **error message** that is printed when the requirement is not satisfied.
+    If you have a free variable, which means a variable that is not quantified, you can print its value by putting it in the
+    string between curly brackets like this: ``{myVar}``. You'll get a warning if the Model Checker can't assign a value to that variable.
+
+A note on positive and negative form
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+The difference is that in **positive form** you would generally use a *for all* quantifier at the beginning,
+which doesn't allow you to know which specific element didn't satisfy the requirement, while in **negative form**
+you'll have some variables that are not quantified, meaning that it's usually possible to retrieve the names of the
+elements associated to those variables that do not satisfy the requirement. **Negative form** is usually faster, you
+can convert an expression into it using :math:numref:`logicconv`, where :math:`P(x)` is a statement containing quantified variable :math:`x`.
+
+.. math:: \forall x P(x) \iff \neg\exists x \neg P(x)
+    :label: logicconv
+
+.. `Syntax`:
+
+Syntax
+======
+
+The syntax is the following:
+
+- Unary operators: ``not``
+    - Example: ``not <expression>``
+- Binary operators: ``or``, ``and``, ``implies``, ``iff`` (if and only if, AKA double implication)
+    - Example: ``<expression> and <expression>``
+- Quantifiers: ``forall``, ``exists``
+    - Example: ``forall x, y ( <expression> )``
+    - After the quantifier keywork (``forall``, ``exists``) you must specify a list of quantified variables
+        (separated by a comma ``,`` if there's more than one).
+    - Between the mandatory pair of parenthesis, you'll be able to use the quantified variables in a logic expression.
+- Parenthesis: ``(`` ... ``)``
+    - Useful when you have doubts about the precedence of operators, or want to increase legibility in certain situations.
+- Elements (variables):
+    - Begin with a lowercase letter.
+    - Example: ``virtualMachine`` or ``vm``
+- Values (constants):
+    - Strings are delimited by double quotes ``"..."``
+    - Numbers are integers.
+    - Booleans are either ``:true`` or ``:false``
+    - Example: ``56``, ``"linux"``, ``:true``
+- Relationships: ``<elem> has <relationship> <elem/value>``
+    - There are two types of relationships:
+        - **Associations** are a relationship between two elements (variables).
+        - **Attributes** are a relationship between an element (variable) and a value (variable or constant).
+    - Relationships follow this naming structure ``<package>.<class>.<relationship>``.
+    - Example:
+        - ``vm has abstract.ComputingNode.ifaces iface`` is an **Association**, as it puts in relationship the element ``vm`` with the element ``iface``.
+
+        - ``vm has abstract.ComputingNode.cpu_count >= 4`` is an **Attribute** Relationship, as it compares a property (``cpu_count``) of the element ``vm`` with a constant number.
+- Classes: ``class <class name>``
+    - They represent a kind of element in the architecture.
+    - Classes follow this naming structure ``<package>.<class>``
+- Equality: ``is``, ``is not``
+    - Used to set an equality (or inequality) constraint on an element variable. You can use it to assign a class to an element.
+    - Example: ``vm is class abstract.VirtualMachine``
+- Comparisons: ``>``,  ``>=``,  ``<``,  ``<=``,  ``==``,  ``!=``
+    - You can compare attributes with constants, or attributes with attributes.
+    - Example: 
+        - ``vm has abstract.ComputingNode.cpu_count >= 4`` compares attribute ``cpu_count`` with a numeric constant.
+        - ``vm1 has abstract.ComputingNode.cpu_count >= vm2 abstract.ComputingNode.cpu_count`` compares attribute ``cpu_count`` of ``vm1`` with the one of ``vm2``.
+
+
+
+Operator Precedence
+-------------------
+
+``exists``/``forall`` > ``not`` > ``or`` > ``and`` > ``implies`` > ``iff``
+
+Examples
+========
+
+1. State that an element must be of a certain class::
+
+    saas is class application.SaaS
+
+2. Check that an element has a certain relationship with another::
+
+    vm has infrastructure.ComputingNode.ifaces iface
+
+Note that in the above example we haven't said anything about the nature of ``vm``. 
+We get that ``iface`` is of class ``NetworkInterface`` for free since the association ``infrastructure.ComputingNode.ifaces`` requires it.
+If you want ``vm`` to be a `VirtualMachine` you should specify it as::
+    
+    vm is class infrastructure.VirtualMachine
+    and
+    vm has infrastructure.ComputingNode.ifaces iface
+
+3. State that all VMs have to use less than 1 GB of memory::
+    
+        forall vm (
+            vm is class infrastructure.VirtualMachine
+            implies
+            vm has infrastructure.ComputingNode.memory_mb <= 1024 
+        )
+
+We use ``forall`` to say that all ``vm``, **if** (that's what ``implies`` does)  ``vm`` that are ``VirtualMachine``, 
+then it should have less than 1024 MB (memory here is expressed in MB).
+
+If we want to rewrite this requirement in negative form, it becomes *'There is a VM that has more than 1 GB'*. If there exists such VM, then it means that
+the expression is *true*, therefore the requirement is *false*::
+    
+    exists vm (
+        vm is class infrastructure.VirtualMachine
+        and
+        vm has infrastructure.ComputingNode.memory_mb > 1024
+        # we can also write it as a negation
+        or not vm has infrastructure.ComputingNode.memory <= 1024 
+    )
+
+4. Compare two attributes of two elements. Let's say that you have two different containers, ``c1`` and ``c2``, and you want to require
+that the memory used by ``c1`` is less than the one used by ``c2`` (note that we don't put another ``has`` in the expression in right hand side of ``<``)::
+
+    c1 has infrastructure.ComputingNode.memory_mb < c2 infrastructure.ComputingNode.memory_mb
+
+Flags
+=====
+You can alter the behaviour of the model checker through flags, which are simple parameters you can put at the beginnning of DOMLR.
+
+They are the following:
+    - ``%IGNORE <id of requirement>`` skips a specific built-in requirement.
+    - ``%IGNORE_BUILTIN`` skips all built-in requirements.
+    - ``%CHECK <id of requirement>`` enables an optional requirement.
+    - ``%CHECK_CONSISTENCY`` enables optional consistency checks.
+    - ``%CSP`` enables a Cloud Service Provider compatibility report, that is appended to the results.
+
+Grammar
+=======
+See the `grammar.lark`_ file on GitHub, it's written in a EBNF-like form.
+
+
+.. _`Syntax Highlight`: https://marketplace.visualstudio.com/items?itemName=andreafra.piacere-domlr
+.. _`First Order Logic`: https://en.wikipedia.org/wiki/First-order_logic
+.. _`grammar.lark`: https://github.com/andreafra/piacere-model-checker/blob/main/mc_openapi/doml_mc/domlr_parser/grammar.lark
\ No newline at end of file
diff --git a/gen_domlr_reference.py b/gen_domlr_reference.py
new file mode 100644
index 0000000000000000000000000000000000000000..336e1299b7d1360c37f962bbfea68fa4f01de43a
--- /dev/null
+++ b/gen_domlr_reference.py
@@ -0,0 +1,52 @@
+from mc_openapi.doml_mc.intermediate_model.metamodel import DOMLVersion, MetaModels
+from pprint import pprint
+from itertools import groupby
+
+DOCS_PATH = lambda version: f"docs/reference_{version}.rst"
+
+DOML_VERSIONS = [v for v in DOMLVersion]
+
+with open(DOCS_PATH('index'), 'w') as findex:
+    print("DOML Reference", file=findex)
+    print("==============\n", file=findex)
+    print("For a comprehensive list of all the classes, attributes and associations supported in the DOML Model Checker and DOMLR, please consult one of the following pages.\n", file=findex)
+
+    for version in DOML_VERSIONS:
+        v_name = f':doc:`Reference for DOML {version.value} <reference_{version.value}>`'
+        print(v_name, file=findex)
+        print('-'*len(v_name), file=findex)
+
+        with open(DOCS_PATH(version.value), 'w') as f:
+            print(f"DOML {version.value} Reference", file=f)
+            print("=============================\n", file=f)
+            
+            MM = MetaModels[version]
+            # ITEM => (package, class, assoc, attrs)
+            ITEMS = [(*(k.split("_", 1)), v.superclass, v.associations, v.attributes) for k, v in MM.items()] 
+            # PKG => CLASS => {ASSOC, ATTRS}
+            ITEMS = {k: [dict(zip(("name", "superclass", "assocs", "attrs"), (x[1], x[2], x[3], x[4]))) for x in v] for k, v in groupby(ITEMS, key=lambda x: x[0])}
+
+            for pkg, clss in ITEMS.items():
+                print(f'\n{pkg}', file=f)
+                print('^'*(len(pkg)), file=f)
+                for cls in sorted(clss, key=lambda x: x.get('name')):
+                    name = cls.get('name')
+                    supcls = cls.get('superclass')
+                    print(f'\n.. _{version.value}_{pkg}_{name}:', file=f)
+                    print(f'\n{name}', file=f)
+                    print('"'*(len(name)), file=f)
+                    if supcls:
+                        supcls_name = supcls.split("_", 1)[1]
+                        print(f'*Inherits from* :ref:`{supcls_name} <{version.value}_{supcls}>`\n', file=f)
+                    if (cls.get('assocs')):
+                        print(f'* Associations:', file=f)
+                        for assoc_k, assoc_v in cls.get('assocs').items():
+                            dest_cls = assoc_v.class_.split("_", 1)[1]
+                            print(f'\t* ``{assoc_k}`` → {dest_cls} [{assoc_v.multiplicity[0]}..{assoc_v.multiplicity[1]}]', file=f)
+                    if (cls.get('attrs')):
+                        print(f'* Attributes:', file=f)
+                        for attr_k, attr_v in cls.get('attrs').items():
+                            print(f'\t* ``{attr_k}`` [{attr_v.type}]', file=f)
+            print("\n\n", file=f)
+
+        print(f"Generated new reference for DOML {version.value} in {DOCS_PATH(version.value)}")
\ No newline at end of file
diff --git a/mc_openapi/.DS_Store b/mc_openapi/.DS_Store
new file mode 100644
index 0000000000000000000000000000000000000000..01112e0e1922d230be7ee15c2e102e5c89780591
Binary files /dev/null and b/mc_openapi/.DS_Store differ
diff --git a/mc_openapi/__init__.py b/mc_openapi/__init__.py
index 7fd229a32b5eefeffa54b9c187302d2c03a0a680..dc0a25b72c93dd2fc3e20ee0638423e5037c330a 100644
--- a/mc_openapi/__init__.py
+++ b/mc_openapi/__init__.py
@@ -1 +1 @@
-__version__ = '0.2.0'
+__version__ = '3.1.3'
diff --git a/mc_openapi/__main__.py b/mc_openapi/__main__.py
index 4289b5dfd801aafbfdaced9b7877ca948fda7523..7b91937b4b38b5b12bc986b33eae6790d7e13528 100644
--- a/mc_openapi/__main__.py
+++ b/mc_openapi/__main__.py
@@ -1,5 +1,139 @@
 #!/usr/bin/env python3
+import argparse
+import logging
+from logging.config import dictConfig
+import re
+import traceback
 
-from mc_openapi.app_config import app
+from tabulate import tabulate
+import uvicorn
 
-app.run(port=8080)
+from mc_openapi.api import app
+from mc_openapi.doml_mc import DOMLVersion, init_model, verify_csp_compatibility, verify_model, synthesize_model
+from mc_openapi.doml_mc.domlr_parser.exceptions import RequirementException
+from mc_openapi.doml_mc.mc_result import MCResult
+
+from . import __version__
+
+parser = argparse.ArgumentParser()
+
+parser.add_argument("-d", "--doml", dest="doml", help="the DOMLX file to check")
+parser.add_argument("-V", "--doml-version", dest="doml_version", help="(optional) the version used by the DOMLX file")
+parser.add_argument("-r", "--requirements", dest="requirements", help="the user-specified requirements file to check")
+parser.add_argument("-p", "--port", dest="port", type=int, default=8080, help="the port exposing the model checker REST API (default: 8080)")
+parser.add_argument("-v", "--verbose", dest="verbose", action='store_true', help="print a detailed human-readable output of everything going on. Helpful for debugging.")
+# Model Checker
+parser.add_argument("-c", "--check-consistency", dest="consistency", action='store_true', help="check on additional built-in consistency requirements")
+parser.add_argument("-S", "--skip-builtin-checks", dest="skip_builtin", action='store_true', help="skip check on built-in requirements")
+parser.add_argument("-C", "--csp", dest="csp", action='store_true', help="check compatibility with supported CSPs")
+parser.add_argument("-t", "--threads", dest="threads", type=int, default=2, help="number of threads used by the model checker")
+
+# Synthesis
+parser.add_argument("-s", "--synth", dest="synth", action='store_true', help="synthetize a new DOMLX file from requirements")
+parser.add_argument("-m", "--max-tries", dest="tries", type=int, default=8, help="max number of iteration while trying to solve the model with unbounded variables")
+
+args = parser.parse_args()
+
+def print_csp_results(results):
+    for csp_k, csp_v in results.items():
+                # Format items in minreq
+        if csp_k == 'minreq':
+            for row in csp_v:
+                for index, col in enumerate(row):
+                    if index > 0 and isinstance(col, list):
+                        row[index] = "\n".join(col)
+
+        print(tabulate(csp_v, headers='firstrow', tablefmt='fancy_grid'))
+
+if not args.doml and not args.synth:
+    dictConfig({
+        'version': 1,
+        'formatters': {'default': {
+            'format': '[%(asctime)s] %(levelname)s: %(message)s',
+        }},
+        'root': {
+            'level': 'DEBUG',
+        }
+    })
+    logging.info(f"DOML Model Checker v{__version__}")
+
+    # Start the webserver
+    uvicorn.run(app, port=args.port)
+    # No actions allowed after uvicorn startup point
+else:
+    logging.basicConfig(level=logging.DEBUG, format='* %(message)s')
+    logging.info(f"DOML Model Checker v{__version__}")
+
+    doml_path = args.doml
+    domlr_path = args.requirements
+
+    # Validate user-provided DOML version
+    doml_ver = None
+    if args.doml_version is not None:
+        try:
+            doml_ver = DOMLVersion.get(args.doml_version)
+        except:
+            # Suggest valid DOML versions
+            print(f"Unknown DOML version '{args.doml_version}'")
+            versions = [ ver.name for ver in list(DOMLVersion)]
+            print(f"Available DOML versions = {versions}")
+            exit(1)
+
+    # Read DOMLX from path
+    with open(doml_path, "rb") as xmif:
+        # Read DOML file from path
+        doml_xmi = xmif.read()
+
+    try:
+        # Read DOMLR from path
+        domlr_src = None
+        if domlr_path:
+            with open(domlr_path, "r") as domlr_file:
+            # Read the user requirements written in DSL
+                domlr_src = domlr_file.read()
+
+        # Config the model checker
+        dmc = init_model(doml_xmi, doml_ver)
+        ####### END OF INIT STEP #######
+        if not args.synth: # Verify Model/CSP Compatibility
+
+            # Check CSP Compatibility
+            if args.csp:
+                csp = verify_csp_compatibility(dmc)
+                print_csp_results(csp)
+            else:
+                
+                    res = verify_model(dmc, domlr_src, args.threads, args.consistency, args.skip_builtin)
+
+                    print("[RESULT]")
+                    if res['result'] == MCResult.sat.name:
+                        print(res['description'])
+
+                        print("[STATS]")
+                        for result in res['all_reqs']:
+                            print(f"\t{result['id']} - {result['time']} - {result['result']}")
+                    else:
+                        print(res['result'])
+                        print("[ERRORS]")
+                        print("\033[91m{}\033[00m".format(res['description']))
+
+                        print("[STATS]")
+                        for result in res['all_reqs']:
+                            print(f"\t{result['id']} - {result['time']} - {result['result']}")
+
+                    csp_res = res.get('csp')
+                    if csp_res:
+                        print("[CSP COMPATIBILITY RESULTS]")
+                        print_csp_results(csp_res)
+        else: # Synthesis
+            synthesize_model(dmc, domlr_src, args.tries)
+            # TODO: Do something with the results
+        
+    except Exception as e:
+        MSG_ERR_GENERIC = "An unknown error has occurred!\nTry with '-t 1' to get more detailed logs!\n\n"
+        err_msg = (e.message 
+                    if hasattr(e, 'message') 
+                    else MSG_ERR_GENERIC + traceback.format_exc())
+        print(f"\033[91m[ERROR]\n{err_msg}\033[00m")
+
+       
\ No newline at end of file
diff --git a/mc_openapi/api.py b/mc_openapi/api.py
new file mode 100644
index 0000000000000000000000000000000000000000..435f36a480fa4ade358d4988ba84bb2f6e328e5f
--- /dev/null
+++ b/mc_openapi/api.py
@@ -0,0 +1,110 @@
+import logging
+from logging.config import dictConfig
+import os
+import sys
+import traceback
+from importlib.resources import files
+
+from fastapi import FastAPI, Request
+from fastapi.responses import HTMLResponse, JSONResponse
+from fastapi.staticfiles import StaticFiles
+from fastapi.templating import Jinja2Templates
+from fastapi.encoders import jsonable_encoder
+from fastapi.logger import logger
+
+import mc_openapi.assets as ASSETS
+from mc_openapi.doml_mc import (init_model, verify_csp_compatibility,
+                                verify_model)
+from mc_openapi.doml_mc.exceptions import *
+from mc_openapi.doml_mc.intermediate_model.metamodel import DOMLVersion
+from mc_openapi.doml_mc.mc import ModelChecker
+import time
+
+assets = files(ASSETS)
+static_path = assets / "static"
+templates_path = assets / "templates"
+app = FastAPI()
+
+print(">>> FastAPI+Uvicorn is incredibly asinine when it comes to logs, so lines prefixed with '>>>' are actually print(...)")
+print(">>> API starting up...")
+
+app.mount("/static", StaticFiles(directory=static_path), name="static")
+
+templates = Jinja2Templates(directory=templates_path)
+
+@app.get("/", response_class=HTMLResponse)
+async def root(request: Request):
+    return templates.TemplateResponse("home.html", {"request": request})
+
+def handleDOMLX(doml_xmi: bytes, callback) -> dict:
+    doml_version_str: str = None
+    doml_version: DOMLVersion = None
+    start_time = time.time()
+    
+    print(">>> Received DOMLX. Beginning validation...")
+
+    try:
+        # First try to infer DOML version from ENV, then query params
+        doml_version_str = os.environ.get("DOML_VERSION")
+        
+        if doml_version_str:
+            doml_version = DOMLVersion.get(doml_version_str)
+            print(f">>> Forcing DOML {doml_version.value}")
+
+        dmc = init_model(doml_xmi, doml_version)
+
+        res = callback(dmc)
+
+        elapsed_time_in_seconds = f"{time.time() - start_time:.4f}"
+
+        print(f">>> Validation complete. It took {elapsed_time_in_seconds}s.")
+        res['elapsed_time'] = elapsed_time_in_seconds
+
+        return res
+    except KeyError as e:
+        ERR_MSG = f"Error: Key '{e.args[0]}' not found.\nVery likely, in the Model Checker requirements, the relationship '{e.args[0]}' is unknown.\nPerhaps this was parsed with the wrong DOML version, otherwise the DOML version you're using is currently unsupported."
+        logging.exception(e)
+        return {
+            "type": "error",
+            "message": ERR_MSG,
+            "debug_message": traceback.format_exc()
+        }
+    except (RuntimeError, Exception) as e:
+        ERR_MSG = "An error has occurred.\nIt could be an error within your DOML file.\nIf it persist, try specifying DOML version manually."
+        logging.exception(e)
+        return {
+            "type": "error",
+            "message": e.message if hasattr(e, 'message') else ERR_MSG,
+            "debug_message": traceback.format_exc()
+        }
+
+@app.post("/modelcheck")
+async def mc(request: Request):
+    doml_xmi = await request.body()
+    return handleDOMLX(doml_xmi, verify_model)
+    
+@app.post("/csp")
+async def csp(request: Request):
+    doml_xmi = await request.body()
+    return handleDOMLX(doml_xmi, verify_csp_compatibility)
+
+@app.post("/modelcheck_html")
+async def mc_html(request: Request):
+    doml_xmi = await request.body()
+    res = handleDOMLX(doml_xmi, verify_model)
+    print(res)
+    if res.get("type") == "error":
+        return templates.TemplateResponse("error.html", {"request": request, **res})
+    else:
+        return templates.TemplateResponse("mc.html", {"request": request, **res})
+  
+
+@app.post("/csp_html")
+async def csp_html(request: Request):
+    doml_xmi = await request.body()
+    res = handleDOMLX(doml_xmi, verify_csp_compatibility)
+    if res.get("type") == "error":
+        return templates.TemplateResponse("error.html", {"request": request, **res})
+    else:
+        return templates.TemplateResponse("csp.html", {"request": request, **res})
+  
\ No newline at end of file
diff --git a/mc_openapi/app_config.py b/mc_openapi/app_config.py
deleted file mode 100644
index e60da49a058797b966cf9de426f0000d98daa4e3..0000000000000000000000000000000000000000
--- a/mc_openapi/app_config.py
+++ /dev/null
@@ -1,6 +0,0 @@
-import connexion
-
-app = connexion.App(__name__, specification_dir='openapi/')
-app.add_api('model_checker.yaml')
-
-application = app.app
diff --git a/mc_openapi/assets/csp/arch.yml b/mc_openapi/assets/csp/arch.yml
new file mode 100644
index 0000000000000000000000000000000000000000..bfdc5f2611d9b7d1676fad1d337a398df10c38a8
--- /dev/null
+++ b/mc_openapi/assets/csp/arch.yml
@@ -0,0 +1,16 @@
+# CSP Name
+aws:
+  - x86
+  - x86_64
+  - ARM64
+
+gcp:
+  - x86
+  - ARM
+
+azure:
+  - x86
+  - ARM
+
+# bad_csp:
+#   - PowerPC
diff --git a/mc_openapi/assets/csp/keypair.yml b/mc_openapi/assets/csp/keypair.yml
new file mode 100644
index 0000000000000000000000000000000000000000..b9083df88b50130dc3bd1362223cb0e50f4db2a5
--- /dev/null
+++ b/mc_openapi/assets/csp/keypair.yml
@@ -0,0 +1,24 @@
+# CSP Name
+aws:
+  - RSA
+  - ED25519
+  - ECDSA
+
+
+azure:
+  - RSA
+  - RSA1_5
+  - RSA-OAEP
+  - RSA-OAEP-256
+  - EC
+  - P-256
+  - P-256K
+  - P-384
+  - P-521
+gcp: 
+  - Elliptic Curve
+  - RSA
+  - ECDSA
+
+# bad_csp:
+#   - OLD_ALGO
diff --git a/mc_openapi/assets/csp/minimum_setup.yml b/mc_openapi/assets/csp/minimum_setup.yml
new file mode 100644
index 0000000000000000000000000000000000000000..05448f3eb52dace7f685f17d2a57cc53a80dc360
--- /dev/null
+++ b/mc_openapi/assets/csp/minimum_setup.yml
@@ -0,0 +1,16 @@
+aws:
+  - infrastructure_ComputingNode::os # AMI
+  # - an Instance Type
+  # - [infrastructure_Node::ifaces, infrastructure_NetworkInterface::associated] # NetworkInterface
+  - [infrastructure_Node::ifaces, infrastructure_NetworkInterface::belongsTo] # NetworkInterface
+  - infrastructure_ComputingNode::credentials # KeyPair
+
+azure:
+  - infrastructure_ComputingNode::os # OS Image
+  - [infrastructure_Node::ifaces, infrastructure_NetworkInterface::belongsTo] # NetworkInterface
+  - infrastructure_ComputingNode::storage # Storage/VMSize
+
+gcp:
+  # - infrastructure_ComputingNode::location
+  - infrastructure_ComputingNode::os # OS Image
+  - infrastructure_ComputingNode::architecture
\ No newline at end of file
diff --git a/mc_openapi/assets/csp/os.yml b/mc_openapi/assets/csp/os.yml
new file mode 100644
index 0000000000000000000000000000000000000000..9a5060edfbe201a900bab603f44ba74a1f5a52bf
--- /dev/null
+++ b/mc_openapi/assets/csp/os.yml
@@ -0,0 +1,41 @@
+aws:
+  Linux:
+    - Amazon Linux
+    - Amazon Linux 2
+    - Bottlerocket
+    - CentOS
+    - Debian Server
+    - Oracle Linux
+    - Red Hat Enterprise Linux (RHEL)
+    - Rocky Linux
+    - SUSE Linux Enterprise Server (SLES)
+    - Ubuntu Server
+  macOS:
+    - macOS
+  Windows Server:
+    - Windows Server
+    
+azure:
+  Linux:
+    - Red Hat Enterprise Linux
+    - CentOS
+    - CoreOS
+    - Debian
+    - Oracle Linux
+    - SUSE Linux Enterprise
+    - openSUSE
+    - Ubuntu
+  Windows Server:
+    - Windows Server
+
+gcp:
+  Linux:
+    - Amazon Linux
+    - Amazon Linux 2
+    - CentOS
+    - Debian
+    - Red Hat Enterprise Linux (RHEL)
+    - SUSE Linux Enterprise
+    - Ubuntu
+  Windows Server:
+    - Windows Server
\ No newline at end of file
diff --git a/mc_openapi/assets/csp/region.yml b/mc_openapi/assets/csp/region.yml
new file mode 100644
index 0000000000000000000000000000000000000000..8b9e1d62578265a61dd0eb2130c04bd6d5548b54
--- /dev/null
+++ b/mc_openapi/assets/csp/region.yml
@@ -0,0 +1,174 @@
+aws:
+  - us-east-2
+  - us-east-1
+  - us-west-1
+  - us-west-2
+  - af-south-1
+  - ap-east-1
+  - ap-south-2
+  - ap-southeast-3
+  - ap-southeast-4
+  - ap-south-1
+  - ap-northeast-3
+  - ap-northeast-2
+  - ap-southeast-1
+  - ap-southeast-2
+  - ap-northeast-1
+  - ca-central-1
+  - eu-central-1
+  - eu-west-1
+  - eu-west-2
+  - eu-south-1
+  - eu-west-3
+  - eu-south-2
+  - eu-north-1
+  - eu-central-2
+  - me-south-1
+  - me-central-1
+  - sa-east-1
+  - us-gov-east-1
+  - us-gov-west-1
+
+gcp:
+  - asia-east1-a
+  - asia-east1-b
+  - asia-east1-c
+  - asia-east2-a
+  - asia-east2-b
+  - asia-east2-c
+  - asia-northeast1-a
+  - asia-northeast1-b
+  - asia-northeast1-c
+  - asia-northeast2-a
+  - asia-northeast2-b
+  - asia-northeast2-c
+  - asia-northeast3-a
+  - asia-northeast3-b
+  - asia-northeast3-c
+  - asia-south1-a
+  - asia-south1-b
+  - asia-south1-c
+  - asia-south2-a
+  - asia-south2-b
+  - asia-south2-c
+  - asia-southeast1-a
+  - asia-southeast1-b
+  - asia-southeast1-c
+  - asia-southeast2-a
+  - asia-southeast2-b
+  - asia-southeast2-c
+  - australia-southeast1-a
+  - australia-southeast1-b
+  - australia-southeast1-c
+  - australia-southeast2-a
+  - australia-southeast2-b
+  - australia-southeast2-c
+  - europe-central2-a
+  - europe-central2-b
+  - europe-central2-c
+  - europe-north1-a
+  - europe-north1-b
+  - europe-north1-c
+  - europe-southwest1-a
+  - europe-southwest1-b
+  - europe-southwest1-c
+  - europe-west1-b
+  - europe-west1-c
+  - europe-west1-d
+  - europe-west2-a
+  - europe-west2-b
+  - europe-west2-c
+  - europe-west3-a
+  - europe-west3-b
+  - europe-west3-c
+  - europe-west4-a
+  - europe-west4-b
+  - europe-west4-c
+  - europe-west6-a
+  - europe-west6-b
+  - europe-west6-c
+  - europe-west8-a
+  - europe-west8-b
+  - europe-west8-c
+  - europe-west9-a
+  - europe-west9-b
+  - europe-west9-c
+  - me-west1-a
+  - me-west1-b
+  - me-west1-c
+  - northamerica-northeast1-a
+  - northamerica-northeast1-b
+  - northamerica-northeast1-c
+  - northamerica-northeast2-a
+  - northamerica-northeast2-b
+  - northamerica-northeast2-c
+  - southamerica-east1-a
+  - southamerica-east1-b
+  - southamerica-east1-c
+  - southamerica-west1-a
+  - southamerica-west1-b
+  - southamerica-west1-c
+  - us-central1-a
+  - us-central1-b
+  - us-central1-c
+  - us-central1-f
+  - us-east1-b
+  - us-east1-c
+  - us-east1-d
+  - us-east4-a
+  - us-east4-b
+  - us-east4-c
+  - us-east5-a
+  - us-east5-b
+  - us-east5-c
+  - us-south1-a
+  - us-south1-b
+  - us-south1-c
+  - us-west1-a
+  - us-west1-b
+  - us-west1-c
+  - us-west2-a
+  - us-west2-b
+  - us-west2-c
+  - us-west3-a
+  - us-west3-b
+  - us-west3-c
+  - us-west4-a
+  - us-west4-b
+  - us-west4-c
+
+azure:
+  - eastasia
+  - southeastasia
+  - centralus
+  - eastus
+  - eastus2
+  - westus
+  - northcentralus
+  - southcentralus
+  - northeurope
+  - westeurope
+  - japanwest
+  - japaneast
+  - brazilsouth
+  - australiaeast
+  - australiasoutheast
+  - southindia
+  - centralindia
+  - westindia
+  - canadacentral
+  - canadaeast
+  - uksouth
+  - ukwest
+  - westcentralus
+  - westus2
+  - koreacentral
+  - koreasouth
+  - francecentral
+  - francesouth
+  - australiacentral
+  - australiacentral2
+  - uaecentral
+  - uaenorth
+  - southafricanorth
+  - southafricawest
\ No newline at end of file
diff --git a/mc_openapi/assets/doml_meta.yaml b/mc_openapi/assets/metamodels/doml_meta_v1.0.yaml
similarity index 100%
rename from mc_openapi/assets/doml_meta.yaml
rename to mc_openapi/assets/metamodels/doml_meta_v1.0.yaml
diff --git a/mc_openapi/assets/metamodels/doml_meta_v2.0.yaml b/mc_openapi/assets/metamodels/doml_meta_v2.0.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..08cc7176fbeda1681e86fbc37afa83080423522c
--- /dev/null
+++ b/mc_openapi/assets/metamodels/doml_meta_v2.0.yaml
@@ -0,0 +1,485 @@
+commons:
+    DOMLElement:
+        attributes:
+            name:
+                type: String
+                multiplicity: "0..1"
+            description:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            annotations:
+                class: commons_Property
+                multiplicity: "0..*"
+    Property:
+        attributes:
+            key:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            reference:
+                class: commons_DOMLElement
+                multiplicity: "0..1"
+    IProperty:
+        superclass: commons_Property
+        attributes:
+            value:
+                type: Integer
+                multiplicity: "0..1"
+    SProperty:
+        superclass: commons_Property
+        attributes:
+            value:
+                type: String
+                multiplicity: "0..1"
+    FProperty:
+        superclass: commons_Property
+        attributes:
+            value:
+                type: String
+                multiplicity: "0..1"
+    BProperty:
+        superclass: commons_Property
+        attributes:
+            value:
+                type: Boolean
+                multiplicity: "0..1"
+    Configuration:
+        superclass: commons_DOMLElement
+        associations:
+            deployments:
+                class: commons_Deployment
+                multiplicity: "0..*"
+    Deployment:
+        associations:
+            component:
+                class: application_ApplicationComponent
+                multiplicity: "1"
+            node:
+                class: infrastructure_InfrastructureElement
+                multiplicity: "1"
+
+application:
+    ApplicationLayer:
+        superclass: commons_DOMLElement
+        associations:
+            components:
+                class: application_ApplicationComponent
+                multiplicity: "0..*"
+    ApplicationComponent:
+        superclass: commons_DOMLElement
+    SoftwareComponent:
+        superclass: application_ApplicationComponent
+        attributes:
+            isPersistent:
+                type: Boolean
+                multiplicity: "1"
+                default: false
+            licenseCost:
+                type: String
+                multiplicity: "0..1"
+            configFile:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            exposedInterfaces:
+                class: application_SoftwareInterface
+                multiplicity: "0..*"
+            consumedInterfaces:
+                class: application_SoftwareInterface
+                multiplicity: "0..*"
+    SaaS:
+        superclass: application_ApplicationComponent
+        attributes:
+            licenseCost:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            exposedInterfaces:
+                class: application_SoftwareInterface
+                multiplicity: "0..*"
+    SoftwareInterface:
+        superclass: application_ApplicationComponent
+        attributes:
+            endPoint:
+                type: String
+                multiplicity: "0..1"
+    DBMS:
+        superclass: application_SoftwareComponent
+    SaaSDBMS:
+        superclass: application_SaaS
+
+infrastructure:
+    InfrastructureLayer:
+        superclass: commons_DOMLElement
+        associations:
+            nodes:
+                class: infrastructure_ComputingNode
+                multiplicity: "0..*"
+            generators:
+                class: infrastructure_ComputingNodeGenerator
+                multiplicity: "0..*"
+            storages:
+                class: infrastructure_Storage
+                multiplicity: "0..*"
+            faas:
+                class: infrastructure_FunctionAsAService
+                multiplicity: "0..*"
+            credentials:
+                class: infrastructure_Credentials
+                multiplicity: "0..*"
+            groups:
+                class: infrastructure_ComputingGroup
+                multiplicity: "0..*"
+            securityGroups:
+                class: infrastructure_SecurityGroup
+                multiplicity: "0..*"
+            networks:
+                class: infrastructure_Network
+                multiplicity: "0..*"
+    InfrastructureElement:
+        superclass: commons_DOMLElement
+    ComputingNode:
+        superclass: infrastructure_InfrastructureElement
+        attributes:
+            architecture: 
+                type: String 
+                multiplicity: "0..1"
+            os: 
+                type: String 
+                multiplicity: "0..1"
+            memory_mb:
+                type: Integer 
+                multiplicity: "0..1"
+            memory_kb:  # Missing in official Ecore, added by parser
+                type: Integer 
+                multiplicity: "0..1"
+            storage: 
+                type: String 
+                multiplicity: "0..1"
+            cpu_count: 
+                type: Integer 
+                multiplicity: "0..1"
+            cost: 
+                type: Integer  # in cents 
+                multiplicity: "0..1"
+        associations:
+            ifaces:
+                class: infrastructure_NetworkInterface
+                multiplicity: "0..*"
+            location:
+                class: infrastructure_Location
+                multiplicity: "0..1"
+            credentials:
+                class: infrastructure_Credentials
+                multiplicity: "0..1"
+            group:
+                class: infrastructure_ComputingGroup
+                multiplicity: "0..1"
+                inverse_of: infrastructure_ComputingGroup::groupedNodes
+    PhysicalComputingNode:
+        superclass: infrastructure_ComputingNode
+    VirtualMachine:
+        superclass: infrastructure_ComputingNode
+        attributes:
+            sizeDescription:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            generatedFrom:
+                class: infrastructure_VMImage
+                multiplicity: "0..1"
+    Location:
+        superclass: commons_DOMLElement
+        attributes:
+            region:
+                type: String
+                multiplicity: "0..1"
+            zone:
+                type: String
+                multiplicity: "0..1"
+    Container:
+        superclass: infrastructure_ComputingNode
+        associations:
+            generatedFrom:
+                class: infrastructure_ContainerImage
+                multiplicity: "0..1"
+            hosts:
+                class: infrastructure_ComputingNode
+                multiplicity: "0..*"
+    ComputingNodeGenerator:
+        superclass: commons_DOMLElement
+        attributes:
+            uri:
+                type: String
+                multiplicity: "0..1"
+            kind:
+                type: GeneratorKind  # enum { SCRIPT, IMAGE }
+    VMImage:
+        superclass: infrastructure_ComputingNodeGenerator
+        associations:
+            generatedVMs:
+                class: infrastructure_VirtualMachine
+                multiplicity: "0..*"
+                inverse_of: infrastructure_VirtualMachine::generatedFrom
+    ContainerImage:
+        superclass: infrastructure_ComputingNodeGenerator
+        associations:
+            generatedContainers:
+                class: infrastructure_Container
+                multiplicity: "0..*"
+                inverse_of: infrastructure_Container::generatedFrom
+    AutoScalingGroup:
+        superclass: infrastructure_ComputingGroup
+        attributes:
+            min:
+                type: Integer
+                multiplicity: "0..1"
+            max:
+                type: Integer
+                multiplicity: "0..1"
+            loadBalancer:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            machineDefinition:
+                class: infrastructure_VirtualMachine
+                multiplicity: "1"
+            deploymentNetwork:
+                class: infrastructure_Network
+                multiplicity: "0..1"
+            securityGroup:
+                class: infrastructure_SecurityGroup
+                multiplicity: "0..1"
+    Storage:
+        superclass: infrastructure_InfrastructureElement
+        attributes:
+            label:
+                type: String
+                multiplicity: "0..1"
+            size_gb:
+                type: Integer  # in GBs
+                multiplicity: "0..1"
+            cost: 
+                type: Integer  # in cents 
+                multiplicity: "0..1"
+        associations:
+            ifaces:
+                class: infrastructure_NetworkInterface
+                multiplicity: "0..*"
+    FunctionAsAService:
+        superclass: infrastructure_InfrastructureElement
+        attributes:
+            cost:
+                type: Integer  # in cents
+                multiplicity: "0..1"
+        associations:
+            ifaces:
+                class: infrastructure_NetworkInterface
+                multiplicity: "0..*"
+    Network:
+        superclass: commons_DOMLElement
+        attributes:
+            protocol:
+                type: String
+                multiplicity: "0..1"
+            address_lb:
+                type: Integer
+                multiplicity: "0..1"
+            address_ub:
+                type: Integer
+                multiplicity: "0..1"
+        associations:
+            connectedIfaces:
+                class: infrastructure_NetworkInterface
+                multiplicity: "0..*"
+                inverse_of: infrastructure_NetworkInterface::belongsTo
+            igws:
+                class: infrastructure_InternetGateway
+                multiplicity: "0..*"
+            subnets:
+                class: infrastructure_Subnet
+                multiplicity: "0..*"
+    Subnet:
+        superclass: infrastructure_Network
+        associations:
+            connectedTo:
+                class: infrastructure_Network
+                multiplicity: "0..1"
+    NetworkInterface:
+        superclass: infrastructure_InfrastructureElement
+        attributes:
+            endPoint:
+                type: Integer
+                multiplicity: "0..1"
+            speed:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            belongsTo:
+                class: infrastructure_Network
+                multiplicity: "0..1" # This should be "1", but it would break InternetGateway
+            associated:
+                class: infrastructure_SecurityGroup
+                multiplicity: "0..1" # TODO: try putting this to 1 and see why it fails
+    InternetGateway:
+        superclass: infrastructure_NetworkInterface
+    ComputingGroup:
+        superclass: commons_DOMLElement
+        associations:
+            groupedNodes:
+                class: infrastructure_ComputingNode
+                multiplicity: "0..*"
+                inverse_of: infrastructure_ComputingNode::group
+    SecurityGroup:
+        superclass: commons_DOMLElement
+        associations:
+            rules:
+                class: infrastructure_Rule
+                multiplicity: "0..*"
+            ifaces:
+                class: infrastructure_NetworkInterface
+                multiplicity: "0..*"
+                inverse_of: infrastructure_NetworkInterface::associated
+    Rule:
+        superclass: commons_DOMLElement
+        attributes:
+            kind:
+                type: String
+                multiplicity: "1"
+            protocol:
+                type: String
+                multiplicity: "1"
+            fromPort:
+                type: Integer
+                multiplicity: "1"
+            toPort:
+                type: Integer
+                multiplicity: "1"
+            cidr:
+                type: String
+                multiplicity: "0..*"
+    Credentials:
+        superclass: commons_DOMLElement
+    KeyPair:
+        superclass: infrastructure_Credentials
+        attributes:
+            user:
+                type: String
+                multiplicity: "0..1"
+            keyfile:
+                type: String
+                multiplicity: "0..1"
+            algorithm:
+                type: String
+                multiplicity: "0..1"
+            bits:
+                type: Integer
+                multiplicity: "0..1"
+    UserPass:
+        superclass: infrastructure_Credentials
+        attributes:
+            username:
+                type: String
+                multiplicity: "1"
+            password:
+                type: String
+                multiplicity: "1"
+    SwarmRole:
+        superclass: commons_DOMLElement
+        attributes:
+            kind:
+                type: String
+                multiplicity: "1"
+        associations:
+            nodes:
+                class: infrastructure_ComputingNode
+                multiplicity: "0..*"
+    Swarm:
+        superclass: infrastructure_ComputingGroup
+        associations:
+            roles:
+                class: infrastructure_SwarmRole
+                multiplicity: "0..*"
+    ExtInfrastructureElement:
+        superclass: infrastructure_InfrastructureElement
+
+concrete:
+    ConcreteInfrastructure:
+        superclass: commons_DOMLElement
+        associations:
+            providers:
+                class: concrete_RuntimeProvider
+                multiplicity: "0..*"
+    ConcreteElement:
+        superclass: commons_DOMLElement
+        attributes:
+            configurationScript:
+                type: String
+                multiplicity: "0..1"
+    RuntimeProvider:
+        superclass: commons_DOMLElement
+        associations:
+            vms:
+                class: concrete_VirtualMachine
+                multiplicity: "0..*"
+            vmImages:
+                class: concrete_VMImage
+                multiplicity: "0..*"
+            containerImages:
+                class: concrete_ContainerImage
+                multiplicity: "0..*"
+            networks:
+                class: concrete_Network
+                multiplicity: "0..*"
+            storages:
+                class: concrete_Storage
+                multiplicity: "0..*"
+            faas:
+                class: concrete_FunctionAsAService
+                multiplicity: "0..*"
+            group:
+                class: concrete_ComputingGroup
+                multiplicity: "0..*"
+    VirtualMachine:
+        superclass: concrete_ConcreteElement
+        associations:
+            maps:
+                class: infrastructure_VirtualMachine
+                multiplicity: "0..1"
+    VMImage:
+        superclass: concrete_ConcreteElement
+        associations:
+            maps:
+                class: infrastructure_VMImage
+                multiplicity: "0..1"
+    ContainerImage:
+        superclass: concrete_ConcreteElement
+        associations:
+            maps:
+                class: infrastructure_ContainerImage
+                multiplicity: "0..1"
+    Network:
+        superclass: concrete_ConcreteElement
+        associations:
+            maps:
+                class: infrastructure_Network
+                multiplicity: "0..1"
+    Storage:
+        superclass: concrete_ConcreteElement
+        associations:
+            maps:
+                class: infrastructure_Storage
+                multiplicity: "0..1"
+    FunctionAsAService:
+        superclass: concrete_ConcreteElement
+        associations:
+            maps:
+                class: infrastructure_FunctionAsAService
+                multiplicity: "0..1"
+    ComputingGroup:
+        superclass: concrete_ConcreteElement
+        associations:
+            maps:
+                class: infrastructure_ComputingGroup
+                multiplicity: "1"
diff --git a/mc_openapi/assets/metamodels/doml_meta_v2.1.yaml b/mc_openapi/assets/metamodels/doml_meta_v2.1.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..cba1f52489abb62aa049084c03073473715d3b81
--- /dev/null
+++ b/mc_openapi/assets/metamodels/doml_meta_v2.1.yaml
@@ -0,0 +1,502 @@
+commons:
+    DOMLElement:
+        attributes:
+            name:
+                type: String
+                multiplicity: "0..1"
+            description:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            annotations:
+                class: commons_Property
+                multiplicity: "0..*"
+    Property:
+        attributes:
+            key:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            reference:
+                class: commons_DOMLElement
+                multiplicity: "0..1"
+    IProperty:
+        superclass: commons_Property
+        attributes:
+            value:
+                type: Integer
+                multiplicity: "0..1"
+    SProperty:
+        superclass: commons_Property
+        attributes:
+            value:
+                type: String
+                multiplicity: "0..1"
+    FProperty:
+        superclass: commons_Property
+        attributes:
+            value:
+                type: String
+                multiplicity: "0..1"
+    BProperty:
+        superclass: commons_Property
+        attributes:
+            value:
+                type: Boolean
+                multiplicity: "0..1"
+    Configuration:
+        superclass: commons_DOMLElement
+        associations:
+            deployments:
+                class: commons_Deployment
+                multiplicity: "0..*"
+    Deployment:
+        associations:
+            component:
+                class: application_ApplicationComponent
+                multiplicity: "1"
+            node:
+                class: infrastructure_InfrastructureElement
+                multiplicity: "1"
+
+application:
+    ApplicationLayer:
+        superclass: commons_DOMLElement
+        associations:
+            components:
+                class: application_ApplicationComponent
+                multiplicity: "0..*"
+    ApplicationComponent:
+        superclass: commons_DOMLElement
+    SoftwareComponent:
+        superclass: application_ApplicationComponent
+        attributes:
+            isPersistent:
+                type: Boolean
+                multiplicity: "1"
+                default: false
+            licenseCost:
+                type: String
+                multiplicity: "0..1"
+            configFile:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            exposedInterfaces:
+                class: application_SoftwareInterface
+                multiplicity: "0..*"
+            consumedInterfaces:
+                class: application_SoftwareInterface
+                multiplicity: "0..*"
+    SaaS:
+        superclass: application_ApplicationComponent
+        attributes:
+            licenseCost:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            exposedInterfaces:
+                class: application_SoftwareInterface
+                multiplicity: "0..*"
+    SoftwareInterface:
+        superclass: application_ApplicationComponent
+        attributes:
+            endPoint:
+                type: String
+                multiplicity: "0..1"
+    DBMS:
+        superclass: application_SoftwareComponent
+    SaaSDBMS:
+        superclass: application_SaaS
+
+infrastructure:
+    InfrastructureLayer:
+        superclass: commons_DOMLElement
+        associations:
+            nodes:
+                class: infrastructure_ComputingNode
+                multiplicity: "0..*"
+            generators:
+                class: infrastructure_ComputingNodeGenerator
+                multiplicity: "0..*"
+            storages:
+                class: infrastructure_Storage
+                multiplicity: "0..*"
+            faas:
+                class: infrastructure_FunctionAsAService
+                multiplicity: "0..*"
+            credentials:
+                class: infrastructure_Credentials
+                multiplicity: "0..*"
+            groups:
+                class: infrastructure_ComputingGroup
+                multiplicity: "0..*"
+            securityGroups:
+                class: infrastructure_SecurityGroup
+                multiplicity: "0..*"
+            networks:
+                class: infrastructure_Network
+                multiplicity: "0..*"
+    InfrastructureElement:
+        superclass: commons_DOMLElement
+    ComputingNode:
+        superclass: infrastructure_InfrastructureElement
+        attributes:
+            architecture: 
+                type: String 
+                multiplicity: "0..1"
+            os: 
+                type: String 
+                multiplicity: "0..1"
+            memory_mb:
+                type: Integer 
+                multiplicity: "0..1"
+            memory_kb:  # Missing in official Ecore, added by parser
+                type: Integer 
+                multiplicity: "0..1"
+            storage: 
+                type: String 
+                multiplicity: "0..1"
+            cpu_count: 
+                type: Integer 
+                multiplicity: "0..1"
+            cost: 
+                type: Integer  # in cents 
+                multiplicity: "0..1"
+        associations:
+            ifaces:
+                class: infrastructure_NetworkInterface
+                multiplicity: "0..*"
+            location:
+                class: infrastructure_Location
+                multiplicity: "0..1"
+            credentials:
+                class: infrastructure_Credentials
+                multiplicity: "0..1"
+            group:
+                class: infrastructure_ComputingGroup
+                multiplicity: "0..1"
+                inverse_of: infrastructure_ComputingGroup::groupedNodes
+    PhysicalComputingNode:
+        superclass: infrastructure_ComputingNode
+    VirtualMachine:
+        superclass: infrastructure_ComputingNode
+        attributes:
+            sizeDescription:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            generatedFrom:
+                class: infrastructure_VMImage
+                multiplicity: "0..1"
+    Location:
+        superclass: commons_DOMLElement
+        attributes:
+            region:
+                type: String
+                multiplicity: "0..1"
+            zone:
+                type: String
+                multiplicity: "0..1"
+    ContainerConfig:
+        superclass: commons_DOMLElement
+        attributes:
+            container_port:
+                type: Integer
+                multiplicity: "0..1"
+            vm_port:
+                type: Integer
+                multiplicity: "0..1"
+        associations:
+            host:
+                class: infrastructure_ComputingNode
+                multiplicity: "0..1"
+            iface:
+                class: infrastructure_NetworkInterface
+                multiplicity: "0..1"
+    Container:
+        superclass: infrastructure_ComputingNode
+        associations:
+            generatedFrom:
+                class: infrastructure_ContainerImage
+                multiplicity: "0..1"
+            configs:
+                class: infrastructure_ContainerConfig
+                multiplicity: "0..*"
+    ComputingNodeGenerator:
+        superclass: commons_DOMLElement
+        attributes:
+            uri:
+                type: String
+                multiplicity: "0..1"
+            kind:
+                type: GeneratorKind  # enum { SCRIPT, IMAGE }
+    VMImage:
+        superclass: infrastructure_ComputingNodeGenerator
+        associations:
+            generatedVMs:
+                class: infrastructure_VirtualMachine
+                multiplicity: "0..*"
+                inverse_of: infrastructure_VirtualMachine::generatedFrom
+    ContainerImage:
+        superclass: infrastructure_ComputingNodeGenerator
+        associations:
+            generatedContainers:
+                class: infrastructure_Container
+                multiplicity: "0..*"
+                inverse_of: infrastructure_Container::generatedFrom
+    AutoScalingGroup:
+        superclass: infrastructure_ComputingGroup
+        attributes:
+            min:
+                type: Integer
+                multiplicity: "0..1"
+            max:
+                type: Integer
+                multiplicity: "0..1"
+            loadBalancer:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            machineDefinition:
+                class: infrastructure_VirtualMachine
+                multiplicity: "1"
+            securityGroup:
+                class: infrastructure_SecurityGroup
+                multiplicity: "0..1"
+    Storage:
+        superclass: infrastructure_InfrastructureElement
+        attributes:
+            label:
+                type: String
+                multiplicity: "0..1"
+            size_gb:
+                type: Integer  # in GBs
+                multiplicity: "0..1"
+            cost: 
+                type: Integer  # in cents 
+                multiplicity: "0..1"
+        associations:
+            ifaces:
+                class: infrastructure_NetworkInterface
+                multiplicity: "0..*"
+    FunctionAsAService:
+        superclass: infrastructure_InfrastructureElement
+        attributes:
+            cost:
+                type: Integer  # in cents
+                multiplicity: "0..1"
+        associations:
+            ifaces:
+                class: infrastructure_NetworkInterface
+                multiplicity: "0..*"
+    Network:
+        superclass: commons_DOMLElement
+        attributes:
+            protocol:
+                type: String
+                multiplicity: "0..1"
+            addressRange:
+                type: String
+                multiplicity: "0..1"
+            cidr:
+                type: Integer
+                multiplicity: "0..1"
+        associations:
+            connectedIfaces:
+                class: infrastructure_NetworkInterface
+                multiplicity: "0..*"
+                inverse_of: infrastructure_NetworkInterface::belongsTo
+            igws:
+                class: infrastructure_InternetGateway
+                multiplicity: "0..*"
+            subnets:
+                class: infrastructure_Subnet
+                multiplicity: "0..*"
+    Subnet:
+        superclass: infrastructure_Network
+        associations:
+            connectedTo:
+                class: infrastructure_Network
+                multiplicity: "0..1"
+    NetworkInterface:
+        superclass: infrastructure_InfrastructureElement
+        attributes:
+            endPoint:
+                type: Integer
+                multiplicity: "0..1"
+            speed:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            belongsTo:
+                class: infrastructure_Network
+                multiplicity: "0..1" # This should be "1", but it would break InternetGateway
+            associated:
+                class: infrastructure_SecurityGroup
+                multiplicity: "0..1" # TODO: try putting this to 1 and see why it fails
+    InternetGateway:
+        superclass: infrastructure_NetworkInterface
+    ComputingGroup:
+        superclass: commons_DOMLElement
+        associations:
+            groupedNodes:
+                class: infrastructure_ComputingNode
+                multiplicity: "0..*"
+                inverse_of: infrastructure_ComputingNode::group
+    SecurityGroup:
+        superclass: commons_DOMLElement
+        associations:
+            rules:
+                class: infrastructure_Rule
+                multiplicity: "0..*"
+            ifaces:
+                class: infrastructure_NetworkInterface
+                multiplicity: "0..*"
+                inverse_of: infrastructure_NetworkInterface::associated
+    Rule:
+        superclass: commons_DOMLElement
+        attributes:
+            kind:
+                type: String
+                multiplicity: "1"
+            protocol:
+                type: String
+                multiplicity: "1"
+            fromPort:
+                type: Integer
+                multiplicity: "1"
+            toPort:
+                type: Integer
+                multiplicity: "1"
+            cidr:
+                type: String
+                multiplicity: "0..*"
+    Credentials:
+        superclass: commons_DOMLElement
+    KeyPair:
+        superclass: infrastructure_Credentials
+        attributes:
+            user:
+                type: String
+                multiplicity: "0..1"
+            keyfile:
+                type: String
+                multiplicity: "0..1"
+            algorithm:
+                type: String
+                multiplicity: "0..1"
+            bits:
+                type: Integer
+                multiplicity: "0..1"
+    UserPass:
+        superclass: infrastructure_Credentials
+        attributes:
+            username:
+                type: String
+                multiplicity: "1"
+            password:
+                type: String
+                multiplicity: "1"
+    SwarmRole:
+        superclass: commons_DOMLElement
+        attributes:
+            kind:
+                type: String
+                multiplicity: "1"
+        associations:
+            nodes:
+                class: infrastructure_ComputingNode
+                multiplicity: "0..*"
+    Swarm:
+        superclass: infrastructure_ComputingGroup
+        associations:
+            roles:
+                class: infrastructure_SwarmRole
+                multiplicity: "0..*"
+    ExtInfrastructureElement:
+        superclass: infrastructure_InfrastructureElement
+
+concrete:
+    ConcreteInfrastructure:
+        superclass: commons_DOMLElement
+        associations:
+            providers:
+                class: concrete_RuntimeProvider
+                multiplicity: "0..*"
+    ConcreteElement:
+        superclass: commons_DOMLElement
+        attributes:
+            configurationScript:
+                type: String
+                multiplicity: "0..1"
+    RuntimeProvider:
+        superclass: commons_DOMLElement
+        associations:
+            vms:
+                class: concrete_VirtualMachine
+                multiplicity: "0..*"
+            vmImages:
+                class: concrete_VMImage
+                multiplicity: "0..*"
+            containerImages:
+                class: concrete_ContainerImage
+                multiplicity: "0..*"
+            networks:
+                class: concrete_Network
+                multiplicity: "0..*"
+            storages:
+                class: concrete_Storage
+                multiplicity: "0..*"
+            faas:
+                class: concrete_FunctionAsAService
+                multiplicity: "0..*"
+            group:
+                class: concrete_ComputingGroup
+                multiplicity: "0..*"
+    VirtualMachine:
+        superclass: concrete_ConcreteElement
+        associations:
+            maps:
+                class: infrastructure_VirtualMachine
+                multiplicity: "0..1"
+    VMImage:
+        superclass: concrete_ConcreteElement
+        associations:
+            maps:
+                class: infrastructure_VMImage
+                multiplicity: "0..1"
+    ContainerImage:
+        superclass: concrete_ConcreteElement
+        associations:
+            maps:
+                class: infrastructure_ContainerImage
+                multiplicity: "0..1"
+    Network:
+        superclass: concrete_ConcreteElement
+        attributes:
+            address:
+                type: Integer
+                multiplicity: "0..1"
+        associations:
+            maps:
+                class: infrastructure_Network
+                multiplicity: "0..1"
+    Storage:
+        superclass: concrete_ConcreteElement
+        associations:
+            maps:
+                class: infrastructure_Storage
+                multiplicity: "0..1"
+    FunctionAsAService:
+        superclass: concrete_ConcreteElement
+        associations:
+            maps:
+                class: infrastructure_FunctionAsAService
+                multiplicity: "0..1"
+    ComputingGroup:
+        superclass: concrete_ConcreteElement
+        associations:
+            maps:
+                class: infrastructure_ComputingGroup
+                multiplicity: "1"
diff --git a/mc_openapi/assets/metamodels/doml_meta_v2.2.1.yaml b/mc_openapi/assets/metamodels/doml_meta_v2.2.1.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..b30e3273d81c4f15e6acab16883d400a1e2ddbc6
--- /dev/null
+++ b/mc_openapi/assets/metamodels/doml_meta_v2.2.1.yaml
@@ -0,0 +1,552 @@
+commons:
+    DOMLElement:
+        attributes:
+            name:
+                type: String
+                multiplicity: "0..1"
+            description:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            annotations:
+                class: commons_Property
+                multiplicity: "0..*"
+    Property:
+        attributes:
+            key:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            reference:
+                class: commons_DOMLElement
+                multiplicity: "0..1"
+    IProperty:
+        superclass: commons_Property
+        attributes:
+            value:
+                type: Integer
+                multiplicity: "0..1"
+    SProperty:
+        superclass: commons_Property
+        attributes:
+            value:
+                type: String
+                multiplicity: "0..1"
+    FProperty:
+        superclass: commons_Property
+        attributes:
+            value:
+                type: String
+                multiplicity: "0..1"
+    BProperty:
+        superclass: commons_Property
+        attributes:
+            value:
+                type: Boolean
+                multiplicity: "0..1"
+    Configuration:
+        superclass: commons_DOMLElement
+        associations:
+            deployments:
+                class: commons_Deployment
+                multiplicity: "0..*"
+    Credentials:
+        abstract: true
+        superclass: commons_DOMLElement
+    DeployableElement:
+        abstract: true
+        superclass: commons_DOMLElement # It's not present in the ECore, but without it breaks.
+    Deployment:
+        associations:
+            component:
+                class: commons_DeployableElement
+                multiplicity: "1"
+            node:
+                class: infrastructure_InfrastructureElement
+                multiplicity: "1"
+    KeyPair:
+        superclass: commons_Credentials
+        attributes:
+            user:
+                type: String
+                multiplicity: "0..1"
+            keyfile:
+                type: String
+                multiplicity: "0..1"
+            algorithm:
+                type: String
+                multiplicity: "0..1"
+            bits:
+                type: Integer
+                multiplicity: "0..1"
+    UserPass:
+        superclass: commons_Credentials
+        attributes:
+            username:
+                type: String
+                multiplicity: "0..1"
+            password:
+                type: String
+                multiplicity: "0..1"
+    Source:
+        superclass: commons_DOMLElement
+        attributes:
+            entry:
+                type: String
+                multiplicity: "0..*"
+            backend:
+                type: String
+                multiplicity: "0..*"
+application:
+    ApplicationLayer:
+        superclass: commons_DOMLElement
+        associations:
+            components:
+                class: application_ApplicationComponent
+                multiplicity: "0..*"
+    ApplicationComponent:
+        superclass: commons_DeployableElement # and commons_DOMLElement too, but that's definitely wrong; keeping discarding DOMLElement since DeplElem inherits it.
+    SoftwareComponent:
+        superclass: application_ApplicationComponent
+        attributes:
+            isPersistent:
+                type: Boolean
+                multiplicity: "1"
+                default: false
+            licenseCost:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            exposedInterfaces:
+                class: application_SoftwareInterface
+                multiplicity: "0..*"
+            consumedInterfaces:
+                class: application_SoftwareInterface
+                multiplicity: "0..*"
+            src:
+                class: commons_Source
+                multiplicity: "0..1"
+    SaaS:
+        superclass: application_ApplicationComponent
+        attributes:
+            licenseCost:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            exposedInterfaces:
+                class: application_SoftwareInterface
+                multiplicity: "0..*"
+    SoftwareInterface:
+        superclass: application_ApplicationComponent
+        attributes:
+            endPoint:
+                type: String
+                multiplicity: "0..1"
+    DBMS:
+        superclass: application_SoftwareComponent
+    SaaSDBMS:
+        superclass: application_SaaS
+
+infrastructure:
+    InfrastructureLayer:
+        superclass: commons_DOMLElement
+        associations:
+            nodes:
+                class: infrastructure_ComputingNode
+                multiplicity: "0..*"
+            generators:
+                class: infrastructure_ComputingNodeGenerator
+                multiplicity: "0..*"
+            storages:
+                class: infrastructure_Storage
+                multiplicity: "0..*"
+            faas:
+                class: infrastructure_FunctionAsAService
+                multiplicity: "0..*"
+            credentials:
+                class: commons_Credentials
+                multiplicity: "0..*"
+            groups:
+                class: infrastructure_ComputingGroup
+                multiplicity: "0..*"
+            securityGroups:
+                class: infrastructure_SecurityGroup
+                multiplicity: "0..*"
+            networks:
+                class: infrastructure_Network
+                multiplicity: "0..*"
+            rules:
+                class: infrastructure_MonitoringRule
+                multiplicity: "0..*"
+    MonitoringRule:
+        superclass: commons_DOMLElement
+        attributes:
+            condition:
+                type: String 
+                multiplicity: "1"
+            strategy:
+                type: String 
+                multiplicity: "1"
+            strategyConfigurationString:
+                type: String 
+                multiplicity: "0..1"
+    InfrastructureElement:
+        superclass: commons_DeployableElement
+    ComputingNode:
+        superclass: infrastructure_InfrastructureElement
+        attributes:
+            architecture: 
+                type: String 
+                multiplicity: "0..1"
+            os: 
+                type: String 
+                multiplicity: "0..1"
+            memory_mb:
+                type: Integer 
+                multiplicity: "0..1"
+            memory_kb:  # Missing in official Ecore, added by parser
+                type: Integer 
+                multiplicity: "0..1"
+            storage: 
+                type: String 
+                multiplicity: "0..1"
+            cpu_count: 
+                type: Integer 
+                multiplicity: "0..1"
+            cost: 
+                type: Integer  # in cents 
+                multiplicity: "0..1"
+            disabledMonitorings:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            ifaces:
+                class: infrastructure_NetworkInterface
+                multiplicity: "0..*"
+            location:
+                class: infrastructure_Location
+                multiplicity: "0..1"
+            credentials:
+                class: commons_Credentials
+                multiplicity: "0..1"
+            group:
+                class: infrastructure_ComputingGroup
+                multiplicity: "0..1"
+                inverse_of: infrastructure_ComputingGroup::groupedNodes
+    PhysicalComputingNode:
+        superclass: infrastructure_ComputingNode
+    VirtualMachine:
+        superclass: infrastructure_ComputingNode
+        attributes:
+            sizeDescription:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            generatedFrom:
+                class: infrastructure_VMImage
+                multiplicity: "0..1"
+    Location:
+        superclass: commons_DOMLElement
+        attributes:
+            region:
+                type: String
+                multiplicity: "0..1"
+            zone:
+                type: String
+                multiplicity: "0..1"
+    ContainerConfig:
+        superclass: commons_DOMLElement
+        attributes:
+            container_port:
+                type: Integer
+                multiplicity: "0..1"
+            vm_port:
+                type: Integer
+                multiplicity: "0..1"
+        associations:
+            host:
+                class: infrastructure_ComputingNode
+                multiplicity: "0..1"
+            iface:
+                class: infrastructure_NetworkInterface
+                multiplicity: "0..1"
+    Container:
+        superclass: infrastructure_ComputingNode
+        associations:
+            generatedFrom:
+                class: infrastructure_ContainerImage
+                multiplicity: "0..1"
+            configs:
+                class: infrastructure_ContainerConfig
+                multiplicity: "0..*"
+    ComputingNodeGenerator:
+        superclass: commons_DOMLElement
+        attributes:
+            uri:
+                type: String
+                multiplicity: "0..1"
+            kind:
+                type: GeneratorKind  # enum { SCRIPT, IMAGE }
+    VMImage:
+        superclass: infrastructure_ComputingNodeGenerator
+        associations:
+            generatedVMs:
+                class: infrastructure_VirtualMachine
+                multiplicity: "0..*"
+                inverse_of: infrastructure_VirtualMachine::generatedFrom
+    ContainerImage:
+        superclass: infrastructure_ComputingNodeGenerator
+        associations:
+            generatedContainers:
+                class: infrastructure_Container
+                multiplicity: "0..*"
+                inverse_of: infrastructure_Container::generatedFrom
+    AutoScalingGroup:
+        superclass: infrastructure_ComputingGroup
+        attributes:
+            min:
+                type: Integer
+                multiplicity: "0..1"
+            max:
+                type: Integer
+                multiplicity: "0..1"
+            loadBalancer:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            machineDefinition:
+                class: infrastructure_VirtualMachine
+                multiplicity: "1"
+            securityGroup:
+                class: infrastructure_SecurityGroup
+                multiplicity: "0..1"
+    Storage:
+        superclass: infrastructure_InfrastructureElement
+        attributes:
+            label:
+                type: String
+                multiplicity: "0..1"
+            size_gb:
+                type: Integer  # in GBs
+                multiplicity: "0..1"
+            cost: 
+                type: Integer  # in cents 
+                multiplicity: "0..1"
+        associations:
+            ifaces:
+                class: infrastructure_NetworkInterface
+                multiplicity: "0..*"
+    FunctionAsAService:
+        superclass: infrastructure_InfrastructureElement
+        attributes:
+            cost:
+                type: Integer  # in cents
+                multiplicity: "0..1"
+        associations:
+            ifaces:
+                class: infrastructure_NetworkInterface
+                multiplicity: "0..*"
+    Network:
+        superclass: commons_DOMLElement
+        attributes:
+            protocol:
+                type: String
+                multiplicity: "0..1"
+            addressRange:
+                type: String
+                multiplicity: "0..1"
+            cidr:
+                type: Integer
+                multiplicity: "0..1"
+        associations:
+            connectedIfaces:
+                class: infrastructure_NetworkInterface
+                multiplicity: "0..*"
+                inverse_of: infrastructure_NetworkInterface::belongsTo
+            gateways:
+                class: infrastructure_InternetGateway
+                multiplicity: "0..*"
+            subnets:
+                class: infrastructure_Subnet
+                multiplicity: "0..*"
+    Subnet:
+        superclass: infrastructure_Network
+        associations:
+            connectedTo:
+                class: infrastructure_Network
+                multiplicity: "0..*"
+    NetworkInterface:
+        superclass: infrastructure_InfrastructureElement
+        attributes:
+            endPoint:
+                type: Integer
+                multiplicity: "0..1"
+            speed:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            belongsTo:
+                class: infrastructure_Network
+                multiplicity: "0..1" # This should be "1", but it would break InternetGateway
+            associated:
+                class: infrastructure_SecurityGroup
+                multiplicity: "0..1" # TODO: try putting this to 1 and see why it fails
+    InternetGateway:
+        superclass: infrastructure_NetworkInterface
+        attributes:
+            address:
+                type: String
+                multiplicity: "1"
+    ComputingGroup:
+        superclass: commons_DOMLElement
+        associations:
+            groupedNodes:
+                class: infrastructure_ComputingNode
+                multiplicity: "0..*"
+                inverse_of: infrastructure_ComputingNode::group
+    SecurityGroup:
+        superclass: commons_DOMLElement
+        associations:
+            rules:
+                class: infrastructure_Rule
+                multiplicity: "0..*"
+            ifaces:
+                class: infrastructure_NetworkInterface
+                multiplicity: "0..*"
+                inverse_of: infrastructure_NetworkInterface::associated
+    Rule:
+        superclass: commons_DOMLElement
+        attributes:
+            kind:
+                type: String
+                multiplicity: "1"
+            protocol:
+                type: String
+                multiplicity: "1"
+            fromPort:
+                type: Integer
+                multiplicity: "1"
+            toPort:
+                type: Integer
+                multiplicity: "1"
+            cidr:
+                type: String
+                multiplicity: "0..*"
+    SwarmRole:
+        superclass: commons_DOMLElement
+        attributes:
+            kind:
+                type: String
+                multiplicity: "1"
+        associations:
+            nodes:
+                class: infrastructure_ComputingNode
+                multiplicity: "0..*"
+    Swarm:
+        superclass: infrastructure_ComputingGroup
+        associations:
+            roles:
+                class: infrastructure_SwarmRole
+                multiplicity: "0..*"
+    ExtInfrastructureElement:
+        superclass: infrastructure_InfrastructureElement
+
+concrete:
+    ConcreteInfrastructure:
+        superclass: commons_DOMLElement
+        associations:
+            providers:
+                class: concrete_RuntimeProvider
+                multiplicity: "0..*"
+    ConcreteElement:
+        superclass: commons_DOMLElement
+        associations:
+            refs:
+                class: concrete_ConcreteElement
+                multiplicity: "0..*"
+        attributes:
+            configurationScript:
+                type: String
+                multiplicity: "0..1"
+            preexisting:
+                multiplicity: "1"
+                type: Boolean
+                default: false
+    RuntimeProvider:
+        superclass: commons_DOMLElement
+        associations:
+            resources:
+                class: concrete_GenericResource
+                multiplicity: "0..*"
+            vms:
+                class: concrete_VirtualMachine
+                multiplicity: "0..*"
+            vmImages:
+                class: concrete_VMImage
+                multiplicity: "0..*"
+            containerImages:
+                class: concrete_ContainerImage
+                multiplicity: "0..*"
+            networks:
+                class: concrete_Network
+                multiplicity: "0..*"
+            storages:
+                class: concrete_Storage
+                multiplicity: "0..*"
+            faas:
+                class: concrete_FunctionAsAService
+                multiplicity: "0..*"
+            group:
+                class: concrete_ComputingGroup
+                multiplicity: "0..*"
+    VirtualMachine:
+        superclass: concrete_ConcreteElement
+        associations:
+            maps:
+                class: infrastructure_VirtualMachine
+                multiplicity: "0..1"
+    VMImage:
+        superclass: concrete_ConcreteElement
+        associations:
+            maps:
+                class: infrastructure_VMImage
+                multiplicity: "0..1"
+    ContainerImage:
+        superclass: concrete_ConcreteElement
+        associations:
+            maps:
+                class: infrastructure_ContainerImage
+                multiplicity: "0..1"
+    Network:
+        superclass: concrete_ConcreteElement
+        associations:
+            maps:
+                class: infrastructure_Network
+                multiplicity: "0..1"
+    Storage:
+        superclass: concrete_ConcreteElement
+        associations:
+            maps:
+                class: infrastructure_Storage
+                multiplicity: "0..1"
+    FunctionAsAService:
+        superclass: concrete_ConcreteElement
+        associations:
+            maps:
+                class: infrastructure_FunctionAsAService
+                multiplicity: "0..1"
+    ComputingGroup:
+        superclass: concrete_ConcreteElement
+        associations:
+            maps:
+                class: infrastructure_ComputingGroup
+                multiplicity: "1"
+    GenericResource:
+        superclass: concrete_ConcreteElement
+        attributes:
+            type:
+                type: "String"
+                multiplicity: "1"
+            gname:
+                type: "String"
+                multiplicity: "1"
diff --git a/mc_openapi/assets/metamodels/doml_meta_v2.2.yaml b/mc_openapi/assets/metamodels/doml_meta_v2.2.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..0867657750bd7ed3027fe3e44ca306169dd27efb
--- /dev/null
+++ b/mc_openapi/assets/metamodels/doml_meta_v2.2.yaml
@@ -0,0 +1,532 @@
+commons:
+    DOMLElement:
+        attributes:
+            name:
+                type: String
+                multiplicity: "0..1"
+            description:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            annotations:
+                class: commons_Property
+                multiplicity: "0..*"
+    Property:
+        attributes:
+            key:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            reference:
+                class: commons_DOMLElement
+                multiplicity: "0..1"
+    IProperty:
+        superclass: commons_Property
+        attributes:
+            value:
+                type: Integer
+                multiplicity: "0..1"
+    SProperty:
+        superclass: commons_Property
+        attributes:
+            value:
+                type: String
+                multiplicity: "0..1"
+    FProperty:
+        superclass: commons_Property
+        attributes:
+            value:
+                type: String
+                multiplicity: "0..1"
+    BProperty:
+        superclass: commons_Property
+        attributes:
+            value:
+                type: Boolean
+                multiplicity: "0..1"
+    Configuration:
+        superclass: commons_DOMLElement
+        associations:
+            deployments:
+                class: commons_Deployment
+                multiplicity: "0..*"
+    Credentials:
+        abstract: true
+        superclass: commons_DOMLElement
+    DeployableElement:
+        abstract: true
+        superclass: commons_DOMLElement # It's not present in the ECore, but without it breaks.
+    Deployment:
+        associations:
+            component:
+                class: commons_DeployableElement
+                multiplicity: "1"
+            node:
+                class: infrastructure_InfrastructureElement
+                multiplicity: "1"
+    KeyPair:
+        superclass: commons_Credentials
+        attributes:
+            user:
+                type: String
+                multiplicity: "0..1"
+            keyfile:
+                type: String
+                multiplicity: "0..1"
+            algorithm:
+                type: String
+                multiplicity: "0..1"
+            bits:
+                type: Integer
+                multiplicity: "0..1"
+    UserPass:
+        superclass: commons_Credentials
+        attributes:
+            username:
+                type: String
+                multiplicity: "0..1"
+            password:
+                type: String
+                multiplicity: "0..1"
+    Source:
+        superclass: commons_DOMLElement
+        attributes:
+            entry:
+                type: String
+                multiplicity: "0..*"
+            backend:
+                type: String
+                multiplicity: "0..*"
+application:
+    ApplicationLayer:
+        superclass: commons_DOMLElement
+        associations:
+            components:
+                class: application_ApplicationComponent
+                multiplicity: "0..*"
+    ApplicationComponent:
+        superclass: commons_DeployableElement # and commons_DOMLElement too, but that's definitely wrong; keeping discarding DOMLElement since DeplElem inherits it.
+    SoftwareComponent:
+        superclass: application_ApplicationComponent
+        attributes:
+            isPersistent:
+                type: Boolean
+                multiplicity: "1"
+                default: false
+            licenseCost:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            exposedInterfaces:
+                class: application_SoftwareInterface
+                multiplicity: "0..*"
+            consumedInterfaces:
+                class: application_SoftwareInterface
+                multiplicity: "0..*"
+            src:
+                class: commons_Source
+                multiplicity: "0..1"
+    SaaS:
+        superclass: application_ApplicationComponent
+        attributes:
+            licenseCost:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            exposedInterfaces:
+                class: application_SoftwareInterface
+                multiplicity: "0..*"
+    SoftwareInterface:
+        superclass: application_ApplicationComponent
+        attributes:
+            endPoint:
+                type: String
+                multiplicity: "0..1"
+    DBMS:
+        superclass: application_SoftwareComponent
+    SaaSDBMS:
+        superclass: application_SaaS
+
+infrastructure:
+    InfrastructureLayer:
+        superclass: commons_DOMLElement
+        associations:
+            nodes:
+                class: infrastructure_ComputingNode
+                multiplicity: "0..*"
+            generators:
+                class: infrastructure_ComputingNodeGenerator
+                multiplicity: "0..*"
+            storages:
+                class: infrastructure_Storage
+                multiplicity: "0..*"
+            faas:
+                class: infrastructure_FunctionAsAService
+                multiplicity: "0..*"
+            credentials:
+                class: commons_Credentials
+                multiplicity: "0..*"
+            groups:
+                class: infrastructure_ComputingGroup
+                multiplicity: "0..*"
+            securityGroups:
+                class: infrastructure_SecurityGroup
+                multiplicity: "0..*"
+            networks:
+                class: infrastructure_Network
+                multiplicity: "0..*"
+            rules:
+                class: infrastructure_MonitoringRule
+                multiplicity: "0..*"
+    MonitoringRule:
+        superclass: commons_DOMLElement
+        attributes:
+            condition:
+                type: String 
+                multiplicity: "1"
+            strategy:
+                type: String 
+                multiplicity: "1"
+            strategyConfigurationString:
+                type: String 
+                multiplicity: "0..1"
+    InfrastructureElement:
+        superclass: commons_DeployableElement
+    ComputingNode:
+        superclass: infrastructure_InfrastructureElement
+        attributes:
+            architecture: 
+                type: String 
+                multiplicity: "0..1"
+            os: 
+                type: String 
+                multiplicity: "0..1"
+            memory_mb:
+                type: Integer 
+                multiplicity: "0..1"
+            memory_kb:  # Missing in official Ecore, added by parser
+                type: Integer 
+                multiplicity: "0..1"
+            storage: 
+                type: String 
+                multiplicity: "0..1"
+            cpu_count: 
+                type: Integer 
+                multiplicity: "0..1"
+            cost: 
+                type: Integer  # in cents 
+                multiplicity: "0..1"
+            disabledMonitorings:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            ifaces:
+                class: infrastructure_NetworkInterface
+                multiplicity: "0..*"
+            location:
+                class: infrastructure_Location
+                multiplicity: "0..1"
+            credentials:
+                class: commons_Credentials
+                multiplicity: "0..1"
+            group:
+                class: infrastructure_ComputingGroup
+                multiplicity: "0..1"
+                inverse_of: infrastructure_ComputingGroup::groupedNodes
+    PhysicalComputingNode:
+        superclass: infrastructure_ComputingNode
+    VirtualMachine:
+        superclass: infrastructure_ComputingNode
+        attributes:
+            sizeDescription:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            generatedFrom:
+                class: infrastructure_VMImage
+                multiplicity: "0..1"
+    Location:
+        superclass: commons_DOMLElement
+        attributes:
+            region:
+                type: String
+                multiplicity: "0..1"
+            zone:
+                type: String
+                multiplicity: "0..1"
+    ContainerConfig:
+        superclass: commons_DOMLElement
+        attributes:
+            container_port:
+                type: Integer
+                multiplicity: "0..1"
+            vm_port:
+                type: Integer
+                multiplicity: "0..1"
+        associations:
+            host:
+                class: infrastructure_ComputingNode
+                multiplicity: "0..1"
+            iface:
+                class: infrastructure_NetworkInterface
+                multiplicity: "0..1"
+    Container:
+        superclass: infrastructure_ComputingNode
+        associations:
+            generatedFrom:
+                class: infrastructure_ContainerImage
+                multiplicity: "0..1"
+            configs:
+                class: infrastructure_ContainerConfig
+                multiplicity: "0..*"
+    ComputingNodeGenerator:
+        superclass: commons_DOMLElement
+        attributes:
+            uri:
+                type: String
+                multiplicity: "0..1"
+            kind:
+                type: GeneratorKind  # enum { SCRIPT, IMAGE }
+    VMImage:
+        superclass: infrastructure_ComputingNodeGenerator
+        associations:
+            generatedVMs:
+                class: infrastructure_VirtualMachine
+                multiplicity: "0..*"
+                inverse_of: infrastructure_VirtualMachine::generatedFrom
+    ContainerImage:
+        superclass: infrastructure_ComputingNodeGenerator
+        associations:
+            generatedContainers:
+                class: infrastructure_Container
+                multiplicity: "0..*"
+                inverse_of: infrastructure_Container::generatedFrom
+    AutoScalingGroup:
+        superclass: infrastructure_ComputingGroup
+        attributes:
+            min:
+                type: Integer
+                multiplicity: "0..1"
+            max:
+                type: Integer
+                multiplicity: "0..1"
+            loadBalancer:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            machineDefinition:
+                class: infrastructure_VirtualMachine
+                multiplicity: "1"
+            securityGroup:
+                class: infrastructure_SecurityGroup
+                multiplicity: "0..1"
+    Storage:
+        superclass: infrastructure_InfrastructureElement
+        attributes:
+            label:
+                type: String
+                multiplicity: "0..1"
+            size_gb:
+                type: Integer  # in GBs
+                multiplicity: "0..1"
+            cost: 
+                type: Integer  # in cents 
+                multiplicity: "0..1"
+        associations:
+            ifaces:
+                class: infrastructure_NetworkInterface
+                multiplicity: "0..*"
+    FunctionAsAService:
+        superclass: infrastructure_InfrastructureElement
+        attributes:
+            cost:
+                type: Integer  # in cents
+                multiplicity: "0..1"
+        associations:
+            ifaces:
+                class: infrastructure_NetworkInterface
+                multiplicity: "0..*"
+    Network:
+        superclass: commons_DOMLElement
+        attributes:
+            protocol:
+                type: String
+                multiplicity: "0..1"
+            addressRange:
+                type: String
+                multiplicity: "0..1"
+            cidr:
+                type: Integer
+                multiplicity: "0..1"
+        associations:
+            connectedIfaces:
+                class: infrastructure_NetworkInterface
+                multiplicity: "0..*"
+                inverse_of: infrastructure_NetworkInterface::belongsTo
+            igws:
+                class: infrastructure_InternetGateway
+                multiplicity: "0..*"
+            subnets:
+                class: infrastructure_Subnet
+                multiplicity: "0..*"
+    Subnet:
+        superclass: infrastructure_Network
+        associations:
+            connectedTo:
+                class: infrastructure_Network
+                multiplicity: "0..*"
+    NetworkInterface:
+        superclass: infrastructure_InfrastructureElement
+        attributes:
+            endPoint:
+                type: Integer
+                multiplicity: "0..1"
+            speed:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            belongsTo:
+                class: infrastructure_Network
+                multiplicity: "0..1" # This should be "1", but it would break InternetGateway
+            associated:
+                class: infrastructure_SecurityGroup
+                multiplicity: "0..1" # TODO: try putting this to 1 and see why it fails
+    InternetGateway:
+        superclass: infrastructure_NetworkInterface
+    ComputingGroup:
+        superclass: commons_DOMLElement
+        associations:
+            groupedNodes:
+                class: infrastructure_ComputingNode
+                multiplicity: "0..*"
+                inverse_of: infrastructure_ComputingNode::group
+    SecurityGroup:
+        superclass: commons_DOMLElement
+        associations:
+            rules:
+                class: infrastructure_Rule
+                multiplicity: "0..*"
+            ifaces:
+                class: infrastructure_NetworkInterface
+                multiplicity: "0..*"
+                inverse_of: infrastructure_NetworkInterface::associated
+    Rule:
+        superclass: commons_DOMLElement
+        attributes:
+            kind:
+                type: String
+                multiplicity: "1"
+            protocol:
+                type: String
+                multiplicity: "1"
+            fromPort:
+                type: Integer
+                multiplicity: "1"
+            toPort:
+                type: Integer
+                multiplicity: "1"
+            cidr:
+                type: String
+                multiplicity: "0..*"
+    SwarmRole:
+        superclass: commons_DOMLElement
+        attributes:
+            kind:
+                type: String
+                multiplicity: "1"
+        associations:
+            nodes:
+                class: infrastructure_ComputingNode
+                multiplicity: "0..*"
+    Swarm:
+        superclass: infrastructure_ComputingGroup
+        associations:
+            roles:
+                class: infrastructure_SwarmRole
+                multiplicity: "0..*"
+    ExtInfrastructureElement:
+        superclass: infrastructure_InfrastructureElement
+
+concrete:
+    ConcreteInfrastructure:
+        superclass: commons_DOMLElement
+        associations:
+            providers:
+                class: concrete_RuntimeProvider
+                multiplicity: "0..*"
+    ConcreteElement:
+        superclass: commons_DOMLElement
+        attributes:
+            configurationScript:
+                type: String
+                multiplicity: "0..1"
+            preexisting:
+                multiplicity: "1"
+                type: Boolean
+                default: false
+    RuntimeProvider:
+        superclass: commons_DOMLElement
+        associations:
+            vms:
+                class: concrete_VirtualMachine
+                multiplicity: "0..*"
+            vmImages:
+                class: concrete_VMImage
+                multiplicity: "0..*"
+            containerImages:
+                class: concrete_ContainerImage
+                multiplicity: "0..*"
+            networks:
+                class: concrete_Network
+                multiplicity: "0..*"
+            storages:
+                class: concrete_Storage
+                multiplicity: "0..*"
+            faas:
+                class: concrete_FunctionAsAService
+                multiplicity: "0..*"
+            group:
+                class: concrete_ComputingGroup
+                multiplicity: "0..*"
+    VirtualMachine:
+        superclass: concrete_ConcreteElement
+        associations:
+            maps:
+                class: infrastructure_VirtualMachine
+                multiplicity: "0..1"
+    VMImage:
+        superclass: concrete_ConcreteElement
+        associations:
+            maps:
+                class: infrastructure_VMImage
+                multiplicity: "0..1"
+    ContainerImage:
+        superclass: concrete_ConcreteElement
+        associations:
+            maps:
+                class: infrastructure_ContainerImage
+                multiplicity: "0..1"
+    Network:
+        superclass: concrete_ConcreteElement
+        associations:
+            maps:
+                class: infrastructure_Network
+                multiplicity: "0..1"
+    Storage:
+        superclass: concrete_ConcreteElement
+        associations:
+            maps:
+                class: infrastructure_Storage
+                multiplicity: "0..1"
+    FunctionAsAService:
+        superclass: concrete_ConcreteElement
+        associations:
+            maps:
+                class: infrastructure_FunctionAsAService
+                multiplicity: "0..1"
+    ComputingGroup:
+        superclass: concrete_ConcreteElement
+        associations:
+            maps:
+                class: infrastructure_ComputingGroup
+                multiplicity: "1"
diff --git a/mc_openapi/assets/metamodels/doml_meta_v2.3.yaml b/mc_openapi/assets/metamodels/doml_meta_v2.3.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..cda67949f57f16186ebf590c630783eefcf60316
--- /dev/null
+++ b/mc_openapi/assets/metamodels/doml_meta_v2.3.yaml
@@ -0,0 +1,551 @@
+commons:
+    DOMLElement:
+        attributes:
+            name:
+                type: String
+                multiplicity: "0..1"
+            description:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            annotations:
+                class: commons_Property
+                multiplicity: "0..*"
+    Property:
+        attributes:
+            key:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            reference:
+                class: commons_DOMLElement
+                multiplicity: "0..1"
+    IProperty:
+        superclass: commons_Property
+        attributes:
+            value:
+                type: Integer
+                multiplicity: "0..1"
+    SProperty:
+        superclass: commons_Property
+        attributes:
+            value:
+                type: String
+                multiplicity: "0..1"
+    FProperty:
+        superclass: commons_Property
+        attributes:
+            value:
+                type: String
+                multiplicity: "0..1"
+    BProperty:
+        superclass: commons_Property
+        attributes:
+            value:
+                type: Boolean
+                multiplicity: "0..1"
+    Configuration:
+        superclass: commons_DOMLElement
+        associations:
+            deployments:
+                class: commons_Deployment
+                multiplicity: "0..*"
+    Credentials:
+        abstract: true
+        superclass: commons_DOMLElement
+    DeployableElement:
+        abstract: true
+        superclass: commons_DOMLElement # It's not present in the ECore, but without it breaks.
+    Deployment:
+        associations:
+            component:
+                class: commons_DeployableElement
+                multiplicity: "1"
+            node:
+                class: infrastructure_InfrastructureElement
+                multiplicity: "1"
+    KeyPair:
+        superclass: commons_Credentials
+        attributes:
+            user:
+                type: String
+                multiplicity: "0..1"
+            keyfile:
+                type: String
+                multiplicity: "0..1"
+            algorithm:
+                type: String
+                multiplicity: "0..1"
+            bits:
+                type: Integer
+                multiplicity: "0..1"
+    UserPass:
+        superclass: commons_Credentials
+        attributes:
+            username:
+                type: String
+                multiplicity: "0..1"
+            password:
+                type: String
+                multiplicity: "0..1"
+    Source:
+        superclass: commons_DOMLElement
+        attributes:
+            entry:
+                type: String
+                multiplicity: "0..*"
+            backend:
+                type: String
+                multiplicity: "0..*"
+application:
+    ApplicationLayer:
+        superclass: commons_DOMLElement
+        associations:
+            components:
+                class: application_ApplicationComponent
+                multiplicity: "0..*"
+    ApplicationComponent:
+        superclass: commons_DeployableElement # and commons_DOMLElement too, but that's definitely wrong; keeping discarding DOMLElement since DeplElem inherits it.
+    SoftwareComponent:
+        superclass: application_ApplicationComponent
+        attributes:
+            isPersistent:
+                type: Boolean
+                multiplicity: "1"
+                default: false
+            licenseCost:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            exposedInterfaces:
+                class: application_SoftwareInterface
+                multiplicity: "0..*"
+            consumedInterfaces:
+                class: application_SoftwareInterface
+                multiplicity: "0..*"
+            src:
+                class: commons_Source
+                multiplicity: "0..1"
+    SaaS:
+        superclass: application_ApplicationComponent
+        attributes:
+            licenseCost:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            exposedInterfaces:
+                class: application_SoftwareInterface
+                multiplicity: "0..*"
+    SoftwareInterface:
+        superclass: application_ApplicationComponent
+        attributes:
+            endPoint:
+                type: String
+                multiplicity: "0..1"
+    DBMS:
+        superclass: application_SoftwareComponent
+    SaaSDBMS:
+        superclass: application_SaaS
+
+infrastructure:
+    InfrastructureLayer:
+        superclass: commons_DOMLElement
+        associations:
+            nodes:
+                class: infrastructure_ComputingNode
+                multiplicity: "0..*"
+            generators:
+                class: infrastructure_ComputingNodeGenerator
+                multiplicity: "0..*"
+            storages:
+                class: infrastructure_Storage
+                multiplicity: "0..*"
+            faas:
+                class: infrastructure_FunctionAsAService
+                multiplicity: "0..*"
+            credentials:
+                class: commons_Credentials
+                multiplicity: "0..*"
+            groups:
+                class: infrastructure_ComputingGroup
+                multiplicity: "0..*"
+            securityGroups:
+                class: infrastructure_SecurityGroup
+                multiplicity: "0..*"
+            networks:
+                class: infrastructure_Network
+                multiplicity: "0..*"
+            rules:
+                class: infrastructure_MonitoringRule
+                multiplicity: "0..*"
+    MonitoringRule:
+        superclass: commons_DOMLElement
+        attributes:
+            condition:
+                type: String 
+                multiplicity: "1"
+            strategy:
+                type: String 
+                multiplicity: "1"
+            strategyConfigurationString:
+                type: String 
+                multiplicity: "0..1"
+    InfrastructureElement:
+        superclass: commons_DeployableElement
+    Node:
+        superclass: infrastructure_InfrastructureElement
+        associations:
+            ifaces:
+                class: infrastructure_NetworkInterface
+                multiplicity: "0..*"
+    ComputingNode:
+        superclass: infrastructure_Node
+        attributes:
+            architecture: 
+                type: String 
+                multiplicity: "0..1"
+            os: 
+                type: String 
+                multiplicity: "0..1"
+            memory_mb:
+                type: Integer 
+                multiplicity: "0..1"
+            memory_kb:  # Missing in official Ecore, added by parser
+                type: Integer 
+                multiplicity: "0..1"
+            storage: 
+                type: String 
+                multiplicity: "0..1"
+            cpu_count: 
+                type: Integer 
+                multiplicity: "0..1"
+            cost: 
+                type: Integer  # in cents 
+                multiplicity: "0..1"
+            disabledMonitorings:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            location:
+                class: infrastructure_Location
+                multiplicity: "0..1"
+            credentials:
+                class: commons_Credentials
+                multiplicity: "0..1"
+            group:
+                class: infrastructure_ComputingGroup
+                multiplicity: "0..1"
+                inverse_of: infrastructure_ComputingGroup::groupedNodes
+    PhysicalComputingNode:
+        superclass: infrastructure_ComputingNode
+    VirtualMachine:
+        superclass: infrastructure_ComputingNode
+        attributes:
+            sizeDescription:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            generatedFrom:
+                class: infrastructure_VMImage
+                multiplicity: "0..1"
+    Location:
+        superclass: commons_DOMLElement
+        attributes:
+            region:
+                type: String
+                multiplicity: "0..1"
+            zone:
+                type: String
+                multiplicity: "0..1"
+    ContainerConfig:
+        superclass: commons_DOMLElement
+        attributes:
+            container_port:
+                type: Integer
+                multiplicity: "0..1"
+            vm_port:
+                type: Integer
+                multiplicity: "0..1"
+        associations:
+            host:
+                class: infrastructure_ComputingNode
+                multiplicity: "0..1"
+            iface:
+                class: infrastructure_NetworkInterface
+                multiplicity: "0..1"
+    Container:
+        superclass: infrastructure_ComputingNode
+        associations:
+            generatedFrom:
+                class: infrastructure_ContainerImage
+                multiplicity: "0..1"
+            configs:
+                class: infrastructure_ContainerConfig
+                multiplicity: "0..*"
+    ComputingNodeGenerator:
+        superclass: commons_DOMLElement
+        attributes:
+            uri:
+                type: String
+                multiplicity: "0..1"
+            kind:
+                type: GeneratorKind  # enum { SCRIPT, IMAGE }
+    VMImage:
+        superclass: infrastructure_ComputingNodeGenerator
+        associations:
+            generatedVMs:
+                class: infrastructure_VirtualMachine
+                multiplicity: "0..*"
+                inverse_of: infrastructure_VirtualMachine::generatedFrom
+    ContainerImage:
+        superclass: infrastructure_ComputingNodeGenerator
+        associations:
+            generatedContainers:
+                class: infrastructure_Container
+                multiplicity: "0..*"
+                inverse_of: infrastructure_Container::generatedFrom
+    AutoScalingGroup:
+        superclass: infrastructure_ComputingGroup
+        attributes:
+            min:
+                type: Integer
+                multiplicity: "0..1"
+            max:
+                type: Integer
+                multiplicity: "0..1"
+            loadBalancer:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            machineDefinition:
+                class: infrastructure_VirtualMachine
+                multiplicity: "1"
+            securityGroup:
+                class: infrastructure_SecurityGroup
+                multiplicity: "0..1"
+    Storage:
+        superclass: infrastructure_Node
+        attributes:
+            label:
+                type: String
+                multiplicity: "0..1"
+            size_gb:
+                type: Integer  # in GBs
+                multiplicity: "0..1"
+            cost: 
+                type: Integer  # in cents 
+                multiplicity: "0..1"
+    FunctionAsAService:
+        superclass: infrastructure_InfrastructureElement
+        attributes:
+            cost:
+                type: Integer  # in cents
+                multiplicity: "0..1"
+    Network:
+        superclass: commons_DOMLElement
+        attributes:
+            protocol:
+                type: String
+                multiplicity: "0..1"
+            addressRange:
+                type: String
+                multiplicity: "0..1"
+            cidr:
+                type: Integer
+                multiplicity: "0..1"
+        associations:
+            connectedIfaces:
+                class: infrastructure_NetworkInterface
+                multiplicity: "0..*"
+                inverse_of: infrastructure_NetworkInterface::belongsTo
+            gateways:
+                class: infrastructure_InternetGateway
+                multiplicity: "0..*"
+            subnets:
+                class: infrastructure_Subnet
+                multiplicity: "0..*"
+    Subnet:
+        superclass: infrastructure_Network
+        associations:
+            connectedTo:
+                class: infrastructure_Network
+                multiplicity: "0..*"
+    NetworkInterface:
+        superclass: infrastructure_InfrastructureElement
+        attributes:
+            endPoint:
+                type: Integer
+                multiplicity: "0..1"
+            speed:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            belongsTo:
+                class: infrastructure_Network
+                multiplicity: "0..1" # This should be "1", but it would break InternetGateway
+            associated:
+                class: infrastructure_SecurityGroup
+                multiplicity: "0..1"
+    InternetGateway:
+        superclass: infrastructure_Node
+        attributes:
+            address:
+                type: String
+                multiplicity: "1"
+    ComputingGroup:
+        superclass: commons_DOMLElement
+        associations:
+            groupedNodes:
+                class: infrastructure_ComputingNode
+                multiplicity: "0..*"
+                inverse_of: infrastructure_ComputingNode::group
+    SecurityGroup:
+        superclass: commons_DOMLElement
+        associations:
+            rules:
+                class: infrastructure_Rule
+                multiplicity: "0..*"
+            ifaces:
+                class: infrastructure_NetworkInterface
+                multiplicity: "0..*"
+                inverse_of: infrastructure_NetworkInterface::associated
+    Rule:
+        superclass: commons_DOMLElement
+        attributes:
+            kind:
+                type: String
+                multiplicity: "1"
+            protocol:
+                type: String
+                multiplicity: "1"
+            fromPort:
+                type: Integer
+                multiplicity: "1"
+            toPort:
+                type: Integer
+                multiplicity: "1"
+            cidr:
+                type: String
+                multiplicity: "0..*"
+    SwarmRole:
+        superclass: commons_DOMLElement
+        attributes:
+            kind:
+                type: String
+                multiplicity: "1"
+        associations:
+            nodes:
+                class: infrastructure_ComputingNode
+                multiplicity: "0..*"
+    Swarm:
+        superclass: infrastructure_ComputingGroup
+        associations:
+            roles:
+                class: infrastructure_SwarmRole
+                multiplicity: "0..*"
+    ExtInfrastructureElement:
+        superclass: infrastructure_InfrastructureElement
+
+concrete:
+    ConcreteInfrastructure:
+        superclass: commons_DOMLElement
+        associations:
+            providers:
+                class: concrete_RuntimeProvider
+                multiplicity: "0..*"
+    ConcreteElement:
+        superclass: commons_DOMLElement
+        associations:
+            refs:
+                class: concrete_ConcreteElement
+                multiplicity: "0..*"
+        attributes:
+            configurationScript:
+                type: String
+                multiplicity: "0..1"
+            preexisting:
+                multiplicity: "1"
+                type: Boolean
+                default: false
+    RuntimeProvider:
+        superclass: commons_DOMLElement
+        associations:
+            resources:
+                class: concrete_GenericResource
+                multiplicity: "0..*"
+            vms:
+                class: concrete_VirtualMachine
+                multiplicity: "0..*"
+            vmImages:
+                class: concrete_VMImage
+                multiplicity: "0..*"
+            containerImages:
+                class: concrete_ContainerImage
+                multiplicity: "0..*"
+            networks:
+                class: concrete_Network
+                multiplicity: "0..*"
+            storages:
+                class: concrete_Storage
+                multiplicity: "0..*"
+            faas:
+                class: concrete_FunctionAsAService
+                multiplicity: "0..*"
+            group:
+                class: concrete_ComputingGroup
+                multiplicity: "0..*"
+    VirtualMachine:
+        superclass: concrete_ConcreteElement
+        associations:
+            maps:
+                class: infrastructure_VirtualMachine
+                multiplicity: "0..1"
+    VMImage:
+        superclass: concrete_ConcreteElement
+        attributes:
+            image_name:
+                type: String
+                multiplicity: "1"
+        associations:
+            maps:
+                class: infrastructure_VMImage
+                multiplicity: "0..1"
+    ContainerImage:
+        superclass: concrete_ConcreteElement
+        associations:
+            maps:
+                class: infrastructure_ContainerImage
+                multiplicity: "0..1"
+    Network:
+        superclass: concrete_ConcreteElement
+        associations:
+            maps:
+                class: infrastructure_Network
+                multiplicity: "0..1"
+    Storage:
+        superclass: concrete_ConcreteElement
+        associations:
+            maps:
+                class: infrastructure_Storage
+                multiplicity: "0..1"
+    FunctionAsAService:
+        superclass: concrete_ConcreteElement
+        associations:
+            maps:
+                class: infrastructure_FunctionAsAService
+                multiplicity: "0..1"
+    ComputingGroup:
+        superclass: concrete_ConcreteElement
+        associations:
+            maps:
+                class: infrastructure_ComputingGroup
+                multiplicity: "1"
+    GenericResource:
+        superclass: concrete_ConcreteElement
+        attributes:
+            type:
+                type: "String"
+                multiplicity: "1"
+            gname:
+                type: "String"
+                multiplicity: "1"
diff --git a/mc_openapi/assets/metamodels/doml_meta_v3.0.yaml b/mc_openapi/assets/metamodels/doml_meta_v3.0.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..550ce647aaffc229c1ac8a89e7b32a44473d551e
--- /dev/null
+++ b/mc_openapi/assets/metamodels/doml_meta_v3.0.yaml
@@ -0,0 +1,554 @@
+commons:
+    DOMLElement:
+        attributes:
+            name:
+                type: String
+                multiplicity: "0..1"
+            description:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            annotations:
+                class: commons_Property
+                multiplicity: "0..*"
+    Property:
+        attributes:
+            key:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            reference:
+                class: commons_DOMLElement
+                multiplicity: "0..1"
+    IProperty:
+        superclass: commons_Property
+        attributes:
+            value:
+                type: Integer
+                multiplicity: "0..1"
+    SProperty:
+        superclass: commons_Property
+        attributes:
+            value:
+                type: String
+                multiplicity: "0..1"
+    FProperty:
+        superclass: commons_Property
+        attributes:
+            value:
+                type: String
+                multiplicity: "0..1"
+    BProperty:
+        superclass: commons_Property
+        attributes:
+            value:
+                type: Boolean
+                multiplicity: "0..1"
+    Configuration:
+        superclass: commons_DOMLElement
+        associations:
+            deployments:
+                class: commons_Deployment
+                multiplicity: "0..*"
+    Credentials:
+        abstract: true
+        superclass: commons_DOMLElement
+    DeployableElement:
+        abstract: true
+        superclass: commons_DOMLElement # It's not present in the ECore, but without it breaks.
+    Deployment:
+        associations:
+            component:
+                class: commons_DeployableElement
+                multiplicity: "1"
+            node:
+                class: infrastructure_InfrastructureElement
+                multiplicity: "1"
+    KeyPair:
+        superclass: commons_Credentials
+        attributes:
+            user:
+                type: String
+                multiplicity: "0..1"
+            keyfile:
+                type: String
+                multiplicity: "0..1"
+            algorithm:
+                type: String
+                multiplicity: "0..1"
+            bits:
+                type: Integer
+                multiplicity: "0..1"
+    UserPass:
+        superclass: commons_Credentials
+        attributes:
+            username:
+                type: String
+                multiplicity: "0..1"
+            password:
+                type: String
+                multiplicity: "0..1"
+    Source:
+        superclass: commons_DOMLElement
+        attributes:
+            entry:
+                type: String
+                multiplicity: "0..*"
+            backend:
+                type: String
+                multiplicity: "0..*"
+application:
+    ApplicationLayer:
+        superclass: commons_DOMLElement
+        associations:
+            components:
+                class: application_ApplicationComponent
+                multiplicity: "0..*"
+    ApplicationComponent:
+        superclass: commons_DeployableElement # and commons_DOMLElement too, but that's definitely wrong; keeping discarding DOMLElement since DeplElem inherits it.
+    SoftwareComponent:
+        superclass: application_ApplicationComponent
+        attributes:
+            isPersistent:
+                type: Boolean
+                multiplicity: "1"
+                default: false
+            licenseCost:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            exposedInterfaces:
+                class: application_SoftwareInterface
+                multiplicity: "0..*"
+            consumedInterfaces:
+                class: application_SoftwareInterface
+                multiplicity: "0..*"
+            src:
+                class: commons_Source
+                multiplicity: "0..1"
+    SaaS:
+        superclass: application_ApplicationComponent
+        attributes:
+            licenseCost:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            exposedInterfaces:
+                class: application_SoftwareInterface
+                multiplicity: "0..*"
+    SoftwareInterface:
+        superclass: application_ApplicationComponent
+        attributes:
+            endPoint:
+                type: String
+                multiplicity: "0..1"
+    DBMS:
+        superclass: application_SoftwareComponent
+    SaaSDBMS:
+        superclass: application_SaaS
+
+infrastructure:
+    InfrastructureLayer:
+        superclass: commons_DOMLElement
+        associations:
+            nodes:
+                class: infrastructure_ComputingNode
+                multiplicity: "0..*"
+            generators:
+                class: infrastructure_ComputingNodeGenerator
+                multiplicity: "0..*"
+            storages:
+                class: infrastructure_Storage
+                multiplicity: "0..*"
+            faas:
+                class: infrastructure_FunctionAsAService
+                multiplicity: "0..*"
+            credentials:
+                class: commons_Credentials
+                multiplicity: "0..*"
+            groups:
+                class: infrastructure_ComputingGroup
+                multiplicity: "0..*"
+            securityGroups:
+                class: infrastructure_SecurityGroup
+                multiplicity: "0..*"
+            networks:
+                class: infrastructure_Network
+                multiplicity: "0..*"
+            rules:
+                class: infrastructure_MonitoringRule
+                multiplicity: "0..*"
+    MonitoringRule:
+        superclass: commons_DOMLElement
+        attributes:
+            condition:
+                type: String 
+                multiplicity: "1"
+            strategy:
+                type: String 
+                multiplicity: "1"
+            strategyConfigurationString:
+                type: String 
+                multiplicity: "0..1"
+    InfrastructureElement:
+        superclass: commons_DeployableElement
+    Node:
+        superclass: infrastructure_InfrastructureElement
+        associations:
+            ifaces:
+                class: infrastructure_NetworkInterface
+                multiplicity: "0..*"
+    ComputingNode:
+        superclass: infrastructure_Node
+        attributes:
+            architecture: 
+                type: String 
+                multiplicity: "0..1"
+            os: 
+                type: String 
+                multiplicity: "0..1"
+            memory_mb:
+                type: Integer 
+                multiplicity: "0..1"
+            memory_kb:  # Missing in official Ecore, added by parser
+                type: Integer 
+                multiplicity: "0..1"
+            storage: 
+                type: String 
+                multiplicity: "0..1"
+            cpu_count: 
+                type: Integer 
+                multiplicity: "0..1"
+            cost: 
+                type: Integer  # in cents 
+                multiplicity: "0..1"
+            disabledMonitorings:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            location:
+                class: infrastructure_Location
+                multiplicity: "0..1"
+            credentials:
+                class: commons_Credentials
+                multiplicity: "0..1"
+            group:
+                class: infrastructure_ComputingGroup
+                multiplicity: "0..1"
+                inverse_of: infrastructure_ComputingGroup::groupedNodes
+            nodeSpecificMonitoring:
+                class: infrastructure_MonitoringRule
+                multiplicity: "0..1"
+    PhysicalComputingNode:
+        superclass: infrastructure_ComputingNode
+    VirtualMachine:
+        superclass: infrastructure_ComputingNode
+        attributes:
+            sizeDescription:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            generatedFrom:
+                class: infrastructure_VMImage
+                multiplicity: "0..1"
+    Location:
+        superclass: commons_DOMLElement
+        attributes:
+            region:
+                type: String
+                multiplicity: "0..1"
+            zone:
+                type: String
+                multiplicity: "0..1"
+    ContainerConfig:
+        superclass: commons_DOMLElement
+        attributes:
+            container_port:
+                type: Integer
+                multiplicity: "0..1"
+            vm_port:
+                type: Integer
+                multiplicity: "0..1"
+        associations:
+            host:
+                class: infrastructure_ComputingNode
+                multiplicity: "0..1"
+            iface:
+                class: infrastructure_NetworkInterface
+                multiplicity: "0..1"
+    Container:
+        superclass: infrastructure_ComputingNode
+        associations:
+            generatedFrom:
+                class: infrastructure_ContainerImage
+                multiplicity: "0..1"
+            configs:
+                class: infrastructure_ContainerConfig
+                multiplicity: "0..*"
+    ComputingNodeGenerator:
+        superclass: commons_DOMLElement
+        attributes:
+            uri:
+                type: String
+                multiplicity: "0..1"
+            kind:
+                type: GeneratorKind  # enum { SCRIPT, IMAGE }
+    VMImage:
+        superclass: infrastructure_ComputingNodeGenerator
+        associations:
+            generatedVMs:
+                class: infrastructure_VirtualMachine
+                multiplicity: "0..*"
+                inverse_of: infrastructure_VirtualMachine::generatedFrom
+    ContainerImage:
+        superclass: infrastructure_ComputingNodeGenerator
+        associations:
+            generatedContainers:
+                class: infrastructure_Container
+                multiplicity: "0..*"
+                inverse_of: infrastructure_Container::generatedFrom
+    AutoScalingGroup:
+        superclass: infrastructure_ComputingGroup
+        attributes:
+            min:
+                type: Integer
+                multiplicity: "0..1"
+            max:
+                type: Integer
+                multiplicity: "0..1"
+            loadBalancer:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            machineDefinition:
+                class: infrastructure_VirtualMachine
+                multiplicity: "1"
+            securityGroup:
+                class: infrastructure_SecurityGroup
+                multiplicity: "0..1"
+    Storage:
+        superclass: infrastructure_Node
+        attributes:
+            label:
+                type: String
+                multiplicity: "0..1"
+            size_gb:
+                type: Integer  # in GBs
+                multiplicity: "0..1"
+            cost: 
+                type: Integer  # in cents 
+                multiplicity: "0..1"
+    FunctionAsAService:
+        superclass: infrastructure_InfrastructureElement
+        attributes:
+            cost:
+                type: Integer  # in cents
+                multiplicity: "0..1"
+    Network:
+        superclass: commons_DOMLElement
+        attributes:
+            protocol:
+                type: String
+                multiplicity: "0..1"
+            addressRange:
+                type: String
+                multiplicity: "0..1"
+            cidr:
+                type: Integer
+                multiplicity: "0..1"
+        associations:
+            connectedIfaces:
+                class: infrastructure_NetworkInterface
+                multiplicity: "0..*"
+                inverse_of: infrastructure_NetworkInterface::belongsTo
+            gateways:
+                class: infrastructure_InternetGateway
+                multiplicity: "0..*"
+            subnets:
+                class: infrastructure_Subnet
+                multiplicity: "0..*"
+    Subnet:
+        superclass: infrastructure_Network
+        associations:
+            connectedTo:
+                class: infrastructure_Network
+                multiplicity: "0..*"
+    NetworkInterface:
+        superclass: infrastructure_InfrastructureElement
+        attributes:
+            endPoint:
+                type: Integer
+                multiplicity: "0..1"
+            speed:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            belongsTo:
+                class: infrastructure_Network
+                multiplicity: "0..1" # This should be "1", but it would break InternetGateway
+            associated:
+                class: infrastructure_SecurityGroup
+                multiplicity: "0..1"
+    InternetGateway:
+        superclass: infrastructure_Node
+        attributes:
+            address:
+                type: String
+                multiplicity: "1"
+    ComputingGroup:
+        superclass: commons_DOMLElement
+        associations:
+            groupedNodes:
+                class: infrastructure_ComputingNode
+                multiplicity: "0..*"
+                inverse_of: infrastructure_ComputingNode::group
+    SecurityGroup:
+        superclass: commons_DOMLElement
+        associations:
+            rules:
+                class: infrastructure_Rule
+                multiplicity: "0..*"
+            ifaces:
+                class: infrastructure_NetworkInterface
+                multiplicity: "0..*"
+                inverse_of: infrastructure_NetworkInterface::associated
+    Rule:
+        superclass: commons_DOMLElement
+        attributes:
+            kind:
+                type: String
+                multiplicity: "1"
+            protocol:
+                type: String
+                multiplicity: "1"
+            fromPort:
+                type: Integer
+                multiplicity: "1"
+            toPort:
+                type: Integer
+                multiplicity: "1"
+            cidr:
+                type: String
+                multiplicity: "0..*"
+    SwarmRole:
+        superclass: commons_DOMLElement
+        attributes:
+            kind:
+                type: String
+                multiplicity: "1"
+        associations:
+            nodes:
+                class: infrastructure_ComputingNode
+                multiplicity: "0..*"
+    Swarm:
+        superclass: infrastructure_ComputingGroup
+        associations:
+            roles:
+                class: infrastructure_SwarmRole
+                multiplicity: "0..*"
+    ExtInfrastructureElement:
+        superclass: infrastructure_InfrastructureElement
+
+concrete:
+    ConcreteInfrastructure:
+        superclass: commons_DOMLElement
+        associations:
+            providers:
+                class: concrete_RuntimeProvider
+                multiplicity: "0..*"
+    ConcreteElement:
+        superclass: commons_DOMLElement
+        associations:
+            refs:
+                class: concrete_ConcreteElement
+                multiplicity: "0..*"
+        attributes:
+            configurationScript:
+                type: String
+                multiplicity: "0..1"
+            preexisting:
+                multiplicity: "1"
+                type: Boolean
+                default: false
+    RuntimeProvider:
+        superclass: commons_DOMLElement
+        associations:
+            resources:
+                class: concrete_GenericResource
+                multiplicity: "0..*"
+            vms:
+                class: concrete_VirtualMachine
+                multiplicity: "0..*"
+            vmImages:
+                class: concrete_VMImage
+                multiplicity: "0..*"
+            containerImages:
+                class: concrete_ContainerImage
+                multiplicity: "0..*"
+            networks:
+                class: concrete_Network
+                multiplicity: "0..*"
+            storages:
+                class: concrete_Storage
+                multiplicity: "0..*"
+            faas:
+                class: concrete_FunctionAsAService
+                multiplicity: "0..*"
+            group:
+                class: concrete_ComputingGroup
+                multiplicity: "0..*"
+    VirtualMachine:
+        superclass: concrete_ConcreteElement
+        associations:
+            maps:
+                class: infrastructure_VirtualMachine
+                multiplicity: "0..1"
+    VMImage:
+        superclass: concrete_ConcreteElement
+        attributes:
+            image_name:
+                type: String
+                multiplicity: "1"
+        associations:
+            maps:
+                class: infrastructure_VMImage
+                multiplicity: "0..1"
+    ContainerImage:
+        superclass: concrete_ConcreteElement
+        associations:
+            maps:
+                class: infrastructure_ContainerImage
+                multiplicity: "0..1"
+    Network:
+        superclass: concrete_ConcreteElement
+        associations:
+            maps:
+                class: infrastructure_Network
+                multiplicity: "0..1"
+    Storage:
+        superclass: concrete_ConcreteElement
+        associations:
+            maps:
+                class: infrastructure_Storage
+                multiplicity: "0..1"
+    FunctionAsAService:
+        superclass: concrete_ConcreteElement
+        associations:
+            maps:
+                class: infrastructure_FunctionAsAService
+                multiplicity: "0..1"
+    ComputingGroup:
+        superclass: concrete_ConcreteElement
+        associations:
+            maps:
+                class: infrastructure_ComputingGroup
+                multiplicity: "1"
+    GenericResource:
+        superclass: concrete_ConcreteElement
+        attributes:
+            type:
+                type: "String"
+                multiplicity: "1"
+            gname:
+                type: "String"
+                multiplicity: "1"
diff --git a/mc_openapi/assets/metamodels/doml_meta_v3.1.yaml b/mc_openapi/assets/metamodels/doml_meta_v3.1.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..c2dd82b4935821cb9d105ca2a249726a4bcc4b3f
--- /dev/null
+++ b/mc_openapi/assets/metamodels/doml_meta_v3.1.yaml
@@ -0,0 +1,677 @@
+commons:
+    DOMLElement:
+        attributes:
+            name:
+                type: String
+                multiplicity: "0..1"
+            description:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            annotations:
+                class: commons_Property
+                multiplicity: "0..*"
+    Property:
+        attributes:
+            key:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            reference:
+                class: commons_DOMLElement
+                multiplicity: "0..1"
+    ListProperty:
+        superclass: commons_Property
+        associations:
+            values:
+                class: commons_Property
+                multiplicity: "0..*"
+    IProperty:
+        superclass: commons_Property
+        attributes:
+            value:
+                type: Integer
+                multiplicity: "0..1"
+    SProperty:
+        superclass: commons_Property
+        attributes:
+            value:
+                type: String
+                multiplicity: "0..1"
+    FProperty:
+        superclass: commons_Property
+        attributes:
+            value:
+                type: String
+                multiplicity: "0..1"
+    BProperty:
+        superclass: commons_Property
+        attributes:
+            value:
+                type: Boolean
+                multiplicity: "0..1"
+    Configuration:
+        superclass: commons_DOMLElement
+        associations:
+            deployments:
+                class: commons_Deployment
+                multiplicity: "0..*"
+    Credentials:
+        abstract: true
+        superclass: commons_DOMLElement
+    DeployableElement:
+        abstract: true
+        superclass: commons_DOMLElement # It's not present in the ECore, but without it breaks.
+    Deployment:
+        associations:
+            component:
+                class: commons_DeployableElement
+                multiplicity: "1"
+            node:
+                class: infrastructure_InfrastructureElement
+                multiplicity: "1"
+    KeyPair:
+        superclass: commons_Credentials
+        attributes:
+            user:
+                type: String
+                multiplicity: "0..1"
+            key:
+                type: String
+                multiplicity: "0..1"
+            algorithm:
+                type: String
+                multiplicity: "0..1"
+            bits:
+                type: Integer
+                multiplicity: "0..1"
+    UserPass:
+        superclass: commons_Credentials
+        attributes:
+            username:
+                type: String
+                multiplicity: "0..1"
+            password:
+                type: String
+                multiplicity: "0..1"
+    Source:
+        superclass: commons_DOMLElement
+        attributes:
+            entry:
+                type: String
+                multiplicity: "0..1"
+            inventory:
+                type: String
+                multiplicity: "0..1"
+            backend:
+                type: String
+                multiplicity: "0..1"
+application:
+    ApplicationLayer:
+        superclass: commons_DOMLElement
+        associations:
+            components:
+                class: application_ApplicationComponent
+                multiplicity: "0..*"
+    ApplicationComponent:
+        superclass: commons_DeployableElement # and commons_DOMLElement too, but that's definitely wrong; keeping discarding DOMLElement since DeplElem inherits it.
+    SoftwareComponent:
+        superclass: application_ApplicationComponent
+        attributes:
+            isPersistent:
+                type: Boolean
+                multiplicity: "1"
+                default: false
+            licenseCost:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            exposedInterfaces:
+                class: application_SoftwareInterface
+                multiplicity: "0..*"
+            consumedInterfaces:
+                class: application_SoftwareInterface
+                multiplicity: "0..*"
+            src:
+                class: commons_Source
+                multiplicity: "0..1"
+    SaaS:
+        superclass: application_ApplicationComponent
+        attributes:
+            licenseCost:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            exposedInterfaces:
+                class: application_SoftwareInterface
+                multiplicity: "0..*"
+    SoftwareInterface:
+        superclass: application_ApplicationComponent
+        attributes:
+            endPoint:
+                type: String
+                multiplicity: "0..1"
+    DBMS:
+        superclass: application_SoftwareComponent
+    SaaSDBMS:
+        superclass: application_SaaS
+        attributes:
+            databaseName:
+                type: String
+                multiplicity: "0..1"
+            engine:
+                type: String
+                multiplicity: "0..1"
+            engineVersion:
+                type: String
+                multiplicity: "0..1"
+infrastructure:
+    InfrastructureLayer:
+        superclass: commons_DOMLElement
+        associations:
+            nodes:
+                class: infrastructure_ComputingNode
+                multiplicity: "0..*"
+            generators:
+                class: infrastructure_ComputingNodeGenerator
+                multiplicity: "0..*"
+            storages:
+                class: infrastructure_Storage
+                multiplicity: "0..*"
+            faas:
+                class: infrastructure_FunctionAsAService
+                multiplicity: "0..*"
+            credentials:
+                class: commons_Credentials
+                multiplicity: "0..*"
+            groups:
+                class: infrastructure_ComputingGroup
+                multiplicity: "0..*"
+            securityGroups:
+                class: infrastructure_SecurityGroup
+                multiplicity: "0..*"
+            networks:
+                class: infrastructure_Network
+                multiplicity: "0..*"
+            rules:
+                class: infrastructure_MonitoringRule
+                multiplicity: "0..*"
+            executionEnvironments:
+                class: infrastructure_ExecutionEnvironment
+                multiplicity: "0..*"
+    MonitoringRule:
+        superclass: commons_DOMLElement
+        attributes:
+            condition:
+                type: String 
+                multiplicity: "1"
+            strategy:
+                type: String 
+                multiplicity: "1"
+            strategyConfigurationString:
+                type: String 
+                multiplicity: "0..1"
+    InfrastructureElement:
+        superclass: commons_DeployableElement
+    Node:
+        superclass: infrastructure_InfrastructureElement
+        associations:
+            ifaces:
+                class: infrastructure_NetworkInterface
+                multiplicity: "0..*"
+    ComputingNode:
+        superclass: infrastructure_Node
+        attributes:
+            architecture: 
+                type: String 
+                multiplicity: "0..1"
+            os: 
+                type: String 
+                multiplicity: "0..1"
+            memory_mb:
+                type: Integer 
+                multiplicity: "0..1"
+            memory_kb:  # Missing in official Ecore, added by parser
+                type: Integer 
+                multiplicity: "0..1"
+            storage: 
+                type: Integer 
+                multiplicity: "0..1"
+            cpu_count: 
+                type: Integer 
+                multiplicity: "0..1"
+            cost: 
+                type: Integer  # in cents 
+                multiplicity: "0..1"
+            disabledMonitorings:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            location:
+                class: infrastructure_Location
+                multiplicity: "0..1"
+            credentials:
+                class: commons_Credentials
+                multiplicity: "0..1"
+            group:
+                class: infrastructure_ComputingGroup
+                multiplicity: "0..1"
+                inverse_of: infrastructure_ComputingGroup::groupedNodes
+            nodeSpecificMonitoring:
+                class: infrastructure_MonitoringRule
+                multiplicity: "0..1"
+    PhysicalComputingNode:
+        superclass: infrastructure_ComputingNode
+        associations:
+            configInterface:
+                class: infrastructure_NetworkInterface
+                multiplicity: "0..1"
+    VirtualMachine:
+        superclass: infrastructure_ComputingNode
+        attributes:
+            sizeDescription:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            generatedFrom:
+                class: infrastructure_VMImage
+                multiplicity: "0..1"
+            configInterface:
+                class: infrastructure_NetworkInterface
+                multiplicity: "0..1"
+    Location:
+        superclass: commons_DOMLElement
+        attributes:
+            region:
+                type: String
+                multiplicity: "0..1"
+            zone:
+                type: String
+                multiplicity: "0..1"
+    ContainerConfig:
+        superclass: commons_DOMLElement
+        attributes:
+            container_port:
+                type: Integer
+                multiplicity: "0..1"
+            vm_port:
+                type: Integer
+                multiplicity: "0..1"
+        associations:
+            iface:
+                class: infrastructure_NetworkInterface
+                multiplicity: "0..1"
+    ContainerHostConfig:
+        superclass: commons_DOMLElement
+        associations:
+            environment_variables:
+                class: commons_SProperty
+                multiplicity: "0..*"
+            host:
+                class: infrastructure_ComputingNode
+                multiplicity: "0..1"
+            configurations:
+                class: infrastructure_ContainerConfig
+                multiplicity: "0..*"
+    Container:
+        superclass: infrastructure_ComputingNode
+        associations:
+            generatedFrom:
+                class: infrastructure_ContainerImage
+                multiplicity: "0..1"
+            hostConfigs:
+                class: infrastructure_ContainerHostConfig
+                multiplicity: "0..*"
+            networks:
+                class: infrastructure_ContainerNetwork
+                multiplicity: "0..*"
+            volumes:
+                class: infrastructure_ContainerVolume
+                multiplicity: "0..*"
+            dependsOn:
+                class: infrastructure_Container
+                multiplicity: "0..*"
+    ContainerGroup:
+        superclass: infrastructure_ComputingGroup
+        associations:
+            services:
+                class: infrastructure_Container
+                multiplicity: "1..*"
+            networks:
+                class: infrastructure_ContainerNetwork
+                multiplicity: "0..*"
+            volumes:
+                class: infrastructure_ContainerVolume
+                multiplicity: "0..*"
+    ContainerNetwork:
+        superclass: commons_DOMLElement
+        attributes:
+            containerNetworkName:
+                type: String
+                multiplicity: "0..1"
+    ContainerVolume:
+        superclass: commons_DOMLElement
+        attributes:
+            containerVolumeName:
+                type: String
+                multiplicity: "0..1"
+            path:
+                type: String
+                multiplicity: "0..1"
+    ExecutionEnvironment:
+        superclass: infrastructure_InfrastructureElement
+        attributes:
+            size:
+                type: Integer
+                multiplicity: "0..1"
+            maxSize:
+                type: Integer
+                multiplicity: "0..1"
+        associations:
+            location:
+                class: infrastructure_Location
+                multiplicity: "0..1"
+            network:
+                class: infrastructure_Network
+                multiplicity: "0..1"
+            securityGroups:
+                class: infrastructure_SecurityGroup
+                multiplicity: "0..*"
+    ComputingNodeGenerator:
+        superclass: commons_DOMLElement
+        attributes:
+            uri:
+                type: String
+                multiplicity: "0..1"
+            kind:
+                type: GeneratorKind  # enum { SCRIPT, IMAGE }
+    VMImage:
+        superclass: infrastructure_ComputingNodeGenerator
+        associations:
+            generatedVMs:
+                class: infrastructure_VirtualMachine
+                multiplicity: "0..*"
+                inverse_of: infrastructure_VirtualMachine::generatedFrom
+    ContainerImage:
+        superclass: infrastructure_ComputingNodeGenerator
+        associations:
+            generatedContainers:
+                class: infrastructure_Container
+                multiplicity: "0..*"
+                inverse_of: infrastructure_Container::generatedFrom
+    AutoScalingGroup:
+        superclass: infrastructure_ComputingGroup
+        attributes:
+            min:
+                type: Integer
+                multiplicity: "0..1"
+            max:
+                type: Integer
+                multiplicity: "0..1"
+            loadBalancer:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            machineDefinition:
+                class: infrastructure_VirtualMachine
+                multiplicity: "1"
+    Storage:
+        superclass: infrastructure_Node
+        attributes:
+            label:
+                type: String
+                multiplicity: "0..1"
+            size_gb:
+                type: Integer  # in GBs
+                multiplicity: "0..1"
+            cost: 
+                type: Integer  # in cents 
+                multiplicity: "0..1"
+    FunctionAsAService:
+        superclass: infrastructure_InfrastructureElement
+        attributes:
+            cost:
+                type: Integer  # in cents
+                multiplicity: "0..1"
+    Network:
+        superclass: commons_DOMLElement
+        attributes:
+            protocol:
+                type: String
+                multiplicity: "0..1"
+                default: "TCP/IP"
+            cidr:
+                type: Integer
+                multiplicity: "0..1"
+        associations:
+            connectedIfaces:
+                class: infrastructure_NetworkInterface
+                multiplicity: "0..*"
+                inverse_of: infrastructure_NetworkInterface::belongsTo
+            gateways:
+                class: infrastructure_InternetGateway
+                multiplicity: "0..*"
+            subnets:
+                class: infrastructure_Subnet
+                multiplicity: "0..*"
+    Subnet:
+        superclass: infrastructure_Network
+        associations:
+            connectedTo:
+                class: infrastructure_Network
+                multiplicity: "0..*"
+    NetworkInterface:
+        superclass: infrastructure_InfrastructureElement
+        attributes:
+            endPoint:
+                type: Integer
+                multiplicity: "0..1"
+            speed:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            belongsTo:
+                class: infrastructure_Network
+                multiplicity: "0..1" # This should be "1", but it would break InternetGateway
+            associated:
+                class: infrastructure_SecurityGroup
+                multiplicity: "0..1"
+    InternetGateway:
+        superclass: infrastructure_Node
+        attributes:
+            address:
+                type: String
+                multiplicity: "1"
+    ComputingGroup:
+        superclass: commons_DOMLElement
+        associations:
+            groupedNodes:
+                class: infrastructure_ComputingNode
+                multiplicity: "0..*"
+                inverse_of: infrastructure_ComputingNode::group
+    SecurityGroup:
+        superclass: commons_DOMLElement
+        associations:
+            rules:
+                class: infrastructure_Rule
+                multiplicity: "0..*"
+            ifaces:
+                class: infrastructure_NetworkInterface
+                multiplicity: "0..*"
+                inverse_of: infrastructure_NetworkInterface::associated
+    Rule:
+        superclass: commons_DOMLElement
+        attributes:
+            kind:
+                type: String
+                multiplicity: "1"
+            protocol:
+                type: String
+                multiplicity: "1"
+            fromPort:
+                type: Integer
+                multiplicity: "1"
+            toPort:
+                type: Integer
+                multiplicity: "1"
+            cidr:
+                type: String
+                multiplicity: "0..*"
+    SwarmRole:
+        superclass: commons_DOMLElement
+        attributes:
+            kind:
+                type: String
+                multiplicity: "1"
+        associations:
+            nodes:
+                class: infrastructure_ComputingNode
+                multiplicity: "0..*"
+    Swarm:
+        superclass: infrastructure_ComputingGroup
+        associations:
+            roles:
+                class: infrastructure_SwarmRole
+                multiplicity: "0..*"
+    ExtInfrastructureElement:
+        superclass: infrastructure_InfrastructureElement
+
+concrete:
+    ConcreteInfrastructure:
+        superclass: commons_DOMLElement
+        associations:
+            providers:
+                class: concrete_RuntimeProvider
+                multiplicity: "0..*"
+    ConcreteElement:
+        superclass: commons_DOMLElement
+        associations:
+            refs:
+                class: concrete_ConcreteElement
+                multiplicity: "0..*"
+        attributes:
+            resourceName:
+                type: String
+                multiplicity: "0..1"
+            configurationScript:
+                type: String
+                multiplicity: "0..1"
+            preexisting:
+                multiplicity: "1"
+                type: Boolean
+                default: false
+    RuntimeProvider:
+        superclass: commons_DOMLElement
+        associations:
+            resources:
+                class: concrete_GenericResource
+                multiplicity: "0..*"
+            vms:
+                class: concrete_VirtualMachine
+                multiplicity: "0..*"
+            executionEnvironments:
+                class: concrete_ExecutionEnvironment
+                multiplicity: "0..*"
+            vmImages:
+                class: concrete_VMImage
+                multiplicity: "0..*"
+            containerImages:
+                class: concrete_ContainerImage
+                multiplicity: "0..*"
+            networks:
+                class: concrete_Network
+                multiplicity: "0..*"
+            storages:
+                class: concrete_Storage
+                multiplicity: "0..*"
+            faas:
+                class: concrete_FunctionAsAService
+                multiplicity: "0..*"
+            autoScalingGroups:
+                class: concrete_AutoScalingGroup
+                multiplicity: "0..*"
+    VirtualMachine:
+        superclass: concrete_ConcreteElement
+        attributes:
+            vm_type:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            maps:
+                class: infrastructure_VirtualMachine
+                multiplicity: "0..1"
+    VMImage:
+        superclass: concrete_ConcreteElement
+        attributes:
+            image_name:
+                type: String
+                multiplicity: "1"
+        associations:
+            maps:
+                class: infrastructure_VMImage
+                multiplicity: "0..1"
+    ContainerImage:
+        superclass: concrete_ConcreteElement
+        associations:
+            maps:
+                class: infrastructure_ContainerImage
+                multiplicity: "0..1"
+    ExecutionEnvironment:
+        superclass: concrete_ConcreteElement
+        attributes:
+            instance_type:
+                type: String
+                multiplicity: "0..1"
+            storage_type:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            maps:
+                class: infrastructure_ExecutionEnvironment
+                multiplicity: "0..1"
+    Network:
+        superclass: concrete_ConcreteElement
+        attributes:
+            protocol:
+                type: String
+                multiplicity: "0..1"
+            addressRange:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            subnets:
+                class: concrete_Subnet
+                multiplicity: "0..*"
+            maps:
+                class: infrastructure_Network
+                multiplicity: "0..1"
+    Subnet:
+        superclass: concrete_Network
+    Storage:
+        superclass: concrete_ConcreteElement
+        associations:
+            maps:
+                class: infrastructure_Storage
+                multiplicity: "0..1"
+    FunctionAsAService:
+        superclass: concrete_ConcreteElement
+        associations:
+            maps:
+                class: infrastructure_FunctionAsAService
+                multiplicity: "0..1"
+    AutoScalingGroup:
+        superclass: concrete_ConcreteElement
+        attributes:
+            vm_type:
+                type: String
+                multiplicity: "0..1"
+        associations:
+            maps:
+                class: infrastructure_AutoScalingGroup
+                multiplicity: "0..1"
+    GenericResource:
+        superclass: concrete_ConcreteElement
+        attributes:
+            type:
+                type: "String"
+                multiplicity: "1"
diff --git a/mc_openapi/assets/doml.ecore b/mc_openapi/assets/metamodels/doml_v1.0.ecore
similarity index 100%
rename from mc_openapi/assets/doml.ecore
rename to mc_openapi/assets/metamodels/doml_v1.0.ecore
diff --git a/mc_openapi/doml/doml.ecore b/mc_openapi/assets/metamodels/doml_v2.0.ecore
similarity index 86%
rename from mc_openapi/doml/doml.ecore
rename to mc_openapi/assets/metamodels/doml_v2.0.ecore
index e8cc0d6e555f08f8fcf9b10522f40ffaecbcca7d..9c23605fed74133837525dfab8b471013077d262 100644
--- a/mc_openapi/doml/doml.ecore
+++ b/mc_openapi/assets/metamodels/doml_v2.0.ecore
@@ -9,6 +9,8 @@
   <eSubpackages name="commons" nsURI="http://www.piacere-project.eu/doml/commons"
       nsPrefix="commons">
     <eClassifiers xsi:type="ecore:EClass" name="DOMLModel" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="version" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+          changeable="false" defaultValueLiteral="v2"/>
       <eStructuralFeatures xsi:type="ecore:EReference" name="application" eType="#//application/ApplicationLayer"
           containment="true"/>
       <eStructuralFeatures xsi:type="ecore:EReference" name="infrastructure" eType="#//infrastructure/InfrastructureLayer"
@@ -26,12 +28,23 @@
       <eStructuralFeatures xsi:type="ecore:EReference" name="functionalRequirements"
           upperBound="-1" eType="#//commons/Requirement" containment="true"/>
     </eClassifiers>
-    <eClassifiers xsi:type="ecore:EClass" name="Property">
+    <eClassifiers xsi:type="ecore:EClass" name="Property" abstract="true">
+      <eOperations name="getValue" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EJavaObject"/>
       <eStructuralFeatures xsi:type="ecore:EAttribute" name="key" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
-      <eStructuralFeatures xsi:type="ecore:EAttribute" name="type" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
-      <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
       <eStructuralFeatures xsi:type="ecore:EReference" name="reference" eType="#//commons/DOMLElement"/>
     </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="IProperty" eSuperTypes="#//commons/Property">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="SProperty" eSuperTypes="#//commons/Property">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="FProperty" eSuperTypes="#//commons/Property">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="BProperty" eSuperTypes="#//commons/Property">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBooleanObject"/>
+    </eClassifiers>
     <eClassifiers xsi:type="ecore:EClass" name="ExtensionElement" abstract="true">
       <eStructuralFeatures xsi:type="ecore:EAttribute" name="metaclassName" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
     </eClassifiers>
@@ -54,7 +67,6 @@
           eType="#//infrastructure/InfrastructureElement"/>
     </eClassifiers>
     <eClassifiers xsi:type="ecore:EClass" name="Requirement">
-      <eStructuralFeatures xsi:type="ecore:EAttribute" name="identifier" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
       <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
       <eStructuralFeatures xsi:type="ecore:EAttribute" name="description" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
       <eStructuralFeatures xsi:type="ecore:EAttribute" name="property" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
@@ -123,10 +135,6 @@
     <eClassifiers xsi:type="ecore:EClass" name="InfrastructureLayer" eSuperTypes="#//commons/DOMLElement">
       <eStructuralFeatures xsi:type="ecore:EReference" name="nodes" upperBound="-1"
           eType="#//infrastructure/ComputingNode" containment="true"/>
-      <eStructuralFeatures xsi:type="ecore:EReference" name="networks" upperBound="-1"
-          eType="#//infrastructure/VPC" containment="true"/>
-      <eStructuralFeatures xsi:type="ecore:EReference" name="secGroups" upperBound="-1"
-          eType="#//infrastructure/SecurityGroup" containment="true"/>
       <eStructuralFeatures xsi:type="ecore:EReference" name="generators" upperBound="-1"
           eType="#//infrastructure/ComputingNodeGenerator" containment="true"/>
       <eStructuralFeatures xsi:type="ecore:EReference" name="storages" upperBound="-1"
@@ -135,12 +143,18 @@
           eType="#//infrastructure/FunctionAsAService" containment="true"/>
       <eStructuralFeatures xsi:type="ecore:EReference" name="credentials" upperBound="-1"
           eType="#//infrastructure/Credentials" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="groups" upperBound="-1"
+          eType="#//infrastructure/ComputingGroup" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="securityGroups" upperBound="-1"
+          eType="#//infrastructure/SecurityGroup" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="networks" upperBound="-1"
+          eType="#//infrastructure/Network" containment="true"/>
     </eClassifiers>
     <eClassifiers xsi:type="ecore:EClass" name="ComputingGroup" abstract="true" eSuperTypes="#//commons/DOMLElement">
       <eStructuralFeatures xsi:type="ecore:EReference" name="groupedNodes" upperBound="-1"
           eType="#//infrastructure/ComputingNode" eOpposite="#//infrastructure/ComputingNode/group"/>
     </eClassifiers>
-    <eClassifiers xsi:type="ecore:EClass" name="AutoScalingGroup" eSuperTypes="#//infrastructure/ComputingNode">
+    <eClassifiers xsi:type="ecore:EClass" name="AutoScalingGroup" eSuperTypes="#//infrastructure/ComputingGroup">
       <eStructuralFeatures xsi:type="ecore:EReference" name="machineDefinition" lowerBound="1"
           eType="#//infrastructure/VirtualMachine" containment="true"/>
       <eStructuralFeatures xsi:type="ecore:EAttribute" name="min" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"
@@ -163,14 +177,14 @@
       <eStructuralFeatures xsi:type="ecore:EAttribute" name="protocol" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
       <eStructuralFeatures xsi:type="ecore:EAttribute" name="fromPort" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/>
       <eStructuralFeatures xsi:type="ecore:EAttribute" name="toPort" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/>
-      <eStructuralFeatures xsi:type="ecore:EAttribute" name="addressRanges" upperBound="-1"
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="cidr" upperBound="-1"
           eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
     </eClassifiers>
     <eClassifiers xsi:type="ecore:EEnum" name="RuleKind">
       <eLiterals name="EGRESS"/>
       <eLiterals name="INGRESS" value="1"/>
     </eClassifiers>
-    <eClassifiers xsi:type="ecore:EClass" name="SecurityGroup" eSuperTypes="#//infrastructure/ComputingGroup">
+    <eClassifiers xsi:type="ecore:EClass" name="SecurityGroup" eSuperTypes="#//commons/DOMLElement">
       <eStructuralFeatures xsi:type="ecore:EReference" name="rules" upperBound="-1"
           eType="#//infrastructure/Rule" containment="true"/>
       <eStructuralFeatures xsi:type="ecore:EReference" name="ifaces" upperBound="-1"
@@ -182,9 +196,9 @@
     <eClassifiers xsi:type="ecore:EClass" name="ComputingNode" abstract="true" eSuperTypes="#//infrastructure/InfrastructureElement">
       <eStructuralFeatures xsi:type="ecore:EAttribute" name="architecture" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
       <eStructuralFeatures xsi:type="ecore:EAttribute" name="os" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
-      <eStructuralFeatures xsi:type="ecore:EAttribute" name="memory" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="memory_mb" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
       <eStructuralFeatures xsi:type="ecore:EAttribute" name="storage" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
-      <eStructuralFeatures xsi:type="ecore:EAttribute" name="cpu" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="cpu_count" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/>
       <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
       <eStructuralFeatures xsi:type="ecore:EReference" name="ifaces" upperBound="-1"
           eType="#//infrastructure/NetworkInterface" containment="true"/>
@@ -225,17 +239,16 @@
     <eClassifiers xsi:type="ecore:EClass" name="Container" eSuperTypes="#//infrastructure/ComputingNode">
       <eStructuralFeatures xsi:type="ecore:EReference" name="generatedFrom" eType="#//infrastructure/ContainerImage"
           eOpposite="#//infrastructure/ContainerImage/generatedContainers"/>
-      <eStructuralFeatures xsi:type="ecore:EReference" name="host" eType="#//infrastructure/ComputingNode"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="hosts" upperBound="-1"
+          eType="#//infrastructure/ComputingNode"/>
     </eClassifiers>
-    <eClassifiers xsi:type="ecore:EClass" name="Network" abstract="true" eSuperTypes="#//commons/DOMLElement">
+    <eClassifiers xsi:type="ecore:EClass" name="Network" eSuperTypes="#//commons/DOMLElement">
       <eStructuralFeatures xsi:type="ecore:EAttribute" name="protocol" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
       <eStructuralFeatures xsi:type="ecore:EAttribute" name="addressRange" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
       <eStructuralFeatures xsi:type="ecore:EReference" name="connectedIfaces" upperBound="-1"
           eType="#//infrastructure/NetworkInterface" eOpposite="#//infrastructure/NetworkInterface/belongsTo"/>
       <eStructuralFeatures xsi:type="ecore:EReference" name="igws" upperBound="-1"
           eType="#//infrastructure/InternetGateway" containment="true"/>
-    </eClassifiers>
-    <eClassifiers xsi:type="ecore:EClass" name="VPC" eSuperTypes="#//infrastructure/Network">
       <eStructuralFeatures xsi:type="ecore:EReference" name="subnets" upperBound="-1"
           eType="#//infrastructure/Subnet" containment="true"/>
     </eClassifiers>
@@ -253,7 +266,8 @@
     </eClassifiers>
     <eClassifiers xsi:type="ecore:EClass" name="InternetGateway" eSuperTypes="#//infrastructure/NetworkInterface"/>
     <eClassifiers xsi:type="ecore:EClass" name="Storage" eSuperTypes="#//infrastructure/InfrastructureElement">
-      <eStructuralFeatures xsi:type="ecore:EAttribute" name="storage" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="label" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="size_gb" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt"/>
       <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
       <eStructuralFeatures xsi:type="ecore:EReference" name="ifaces" upperBound="-1"
           eType="#//infrastructure/NetworkInterface" containment="true"/>
@@ -265,6 +279,8 @@
     </eClassifiers>
     <eClassifiers xsi:type="ecore:EClass" name="Credentials" abstract="true" eSuperTypes="#//commons/DOMLElement"/>
     <eClassifiers xsi:type="ecore:EClass" name="KeyPair" eSuperTypes="#//infrastructure/Credentials">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="user" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="keyfile" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
       <eStructuralFeatures xsi:type="ecore:EAttribute" name="algorithm" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
       <eStructuralFeatures xsi:type="ecore:EAttribute" name="bits" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/>
     </eClassifiers>
@@ -272,6 +288,21 @@
       <eStructuralFeatures xsi:type="ecore:EAttribute" name="username" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
       <eStructuralFeatures xsi:type="ecore:EAttribute" name="password" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
     </eClassifiers>
+    <eClassifiers xsi:type="ecore:EEnum" name="RoleKind">
+      <eLiterals name="NONE"/>
+      <eLiterals name="MANAGER" value="1"/>
+      <eLiterals name="WORKER" value="2"/>
+      <eLiterals name="MASTER" value="3"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="SwarmRole" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" eType="#//infrastructure/RoleKind"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="nodes" upperBound="-1"
+          eType="#//infrastructure/ComputingNode" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Swarm" eSuperTypes="#//infrastructure/ComputingGroup">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="roles" upperBound="-1"
+          eType="#//infrastructure/SwarmRole" containment="true"/>
+    </eClassifiers>
     <eClassifiers xsi:type="ecore:EClass" name="ExtInfrastructureElement" eSuperTypes="#//infrastructure/InfrastructureElement #//commons/ExtensionElement"/>
   </eSubpackages>
   <eSubpackages name="concrete" nsURI="http://www.piacere-project.eu/doml/concrete"
@@ -334,7 +365,17 @@
       <eStructuralFeatures xsi:type="ecore:EReference" name="nonfunctionalRequirements"
           upperBound="-1" eType="#//commons/Requirement" containment="true"/>
     </eClassifiers>
-    <eClassifiers xsi:type="ecore:EClass" name="OptimizationSolution" eSuperTypes="#//commons/Configuration"/>
+    <eClassifiers xsi:type="ecore:EClass" name="ObjectiveValue">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="availability" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="performance" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="OptimizationSolution" eSuperTypes="#//commons/Configuration">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="objectives" eType="#//optimization/ObjectiveValue"
+          containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="decisions" upperBound="-1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
     <eClassifiers xsi:type="ecore:EClass" name="OptimizationObjective" abstract="true"
         eSuperTypes="#//commons/DOMLElement">
       <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" lowerBound="1"
diff --git a/mc_openapi/assets/metamodels/doml_v2.1.ecore b/mc_openapi/assets/metamodels/doml_v2.1.ecore
new file mode 100644
index 0000000000000000000000000000000000000000..02f3904f45a536afce64bd47b8e8a4f89b8209a4
--- /dev/null
+++ b/mc_openapi/assets/metamodels/doml_v2.1.ecore
@@ -0,0 +1,396 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="doml" nsURI="http://www.piacere-project.eu/doml" nsPrefix="doml">
+  <eAnnotations source="emf.gen">
+    <details key="basePackage" value="eu.piacere.doml"/>
+    <details key="fileExtensions" value="domlx"/>
+    <details key="complianceLevel" value="JDK80"/>
+  </eAnnotations>
+  <eSubpackages name="commons" nsURI="http://www.piacere-project.eu/doml/commons"
+      nsPrefix="commons">
+    <eClassifiers xsi:type="ecore:EClass" name="DOMLModel" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="version" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+          changeable="false" defaultValueLiteral="v2"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="application" eType="#//application/ApplicationLayer"
+          containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="infrastructure" eType="#//infrastructure/InfrastructureLayer"
+          containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="concretizations" upperBound="-1"
+          eType="#//concrete/ConcreteInfrastructure" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="optimization" eType="#//optimization/OptimizationLayer"
+          containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="configurations" upperBound="-1"
+          eType="#//commons/Configuration" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="activeConfiguration"
+          eType="#//commons/Configuration"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="activeInfrastructure"
+          eType="#//concrete/ConcreteInfrastructure"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="functionalRequirements"
+          upperBound="-1" eType="#//commons/Requirement" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Property" abstract="true">
+      <eOperations name="getValue" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EJavaObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="key" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="reference" eType="#//commons/DOMLElement"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="IProperty" eSuperTypes="#//commons/Property">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="SProperty" eSuperTypes="#//commons/Property">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="FProperty" eSuperTypes="#//commons/Property">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="BProperty" eSuperTypes="#//commons/Property">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBooleanObject"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ExtensionElement" abstract="true">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="metaclassName" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="DOMLElement" abstract="true">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="description" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="annotations" upperBound="-1"
+          eType="#//commons/Property" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="contributesTo" upperBound="-1"
+          eType="#//commons/Requirement" eOpposite="#//commons/Requirement/predicatesOn"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Configuration" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="deployments" upperBound="-1"
+          eType="#//commons/Deployment" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Deployment">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="component" lowerBound="1"
+          eType="#//application/ApplicationComponent"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="node" lowerBound="1"
+          eType="#//infrastructure/InfrastructureElement"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Requirement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="description" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="property" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="predicatesOn" upperBound="-1"
+          eType="#//commons/DOMLElement" eOpposite="#//commons/DOMLElement/contributesTo"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="RangedRequirement" eSuperTypes="#//commons/Requirement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="min" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="max" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="EnumeratedRequirement" eSuperTypes="#//commons/Requirement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="values" upperBound="-1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="DeploymentRequirement" abstract="true"
+        eSuperTypes="#//commons/Requirement"/>
+    <eClassifiers xsi:type="ecore:EClass" name="DeploymentToNodeTypeRequirement" eSuperTypes="#//commons/DeploymentRequirement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="validTypes" upperBound="-1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="DeploymentToNodeWithPropertyRequirement"
+        eSuperTypes="#//commons/DeploymentRequirement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="min" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="max" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="values" upperBound="-1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="DeploymentToSpecificNodeRequirement"
+        eSuperTypes="#//commons/DeploymentRequirement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="validElements" upperBound="-1"
+          eType="#//infrastructure/InfrastructureElement"/>
+    </eClassifiers>
+  </eSubpackages>
+  <eSubpackages name="application" nsURI="http://www.piacere-project.eu/doml/application"
+      nsPrefix="app">
+    <eClassifiers xsi:type="ecore:EClass" name="ApplicationLayer" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="components" upperBound="-1"
+          eType="#//application/ApplicationComponent" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ApplicationComponent" abstract="true"
+        eSuperTypes="#//commons/DOMLElement"/>
+    <eClassifiers xsi:type="ecore:EClass" name="SoftwareComponent" eSuperTypes="#//application/ApplicationComponent">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="isPersistent" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBooleanObject"
+          defaultValueLiteral="false"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="licenseCost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="configFile" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="exposedInterfaces" upperBound="-1"
+          eType="#//application/SoftwareInterface" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="consumedInterfaces" upperBound="-1"
+          eType="#//application/SoftwareInterface"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="DBMS" eSuperTypes="#//application/SoftwareComponent"/>
+    <eClassifiers xsi:type="ecore:EClass" name="SaaS" eSuperTypes="#//application/ApplicationComponent">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="licenseCost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="exposedInterfaces" upperBound="-1"
+          eType="#//application/SoftwareInterface" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="SaaSDBMS" eSuperTypes="#//application/SaaS"/>
+    <eClassifiers xsi:type="ecore:EClass" name="SoftwareInterface" eSuperTypes="#//application/ApplicationComponent">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="endPoint" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ExtApplicationComponent" eSuperTypes="#//application/ApplicationComponent #//commons/ExtensionElement"/>
+  </eSubpackages>
+  <eSubpackages name="infrastructure" nsURI="http://www.piacere-project.eu/doml/infrastructure"
+      nsPrefix="infra">
+    <eClassifiers xsi:type="ecore:EClass" name="InfrastructureLayer" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="nodes" upperBound="-1"
+          eType="#//infrastructure/ComputingNode" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="generators" upperBound="-1"
+          eType="#//infrastructure/ComputingNodeGenerator" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="storages" upperBound="-1"
+          eType="#//infrastructure/Storage" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="faas" upperBound="-1"
+          eType="#//infrastructure/FunctionAsAService" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="credentials" upperBound="-1"
+          eType="#//infrastructure/Credentials" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="groups" upperBound="-1"
+          eType="#//infrastructure/ComputingGroup" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="securityGroups" upperBound="-1"
+          eType="#//infrastructure/SecurityGroup" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="networks" upperBound="-1"
+          eType="#//infrastructure/Network" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ComputingGroup" abstract="true" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="groupedNodes" upperBound="-1"
+          eType="#//infrastructure/ComputingNode" eOpposite="#//infrastructure/ComputingNode/group"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="AutoScalingGroup" eSuperTypes="#//infrastructure/ComputingGroup">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="machineDefinition" lowerBound="1"
+          eType="#//infrastructure/VirtualMachine" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="min" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"
+          defaultValueLiteral="1"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="max" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"
+          defaultValueLiteral="1"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="securityGroup" eType="#//infrastructure/SecurityGroup"
+          containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="loadBalancer" eType="#//infrastructure/LoadBalancerKind"
+          defaultValueLiteral="DEFAULT"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EEnum" name="LoadBalancerKind">
+      <eLiterals name="DEFAULT"/>
+      <eLiterals name="INTERNAL" value="1"/>
+      <eLiterals name="EXTERNAL" value="2"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Rule" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" eType="#//infrastructure/RuleKind"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="protocol" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="fromPort" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="toPort" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="cidr" upperBound="-1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EEnum" name="RuleKind">
+      <eLiterals name="EGRESS"/>
+      <eLiterals name="INGRESS" value="1"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="SecurityGroup" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="rules" upperBound="-1"
+          eType="#//infrastructure/Rule" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="ifaces" upperBound="-1"
+          eType="#//infrastructure/NetworkInterface" eOpposite="#//infrastructure/NetworkInterface/associated"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="AvailabilityGroup" eSuperTypes="#//infrastructure/ComputingGroup"/>
+    <eClassifiers xsi:type="ecore:EClass" name="InfrastructureElement" abstract="true"
+        eSuperTypes="#//commons/DOMLElement"/>
+    <eClassifiers xsi:type="ecore:EClass" name="ComputingNode" abstract="true" eSuperTypes="#//infrastructure/InfrastructureElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="architecture" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="os" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="memory_mb" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="storage" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="cpu_count" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="ifaces" upperBound="-1"
+          eType="#//infrastructure/NetworkInterface" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="location" eType="#//infrastructure/Location"
+          containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="credentials" eType="#//infrastructure/Credentials"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="group" eType="#//infrastructure/ComputingGroup"
+          eOpposite="#//infrastructure/ComputingGroup/groupedNodes"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ComputingNodeGenerator" abstract="true"
+        eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="uri" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" eType="#//infrastructure/GeneratorKind"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EEnum" name="GeneratorKind">
+      <eLiterals name="SCRIPT"/>
+      <eLiterals name="IMAGE" value="1"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="VMImage" eSuperTypes="#//infrastructure/ComputingNodeGenerator">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="generatedVMs" upperBound="-1"
+          eType="#//infrastructure/VirtualMachine" eOpposite="#//infrastructure/VirtualMachine/generatedFrom"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ContainerImage" eSuperTypes="#//infrastructure/ComputingNodeGenerator">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="generatedContainers"
+          upperBound="-1" eType="#//infrastructure/Container" eOpposite="#//infrastructure/Container/generatedFrom"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="PhysicalComputingNode" eSuperTypes="#//infrastructure/ComputingNode"/>
+    <eClassifiers xsi:type="ecore:EClass" name="VirtualMachine" eSuperTypes="#//infrastructure/ComputingNode">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="sizeDescription" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="generatedFrom" eType="#//infrastructure/VMImage"
+          eOpposite="#//infrastructure/VMImage/generatedVMs"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Location" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="region" lowerBound="1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="zone" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ContainerConfig" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="container_port" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="vm_port" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="host" eType="#//infrastructure/ComputingNode"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="iface" eType="#//infrastructure/NetworkInterface"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Container" eSuperTypes="#//infrastructure/ComputingNode">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="generatedFrom" eType="#//infrastructure/ContainerImage"
+          eOpposite="#//infrastructure/ContainerImage/generatedContainers"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="configs" upperBound="-1"
+          eType="#//infrastructure/ContainerConfig" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Network" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="protocol" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="addressRange" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="connectedIfaces" upperBound="-1"
+          eType="#//infrastructure/NetworkInterface" eOpposite="#//infrastructure/NetworkInterface/belongsTo"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="igws" upperBound="-1"
+          eType="#//infrastructure/InternetGateway" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="subnets" upperBound="-1"
+          eType="#//infrastructure/Subnet" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Subnet" eSuperTypes="#//infrastructure/Network">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="connectedTo" upperBound="-1"
+          eType="#//infrastructure/Subnet"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="NetworkInterface" eSuperTypes="#//infrastructure/InfrastructureElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="speed" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="endPoint" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="belongsTo" eType="#//infrastructure/Network"
+          eOpposite="#//infrastructure/Network/connectedIfaces"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="associated" eType="#//infrastructure/SecurityGroup"
+          eOpposite="#//infrastructure/SecurityGroup/ifaces"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="InternetGateway" eSuperTypes="#//infrastructure/NetworkInterface"/>
+    <eClassifiers xsi:type="ecore:EClass" name="Storage" eSuperTypes="#//infrastructure/InfrastructureElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="label" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="size_gb" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="ifaces" upperBound="-1"
+          eType="#//infrastructure/NetworkInterface" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="FunctionAsAService" eSuperTypes="#//infrastructure/InfrastructureElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="ifaces" upperBound="-1"
+          eType="#//infrastructure/NetworkInterface" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Credentials" abstract="true" eSuperTypes="#//commons/DOMLElement"/>
+    <eClassifiers xsi:type="ecore:EClass" name="KeyPair" eSuperTypes="#//infrastructure/Credentials">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="user" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="keyfile" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="algorithm" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="bits" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="UserPass" eSuperTypes="#//infrastructure/Credentials">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="username" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="password" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EEnum" name="RoleKind">
+      <eLiterals name="NONE"/>
+      <eLiterals name="MANAGER" value="1"/>
+      <eLiterals name="WORKER" value="2"/>
+      <eLiterals name="MASTER" value="3"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="SwarmRole" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" eType="#//infrastructure/RoleKind"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="nodes" upperBound="-1"
+          eType="#//infrastructure/ComputingNode" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Swarm" eSuperTypes="#//infrastructure/ComputingGroup">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="roles" upperBound="-1"
+          eType="#//infrastructure/SwarmRole" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ExtInfrastructureElement" eSuperTypes="#//infrastructure/InfrastructureElement #//commons/ExtensionElement"/>
+  </eSubpackages>
+  <eSubpackages name="concrete" nsURI="http://www.piacere-project.eu/doml/concrete"
+      nsPrefix="concrete">
+    <eClassifiers xsi:type="ecore:EClass" name="ConcreteInfrastructure" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="providers" upperBound="-1"
+          eType="#//concrete/RuntimeProvider" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="RuntimeProvider" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="vms" upperBound="-1"
+          eType="#//concrete/VirtualMachine" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="vmImages" upperBound="-1"
+          eType="#//concrete/VMImage" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="containerImages" upperBound="-1"
+          eType="#//concrete/ContainerImage" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="networks" upperBound="-1"
+          eType="#//concrete/Network" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="storages" upperBound="-1"
+          eType="#//concrete/Storage" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="faas" upperBound="-1"
+          eType="#//concrete/FunctionAsAService" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="group" upperBound="-1"
+          eType="#//concrete/ComputingGroup" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ConcreteElement" abstract="true" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="configurationScript"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="VirtualMachine" eSuperTypes="#//concrete/ConcreteElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/VirtualMachine"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="VMImage" eSuperTypes="#//concrete/ConcreteElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/VMImage"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ContainerImage" eSuperTypes="#//concrete/ConcreteElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/ContainerImage"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Network" eSuperTypes="#//concrete/ConcreteElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="address" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/Network"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Storage" eSuperTypes="#//concrete/ConcreteElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/Storage"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="FunctionAsAService" eSuperTypes="#//concrete/ConcreteElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/FunctionAsAService"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ComputingGroup" eSuperTypes="#//concrete/ConcreteElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/ComputingGroup"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ExtConcreteElement" eSuperTypes="#//concrete/ConcreteElement #//commons/ExtensionElement"/>
+  </eSubpackages>
+  <eSubpackages name="optimization" nsURI="http://www.piacere-project.eu/doml/optimization"
+      nsPrefix="optimization">
+    <eClassifiers xsi:type="ecore:EClass" name="OptimizationLayer" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="startingHint" eType="#//commons/Configuration"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="solutions" upperBound="-1"
+          eType="#//optimization/OptimizationSolution" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="objectives" upperBound="-1"
+          eType="#//optimization/OptimizationObjective" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="nonfunctionalRequirements"
+          upperBound="-1" eType="#//commons/Requirement" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ObjectiveValue">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="availability" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="performance" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="OptimizationSolution" eSuperTypes="#//commons/Configuration">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="objectives" eType="#//optimization/ObjectiveValue"
+          containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="decisions" upperBound="-1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="OptimizationObjective" abstract="true"
+        eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" lowerBound="1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+          defaultValueLiteral="Max"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="property" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="CountObjective" eSuperTypes="#//optimization/OptimizationObjective"/>
+    <eClassifiers xsi:type="ecore:EClass" name="MeasurableObjective" eSuperTypes="#//optimization/OptimizationObjective"/>
+    <eClassifiers xsi:type="ecore:EClass" name="ExtOptimizationObjective" eSuperTypes="#//optimization/OptimizationObjective #//commons/ExtensionElement"/>
+  </eSubpackages>
+</ecore:EPackage>
diff --git a/mc_openapi/assets/metamodels/doml_v2.2.1.ecore b/mc_openapi/assets/metamodels/doml_v2.2.1.ecore
new file mode 100644
index 0000000000000000000000000000000000000000..cbff3c686bae8d319a1d8c6a272d16b18cc65034
--- /dev/null
+++ b/mc_openapi/assets/metamodels/doml_v2.2.1.ecore
@@ -0,0 +1,423 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="doml" nsURI="http://www.piacere-project.eu/doml" nsPrefix="doml">
+  <eAnnotations source="emf.gen">
+    <details key="basePackage" value="eu.piacere.doml"/>
+    <details key="fileExtensions" value="domlx"/>
+    <details key="complianceLevel" value="JDK80"/>
+  </eAnnotations>
+  <eSubpackages name="commons" nsURI="http://www.piacere-project.eu/doml/commons"
+      nsPrefix="commons">
+    <eClassifiers xsi:type="ecore:EClass" name="DOMLModel" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="version" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+          defaultValueLiteral="2.2"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="application" eType="#//application/ApplicationLayer"
+          containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="infrastructure" eType="#//infrastructure/InfrastructureLayer"
+          containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="concretizations" upperBound="-1"
+          eType="#//concrete/ConcreteInfrastructure" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="optimization" eType="#//optimization/OptimizationLayer"
+          containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="configurations" upperBound="-1"
+          eType="#//commons/Configuration" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="activeConfiguration"
+          eType="#//commons/Configuration"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="activeInfrastructure"
+          eType="#//concrete/ConcreteInfrastructure"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="functionalRequirements"
+          upperBound="-1" eType="#//commons/Requirement" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Property" abstract="true">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="key" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="IProperty" eSuperTypes="#//commons/Property">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="SProperty" eSuperTypes="#//commons/Property">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="FProperty" eSuperTypes="#//commons/Property">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="BProperty" eSuperTypes="#//commons/Property">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBooleanObject"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ExtensionElement" abstract="true">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="metaclassName" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="DOMLElement" abstract="true">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="description" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="annotations" upperBound="-1"
+          eType="#//commons/Property" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="contributesTo" upperBound="-1"
+          eType="#//commons/Requirement" eOpposite="#//commons/Requirement/predicatesOn"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Configuration" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="deployments" upperBound="-1"
+          eType="#//commons/Deployment" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="DeployableElement" abstract="true"/>
+    <eClassifiers xsi:type="ecore:EClass" name="Deployment">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="component" lowerBound="1"
+          eType="#//commons/DeployableElement"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="node" lowerBound="1"
+          eType="#//infrastructure/InfrastructureElement"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Requirement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="description" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="property" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="predicatesOn" upperBound="-1"
+          eType="#//commons/DOMLElement" eOpposite="#//commons/DOMLElement/contributesTo"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="RangedRequirement" eSuperTypes="#//commons/Requirement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="min" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="max" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="EnumeratedRequirement" eSuperTypes="#//commons/Requirement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="values" upperBound="-1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="DeploymentRequirement" abstract="true"
+        eSuperTypes="#//commons/Requirement"/>
+    <eClassifiers xsi:type="ecore:EClass" name="DeploymentToNodeTypeRequirement" eSuperTypes="#//commons/DeploymentRequirement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="validTypes" upperBound="-1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="DeploymentToNodeWithPropertyRequirement"
+        eSuperTypes="#//commons/DeploymentRequirement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="min" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="max" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="values" upperBound="-1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="DeploymentToSpecificNodeRequirement"
+        eSuperTypes="#//commons/DeploymentRequirement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="validElements" upperBound="-1"
+          eType="#//infrastructure/InfrastructureElement"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Credentials" abstract="true" eSuperTypes="#//commons/DOMLElement"/>
+    <eClassifiers xsi:type="ecore:EClass" name="KeyPair" eSuperTypes="#//commons/Credentials">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="user" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="keyfile" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="algorithm" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="bits" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="UserPass" eSuperTypes="#//commons/Credentials">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="username" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="password" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Source" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="entry" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="backend" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+  </eSubpackages>
+  <eSubpackages name="application" nsURI="http://www.piacere-project.eu/doml/application"
+      nsPrefix="app">
+    <eClassifiers xsi:type="ecore:EClass" name="ApplicationLayer" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="components" upperBound="-1"
+          eType="#//application/ApplicationComponent" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ApplicationComponent" abstract="true"
+        eSuperTypes="#//commons/DOMLElement #//commons/DeployableElement"/>
+    <eClassifiers xsi:type="ecore:EClass" name="SoftwareComponent" eSuperTypes="#//application/ApplicationComponent">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="isPersistent" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBooleanObject"
+          defaultValueLiteral="false"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="licenseCost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="exposedInterfaces" upperBound="-1"
+          eType="#//application/SoftwareInterface" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="consumedInterfaces" upperBound="-1"
+          eType="#//application/SoftwareInterface"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="src" eType="#//commons/Source"
+          containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="DBMS" eSuperTypes="#//application/SoftwareComponent"/>
+    <eClassifiers xsi:type="ecore:EClass" name="SaaS" eSuperTypes="#//application/ApplicationComponent">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="licenseCost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="exposedInterfaces" upperBound="-1"
+          eType="#//application/SoftwareInterface" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="SaaSDBMS" eSuperTypes="#//application/SaaS"/>
+    <eClassifiers xsi:type="ecore:EClass" name="SoftwareInterface" eSuperTypes="#//application/ApplicationComponent">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="endPoint" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ExtApplicationComponent" eSuperTypes="#//application/ApplicationComponent #//commons/ExtensionElement"/>
+  </eSubpackages>
+  <eSubpackages name="infrastructure" nsURI="http://www.piacere-project.eu/doml/infrastructure"
+      nsPrefix="infra">
+    <eClassifiers xsi:type="ecore:EClass" name="InfrastructureLayer" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="nodes" upperBound="-1"
+          eType="#//infrastructure/ComputingNode" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="generators" upperBound="-1"
+          eType="#//infrastructure/ComputingNodeGenerator" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="storages" upperBound="-1"
+          eType="#//infrastructure/Storage" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="faas" upperBound="-1"
+          eType="#//infrastructure/FunctionAsAService" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="credentials" upperBound="-1"
+          eType="#//commons/Credentials" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="groups" upperBound="-1"
+          eType="#//infrastructure/ComputingGroup" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="securityGroups" upperBound="-1"
+          eType="#//infrastructure/SecurityGroup" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="networks" upperBound="-1"
+          eType="#//infrastructure/Network" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="rules" upperBound="-1"
+          eType="#//infrastructure/MonitoringRule" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="MonitoringRule" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="condition" lowerBound="1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="strategy" lowerBound="1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="strategyConfigurationString"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ComputingGroup" abstract="true" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="groupedNodes" upperBound="-1"
+          eType="#//infrastructure/ComputingNode" eOpposite="#//infrastructure/ComputingNode/group"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="AutoScalingGroup" eSuperTypes="#//infrastructure/ComputingGroup">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="machineDefinition" lowerBound="1"
+          eType="#//infrastructure/VirtualMachine" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="min" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"
+          defaultValueLiteral="1"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="max" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"
+          defaultValueLiteral="1"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="securityGroup" eType="#//infrastructure/SecurityGroup"
+          containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="loadBalancer" eType="#//infrastructure/LoadBalancerKind"
+          defaultValueLiteral="DEFAULT"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EEnum" name="LoadBalancerKind">
+      <eLiterals name="DEFAULT"/>
+      <eLiterals name="INTERNAL" value="1"/>
+      <eLiterals name="EXTERNAL" value="2"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Rule" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" eType="#//infrastructure/RuleKind"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="protocol" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="fromPort" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="toPort" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="cidr" upperBound="-1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EEnum" name="RuleKind">
+      <eLiterals name="EGRESS"/>
+      <eLiterals name="INGRESS" value="1"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="SecurityGroup" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="rules" upperBound="-1"
+          eType="#//infrastructure/Rule" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="ifaces" upperBound="-1"
+          eType="#//infrastructure/NetworkInterface" eOpposite="#//infrastructure/NetworkInterface/associated"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="AvailabilityGroup" eSuperTypes="#//infrastructure/ComputingGroup"/>
+    <eClassifiers xsi:type="ecore:EClass" name="InfrastructureElement" abstract="true"
+        eSuperTypes="#//commons/DOMLElement #//commons/DeployableElement"/>
+    <eClassifiers xsi:type="ecore:EClass" name="ComputingNode" abstract="true" eSuperTypes="#//infrastructure/InfrastructureElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="architecture" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="os" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="memory_mb" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="storage" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="cpu_count" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="ifaces" upperBound="-1"
+          eType="#//infrastructure/NetworkInterface" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="location" eType="#//infrastructure/Location"
+          containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="credentials" eType="#//commons/Credentials"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="group" eType="#//infrastructure/ComputingGroup"
+          eOpposite="#//infrastructure/ComputingGroup/groupedNodes"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="disabledMonitorings"
+          upperBound="-1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ComputingNodeGenerator" abstract="true"
+        eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="uri" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" eType="#//infrastructure/GeneratorKind"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EEnum" name="GeneratorKind">
+      <eLiterals name="SCRIPT"/>
+      <eLiterals name="IMAGE" value="1"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="VMImage" eSuperTypes="#//infrastructure/ComputingNodeGenerator">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="generatedVMs" upperBound="-1"
+          eType="#//infrastructure/VirtualMachine" eOpposite="#//infrastructure/VirtualMachine/generatedFrom"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ContainerImage" eSuperTypes="#//infrastructure/ComputingNodeGenerator">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="generatedContainers"
+          upperBound="-1" eType="#//infrastructure/Container" eOpposite="#//infrastructure/Container/generatedFrom"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="PhysicalComputingNode" eSuperTypes="#//infrastructure/ComputingNode"/>
+    <eClassifiers xsi:type="ecore:EClass" name="VirtualMachine" eSuperTypes="#//infrastructure/ComputingNode">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="sizeDescription" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="generatedFrom" eType="#//infrastructure/VMImage"
+          eOpposite="#//infrastructure/VMImage/generatedVMs"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Location" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="region" lowerBound="1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="zone" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ContainerConfig" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="container_port" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="vm_port" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="host" eType="#//infrastructure/ComputingNode"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="iface" eType="#//infrastructure/NetworkInterface"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Container" eSuperTypes="#//infrastructure/ComputingNode">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="generatedFrom" eType="#//infrastructure/ContainerImage"
+          eOpposite="#//infrastructure/ContainerImage/generatedContainers"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="configs" upperBound="-1"
+          eType="#//infrastructure/ContainerConfig" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Network" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="protocol" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="addressRange" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="connectedIfaces" upperBound="-1"
+          eType="#//infrastructure/NetworkInterface" eOpposite="#//infrastructure/NetworkInterface/belongsTo"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="gateways" upperBound="-1"
+          eType="#//infrastructure/InternetGateway" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="subnets" upperBound="-1"
+          eType="#//infrastructure/Subnet" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Subnet" eSuperTypes="#//infrastructure/Network">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="connectedTo" upperBound="-1"
+          eType="#//infrastructure/Subnet"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="NetworkInterface" eSuperTypes="#//infrastructure/InfrastructureElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="speed" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="endPoint" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="belongsTo" eType="#//infrastructure/Network"
+          eOpposite="#//infrastructure/Network/connectedIfaces"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="associated" eType="#//infrastructure/SecurityGroup"
+          eOpposite="#//infrastructure/SecurityGroup/ifaces"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="InternetGateway" eSuperTypes="#//infrastructure/NetworkInterface">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="address" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Storage" eSuperTypes="#//infrastructure/InfrastructureElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="label" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="size_gb" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="ifaces" upperBound="-1"
+          eType="#//infrastructure/NetworkInterface" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="FunctionAsAService" eSuperTypes="#//infrastructure/InfrastructureElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="ifaces" upperBound="-1"
+          eType="#//infrastructure/NetworkInterface" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EEnum" name="RoleKind">
+      <eLiterals name="NONE"/>
+      <eLiterals name="MANAGER" value="1"/>
+      <eLiterals name="WORKER" value="2"/>
+      <eLiterals name="MASTER" value="3"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="SwarmRole" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" eType="#//infrastructure/RoleKind"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="nodes" upperBound="-1"
+          eType="#//infrastructure/ComputingNode" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Swarm" eSuperTypes="#//infrastructure/ComputingGroup">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="roles" upperBound="-1"
+          eType="#//infrastructure/SwarmRole" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ExtInfrastructureElement" eSuperTypes="#//infrastructure/InfrastructureElement #//commons/ExtensionElement"/>
+  </eSubpackages>
+  <eSubpackages name="concrete" nsURI="http://www.piacere-project.eu/doml/concrete"
+      nsPrefix="concrete">
+    <eClassifiers xsi:type="ecore:EClass" name="ConcreteInfrastructure" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="providers" upperBound="-1"
+          eType="#//concrete/RuntimeProvider" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="RuntimeProvider" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="resources" upperBound="-1"
+          eType="#//concrete/GenericResource" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="vms" upperBound="-1"
+          eType="#//concrete/VirtualMachine" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="vmImages" upperBound="-1"
+          eType="#//concrete/VMImage" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="containerImages" upperBound="-1"
+          eType="#//concrete/ContainerImage" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="networks" upperBound="-1"
+          eType="#//concrete/Network" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="storages" upperBound="-1"
+          eType="#//concrete/Storage" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="faas" upperBound="-1"
+          eType="#//concrete/FunctionAsAService" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="group" upperBound="-1"
+          eType="#//concrete/ComputingGroup" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ConcreteElement" abstract="true" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="configurationScript"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="preexisting" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBooleanObject"
+          defaultValueLiteral="false"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="refs" upperBound="-1"
+          eType="#//concrete/ConcreteElement"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="GenericResource" eSuperTypes="#//concrete/ConcreteElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="type" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="gname" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="VirtualMachine" eSuperTypes="#//concrete/ConcreteElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/VirtualMachine"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="VMImage" eSuperTypes="#//concrete/ConcreteElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/VMImage"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ContainerImage" eSuperTypes="#//concrete/ConcreteElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/ContainerImage"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Network" eSuperTypes="#//concrete/ConcreteElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/Network"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Storage" eSuperTypes="#//concrete/ConcreteElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/Storage"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="FunctionAsAService" eSuperTypes="#//concrete/ConcreteElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/FunctionAsAService"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ComputingGroup" eSuperTypes="#//concrete/ConcreteElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/ComputingGroup"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ExtConcreteElement" eSuperTypes="#//concrete/ConcreteElement #//commons/ExtensionElement"/>
+  </eSubpackages>
+  <eSubpackages name="optimization" nsURI="http://www.piacere-project.eu/doml/optimization"
+      nsPrefix="optimization">
+    <eClassifiers xsi:type="ecore:EClass" name="OptimizationLayer" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="startingHint" eType="#//commons/Configuration"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="solutions" upperBound="-1"
+          eType="#//optimization/OptimizationSolution" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="objectives" upperBound="-1"
+          eType="#//optimization/OptimizationObjective" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="nonfunctionalRequirements"
+          upperBound="-1" eType="#//commons/Requirement" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ObjectiveValue">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="availability" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="performance" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="OptimizationSolution" eSuperTypes="#//commons/Configuration">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="objectives" eType="#//optimization/ObjectiveValue"
+          containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="decisions" upperBound="-1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="OptimizationObjective" abstract="true"
+        eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" lowerBound="1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+          defaultValueLiteral="Max"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="property" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="CountObjective" eSuperTypes="#//optimization/OptimizationObjective"/>
+    <eClassifiers xsi:type="ecore:EClass" name="MeasurableObjective" eSuperTypes="#//optimization/OptimizationObjective"/>
+    <eClassifiers xsi:type="ecore:EClass" name="ExtOptimizationObjective" eSuperTypes="#//optimization/OptimizationObjective #//commons/ExtensionElement"/>
+  </eSubpackages>
+</ecore:EPackage>
diff --git a/mc_openapi/assets/metamodels/doml_v2.2.ecore b/mc_openapi/assets/metamodels/doml_v2.2.ecore
new file mode 100644
index 0000000000000000000000000000000000000000..a294cdef5b4ac189c94d5e7088cfb79db4aaf7ae
--- /dev/null
+++ b/mc_openapi/assets/metamodels/doml_v2.2.ecore
@@ -0,0 +1,415 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="doml" nsURI="http://www.piacere-project.eu/doml" nsPrefix="doml">
+  <eAnnotations source="emf.gen">
+    <details key="basePackage" value="eu.piacere.doml"/>
+    <details key="fileExtensions" value="domlx"/>
+    <details key="complianceLevel" value="JDK80"/>
+  </eAnnotations>
+  <eSubpackages name="commons" nsURI="http://www.piacere-project.eu/doml/commons"
+      nsPrefix="commons">
+    <eClassifiers xsi:type="ecore:EClass" name="DOMLModel" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="version" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+          defaultValueLiteral="2.2"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="application" eType="#//application/ApplicationLayer"
+          containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="infrastructure" eType="#//infrastructure/InfrastructureLayer"
+          containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="concretizations" upperBound="-1"
+          eType="#//concrete/ConcreteInfrastructure" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="optimization" eType="#//optimization/OptimizationLayer"
+          containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="configurations" upperBound="-1"
+          eType="#//commons/Configuration" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="activeConfiguration"
+          eType="#//commons/Configuration"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="activeInfrastructure"
+          eType="#//concrete/ConcreteInfrastructure"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="functionalRequirements"
+          upperBound="-1" eType="#//commons/Requirement" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Property" abstract="true">
+      <eOperations name="getValue" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EJavaObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="key" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="reference" eType="#//commons/DOMLElement"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="IProperty" eSuperTypes="#//commons/Property">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="SProperty" eSuperTypes="#//commons/Property">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="FProperty" eSuperTypes="#//commons/Property">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="BProperty" eSuperTypes="#//commons/Property">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBooleanObject"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ExtensionElement" abstract="true">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="metaclassName" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="DOMLElement" abstract="true">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="description" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="annotations" upperBound="-1"
+          eType="#//commons/Property" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="contributesTo" upperBound="-1"
+          eType="#//commons/Requirement" eOpposite="#//commons/Requirement/predicatesOn"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Configuration" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="deployments" upperBound="-1"
+          eType="#//commons/Deployment" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="DeployableElement" abstract="true"/>
+    <eClassifiers xsi:type="ecore:EClass" name="Deployment">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="component" lowerBound="1"
+          eType="#//commons/DeployableElement"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="node" lowerBound="1"
+          eType="#//infrastructure/InfrastructureElement"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Requirement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="description" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="property" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="predicatesOn" upperBound="-1"
+          eType="#//commons/DOMLElement" eOpposite="#//commons/DOMLElement/contributesTo"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="RangedRequirement" eSuperTypes="#//commons/Requirement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="min" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="max" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="EnumeratedRequirement" eSuperTypes="#//commons/Requirement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="values" upperBound="-1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="DeploymentRequirement" abstract="true"
+        eSuperTypes="#//commons/Requirement"/>
+    <eClassifiers xsi:type="ecore:EClass" name="DeploymentToNodeTypeRequirement" eSuperTypes="#//commons/DeploymentRequirement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="validTypes" upperBound="-1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="DeploymentToNodeWithPropertyRequirement"
+        eSuperTypes="#//commons/DeploymentRequirement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="min" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="max" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="values" upperBound="-1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="DeploymentToSpecificNodeRequirement"
+        eSuperTypes="#//commons/DeploymentRequirement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="validElements" upperBound="-1"
+          eType="#//infrastructure/InfrastructureElement"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Credentials" abstract="true" eSuperTypes="#//commons/DOMLElement"/>
+    <eClassifiers xsi:type="ecore:EClass" name="KeyPair" eSuperTypes="#//commons/Credentials">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="user" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="keyfile" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="algorithm" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="bits" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="UserPass" eSuperTypes="#//commons/Credentials">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="username" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="password" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Source" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="entry" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="backend" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+  </eSubpackages>
+  <eSubpackages name="application" nsURI="http://www.piacere-project.eu/doml/application"
+      nsPrefix="app">
+    <eClassifiers xsi:type="ecore:EClass" name="ApplicationLayer" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="components" upperBound="-1"
+          eType="#//application/ApplicationComponent" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ApplicationComponent" abstract="true"
+        eSuperTypes="#//commons/DOMLElement #//commons/DeployableElement"/>
+    <eClassifiers xsi:type="ecore:EClass" name="SoftwareComponent" eSuperTypes="#//application/ApplicationComponent">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="isPersistent" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBooleanObject"
+          defaultValueLiteral="false"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="licenseCost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="exposedInterfaces" upperBound="-1"
+          eType="#//application/SoftwareInterface" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="consumedInterfaces" upperBound="-1"
+          eType="#//application/SoftwareInterface"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="src" eType="#//commons/Source"
+          containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="DBMS" eSuperTypes="#//application/SoftwareComponent"/>
+    <eClassifiers xsi:type="ecore:EClass" name="SaaS" eSuperTypes="#//application/ApplicationComponent">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="licenseCost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="exposedInterfaces" upperBound="-1"
+          eType="#//application/SoftwareInterface" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="SaaSDBMS" eSuperTypes="#//application/SaaS"/>
+    <eClassifiers xsi:type="ecore:EClass" name="SoftwareInterface" eSuperTypes="#//application/ApplicationComponent">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="endPoint" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ExtApplicationComponent" eSuperTypes="#//application/ApplicationComponent #//commons/ExtensionElement"/>
+  </eSubpackages>
+  <eSubpackages name="infrastructure" nsURI="http://www.piacere-project.eu/doml/infrastructure"
+      nsPrefix="infra">
+    <eClassifiers xsi:type="ecore:EClass" name="InfrastructureLayer" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="nodes" upperBound="-1"
+          eType="#//infrastructure/ComputingNode" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="generators" upperBound="-1"
+          eType="#//infrastructure/ComputingNodeGenerator" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="storages" upperBound="-1"
+          eType="#//infrastructure/Storage" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="faas" upperBound="-1"
+          eType="#//infrastructure/FunctionAsAService" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="credentials" upperBound="-1"
+          eType="#//commons/Credentials" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="groups" upperBound="-1"
+          eType="#//infrastructure/ComputingGroup" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="securityGroups" upperBound="-1"
+          eType="#//infrastructure/SecurityGroup" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="networks" upperBound="-1"
+          eType="#//infrastructure/Network" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="rules" upperBound="-1"
+          eType="#//infrastructure/MonitoringRule" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="MonitoringRule" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="condition" lowerBound="1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="strategy" lowerBound="1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="strategyConfigurationString"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ComputingGroup" abstract="true" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="groupedNodes" upperBound="-1"
+          eType="#//infrastructure/ComputingNode" eOpposite="#//infrastructure/ComputingNode/group"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="AutoScalingGroup" eSuperTypes="#//infrastructure/ComputingGroup">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="machineDefinition" lowerBound="1"
+          eType="#//infrastructure/VirtualMachine" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="min" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"
+          defaultValueLiteral="1"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="max" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"
+          defaultValueLiteral="1"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="securityGroup" eType="#//infrastructure/SecurityGroup"
+          containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="loadBalancer" eType="#//infrastructure/LoadBalancerKind"
+          defaultValueLiteral="DEFAULT"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EEnum" name="LoadBalancerKind">
+      <eLiterals name="DEFAULT"/>
+      <eLiterals name="INTERNAL" value="1"/>
+      <eLiterals name="EXTERNAL" value="2"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Rule" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" eType="#//infrastructure/RuleKind"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="protocol" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="fromPort" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="toPort" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="cidr" upperBound="-1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EEnum" name="RuleKind">
+      <eLiterals name="EGRESS"/>
+      <eLiterals name="INGRESS" value="1"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="SecurityGroup" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="rules" upperBound="-1"
+          eType="#//infrastructure/Rule" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="ifaces" upperBound="-1"
+          eType="#//infrastructure/NetworkInterface" eOpposite="#//infrastructure/NetworkInterface/associated"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="AvailabilityGroup" eSuperTypes="#//infrastructure/ComputingGroup"/>
+    <eClassifiers xsi:type="ecore:EClass" name="InfrastructureElement" abstract="true"
+        eSuperTypes="#//commons/DOMLElement #//commons/DeployableElement"/>
+    <eClassifiers xsi:type="ecore:EClass" name="ComputingNode" abstract="true" eSuperTypes="#//infrastructure/InfrastructureElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="architecture" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="os" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="memory_mb" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="storage" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="cpu_count" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="ifaces" upperBound="-1"
+          eType="#//infrastructure/NetworkInterface" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="location" eType="#//infrastructure/Location"
+          containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="credentials" eType="#//commons/Credentials"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="group" eType="#//infrastructure/ComputingGroup"
+          eOpposite="#//infrastructure/ComputingGroup/groupedNodes"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="disabledMonitorings"
+          upperBound="-1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ComputingNodeGenerator" abstract="true"
+        eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="uri" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" eType="#//infrastructure/GeneratorKind"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EEnum" name="GeneratorKind">
+      <eLiterals name="SCRIPT"/>
+      <eLiterals name="IMAGE" value="1"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="VMImage" eSuperTypes="#//infrastructure/ComputingNodeGenerator">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="generatedVMs" upperBound="-1"
+          eType="#//infrastructure/VirtualMachine" eOpposite="#//infrastructure/VirtualMachine/generatedFrom"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ContainerImage" eSuperTypes="#//infrastructure/ComputingNodeGenerator">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="generatedContainers"
+          upperBound="-1" eType="#//infrastructure/Container" eOpposite="#//infrastructure/Container/generatedFrom"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="PhysicalComputingNode" eSuperTypes="#//infrastructure/ComputingNode"/>
+    <eClassifiers xsi:type="ecore:EClass" name="VirtualMachine" eSuperTypes="#//infrastructure/ComputingNode">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="sizeDescription" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="generatedFrom" eType="#//infrastructure/VMImage"
+          eOpposite="#//infrastructure/VMImage/generatedVMs"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Location" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="region" lowerBound="1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="zone" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ContainerConfig" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="container_port" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="vm_port" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="host" eType="#//infrastructure/ComputingNode"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="iface" eType="#//infrastructure/NetworkInterface"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Container" eSuperTypes="#//infrastructure/ComputingNode">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="generatedFrom" eType="#//infrastructure/ContainerImage"
+          eOpposite="#//infrastructure/ContainerImage/generatedContainers"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="configs" upperBound="-1"
+          eType="#//infrastructure/ContainerConfig" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Network" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="protocol" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="addressRange" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="connectedIfaces" upperBound="-1"
+          eType="#//infrastructure/NetworkInterface" eOpposite="#//infrastructure/NetworkInterface/belongsTo"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="igws" upperBound="-1"
+          eType="#//infrastructure/InternetGateway" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="subnets" upperBound="-1"
+          eType="#//infrastructure/Subnet" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Subnet" eSuperTypes="#//infrastructure/Network">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="connectedTo" upperBound="-1"
+          eType="#//infrastructure/Subnet"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="NetworkInterface" eSuperTypes="#//infrastructure/InfrastructureElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="speed" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="endPoint" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="belongsTo" eType="#//infrastructure/Network"
+          eOpposite="#//infrastructure/Network/connectedIfaces"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="associated" eType="#//infrastructure/SecurityGroup"
+          eOpposite="#//infrastructure/SecurityGroup/ifaces"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="InternetGateway" eSuperTypes="#//infrastructure/NetworkInterface"/>
+    <eClassifiers xsi:type="ecore:EClass" name="Storage" eSuperTypes="#//infrastructure/InfrastructureElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="label" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="size_gb" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="ifaces" upperBound="-1"
+          eType="#//infrastructure/NetworkInterface" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="FunctionAsAService" eSuperTypes="#//infrastructure/InfrastructureElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="ifaces" upperBound="-1"
+          eType="#//infrastructure/NetworkInterface" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EEnum" name="RoleKind">
+      <eLiterals name="NONE"/>
+      <eLiterals name="MANAGER" value="1"/>
+      <eLiterals name="WORKER" value="2"/>
+      <eLiterals name="MASTER" value="3"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="SwarmRole" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" eType="#//infrastructure/RoleKind"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="nodes" upperBound="-1"
+          eType="#//infrastructure/ComputingNode" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Swarm" eSuperTypes="#//infrastructure/ComputingGroup">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="roles" upperBound="-1"
+          eType="#//infrastructure/SwarmRole" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ExtInfrastructureElement" eSuperTypes="#//infrastructure/InfrastructureElement #//commons/ExtensionElement"/>
+  </eSubpackages>
+  <eSubpackages name="concrete" nsURI="http://www.piacere-project.eu/doml/concrete"
+      nsPrefix="concrete">
+    <eClassifiers xsi:type="ecore:EClass" name="ConcreteInfrastructure" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="providers" upperBound="-1"
+          eType="#//concrete/RuntimeProvider" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="RuntimeProvider" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="vms" upperBound="-1"
+          eType="#//concrete/VirtualMachine" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="vmImages" upperBound="-1"
+          eType="#//concrete/VMImage" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="containerImages" upperBound="-1"
+          eType="#//concrete/ContainerImage" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="networks" upperBound="-1"
+          eType="#//concrete/Network" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="storages" upperBound="-1"
+          eType="#//concrete/Storage" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="faas" upperBound="-1"
+          eType="#//concrete/FunctionAsAService" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="group" upperBound="-1"
+          eType="#//concrete/ComputingGroup" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ConcreteElement" abstract="true" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="configurationScript"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="preexisting" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBooleanObject"
+          defaultValueLiteral="false"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="VirtualMachine" eSuperTypes="#//concrete/ConcreteElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/VirtualMachine"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="VMImage" eSuperTypes="#//concrete/ConcreteElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/VMImage"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ContainerImage" eSuperTypes="#//concrete/ConcreteElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/ContainerImage"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Network" eSuperTypes="#//concrete/ConcreteElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/Network"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Storage" eSuperTypes="#//concrete/ConcreteElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/Storage"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="FunctionAsAService" eSuperTypes="#//concrete/ConcreteElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/FunctionAsAService"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ComputingGroup" eSuperTypes="#//concrete/ConcreteElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/ComputingGroup"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ExtConcreteElement" eSuperTypes="#//concrete/ConcreteElement #//commons/ExtensionElement"/>
+  </eSubpackages>
+  <eSubpackages name="optimization" nsURI="http://www.piacere-project.eu/doml/optimization"
+      nsPrefix="optimization">
+    <eClassifiers xsi:type="ecore:EClass" name="OptimizationLayer" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="startingHint" eType="#//commons/Configuration"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="solutions" upperBound="-1"
+          eType="#//optimization/OptimizationSolution" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="objectives" upperBound="-1"
+          eType="#//optimization/OptimizationObjective" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="nonfunctionalRequirements"
+          upperBound="-1" eType="#//commons/Requirement" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ObjectiveValue">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="availability" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="performance" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="OptimizationSolution" eSuperTypes="#//commons/Configuration">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="objectives" eType="#//optimization/ObjectiveValue"
+          containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="decisions" upperBound="-1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="OptimizationObjective" abstract="true"
+        eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" lowerBound="1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+          defaultValueLiteral="Max"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="property" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="CountObjective" eSuperTypes="#//optimization/OptimizationObjective"/>
+    <eClassifiers xsi:type="ecore:EClass" name="MeasurableObjective" eSuperTypes="#//optimization/OptimizationObjective"/>
+    <eClassifiers xsi:type="ecore:EClass" name="ExtOptimizationObjective" eSuperTypes="#//optimization/OptimizationObjective #//commons/ExtensionElement"/>
+  </eSubpackages>
+</ecore:EPackage>
diff --git a/mc_openapi/assets/metamodels/doml_v2.3.ecore b/mc_openapi/assets/metamodels/doml_v2.3.ecore
new file mode 100644
index 0000000000000000000000000000000000000000..30a5244fea7c765953d14e30108c5163936f1758
--- /dev/null
+++ b/mc_openapi/assets/metamodels/doml_v2.3.ecore
@@ -0,0 +1,422 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="doml" nsURI="http://www.piacere-project.eu/doml" nsPrefix="doml">
+  <eAnnotations source="emf.gen">
+    <details key="basePackage" value="eu.piacere.doml"/>
+    <details key="fileExtensions" value="domlx"/>
+    <details key="complianceLevel" value="JDK80"/>
+  </eAnnotations>
+  <eSubpackages name="commons" nsURI="http://www.piacere-project.eu/doml/commons"
+      nsPrefix="commons">
+    <eClassifiers xsi:type="ecore:EClass" name="DOMLModel" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="version" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+          defaultValueLiteral="2.2"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="application" eType="#//application/ApplicationLayer"
+          containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="infrastructure" eType="#//infrastructure/InfrastructureLayer"
+          containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="concretizations" upperBound="-1"
+          eType="#//concrete/ConcreteInfrastructure" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="optimization" eType="#//optimization/OptimizationLayer"
+          containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="configurations" upperBound="-1"
+          eType="#//commons/Configuration" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="activeConfiguration"
+          eType="#//commons/Configuration"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="activeInfrastructure"
+          eType="#//concrete/ConcreteInfrastructure"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="functionalRequirements"
+          upperBound="-1" eType="#//commons/Requirement" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Property" abstract="true">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="key" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="IProperty" eSuperTypes="#//commons/Property">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="SProperty" eSuperTypes="#//commons/Property">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="FProperty" eSuperTypes="#//commons/Property">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="BProperty" eSuperTypes="#//commons/Property">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBooleanObject"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ExtensionElement" abstract="true">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="metaclassName" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="DOMLElement" abstract="true">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="description" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="annotations" upperBound="-1"
+          eType="#//commons/Property" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="contributesTo" upperBound="-1"
+          eType="#//commons/Requirement" eOpposite="#//commons/Requirement/predicatesOn"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Configuration" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="deployments" upperBound="-1"
+          eType="#//commons/Deployment" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="DeployableElement" abstract="true"/>
+    <eClassifiers xsi:type="ecore:EClass" name="Deployment">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="component" lowerBound="1"
+          eType="#//commons/DeployableElement"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="node" lowerBound="1"
+          eType="#//infrastructure/InfrastructureElement"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Requirement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="description" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="property" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="predicatesOn" upperBound="-1"
+          eType="#//commons/DOMLElement" eOpposite="#//commons/DOMLElement/contributesTo"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="RangedRequirement" eSuperTypes="#//commons/Requirement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="min" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="max" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="EnumeratedRequirement" eSuperTypes="#//commons/Requirement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="values" upperBound="-1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="DeploymentRequirement" abstract="true"
+        eSuperTypes="#//commons/Requirement"/>
+    <eClassifiers xsi:type="ecore:EClass" name="DeploymentToNodeTypeRequirement" eSuperTypes="#//commons/DeploymentRequirement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="validTypes" upperBound="-1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="DeploymentToNodeWithPropertyRequirement"
+        eSuperTypes="#//commons/DeploymentRequirement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="min" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="max" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="values" upperBound="-1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="DeploymentToSpecificNodeRequirement"
+        eSuperTypes="#//commons/DeploymentRequirement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="validElements" upperBound="-1"
+          eType="#//infrastructure/InfrastructureElement"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Credentials" abstract="true" eSuperTypes="#//commons/DOMLElement"/>
+    <eClassifiers xsi:type="ecore:EClass" name="KeyPair" eSuperTypes="#//commons/Credentials">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="user" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="keyfile" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="algorithm" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="bits" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="UserPass" eSuperTypes="#//commons/Credentials">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="username" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="password" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Source" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="entry" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="backend" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+  </eSubpackages>
+  <eSubpackages name="application" nsURI="http://www.piacere-project.eu/doml/application"
+      nsPrefix="app">
+    <eClassifiers xsi:type="ecore:EClass" name="ApplicationLayer" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="components" upperBound="-1"
+          eType="#//application/ApplicationComponent" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ApplicationComponent" abstract="true"
+        eSuperTypes="#//commons/DOMLElement #//commons/DeployableElement"/>
+    <eClassifiers xsi:type="ecore:EClass" name="SoftwareComponent" eSuperTypes="#//application/ApplicationComponent">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="isPersistent" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBooleanObject"
+          defaultValueLiteral="false"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="licenseCost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="exposedInterfaces" upperBound="-1"
+          eType="#//application/SoftwareInterface" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="consumedInterfaces" upperBound="-1"
+          eType="#//application/SoftwareInterface"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="src" eType="#//commons/Source"
+          containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="DBMS" eSuperTypes="#//application/SoftwareComponent"/>
+    <eClassifiers xsi:type="ecore:EClass" name="SaaS" eSuperTypes="#//application/ApplicationComponent">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="licenseCost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="exposedInterfaces" upperBound="-1"
+          eType="#//application/SoftwareInterface" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="SaaSDBMS" eSuperTypes="#//application/SaaS"/>
+    <eClassifiers xsi:type="ecore:EClass" name="SoftwareInterface" eSuperTypes="#//application/ApplicationComponent">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="endPoint" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ExtApplicationComponent" eSuperTypes="#//application/ApplicationComponent #//commons/ExtensionElement"/>
+  </eSubpackages>
+  <eSubpackages name="infrastructure" nsURI="http://www.piacere-project.eu/doml/infrastructure"
+      nsPrefix="infra">
+    <eClassifiers xsi:type="ecore:EClass" name="InfrastructureLayer" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="nodes" upperBound="-1"
+          eType="#//infrastructure/ComputingNode" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="generators" upperBound="-1"
+          eType="#//infrastructure/ComputingNodeGenerator" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="storages" upperBound="-1"
+          eType="#//infrastructure/Storage" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="faas" upperBound="-1"
+          eType="#//infrastructure/FunctionAsAService" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="credentials" upperBound="-1"
+          eType="#//commons/Credentials" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="groups" upperBound="-1"
+          eType="#//infrastructure/ComputingGroup" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="securityGroups" upperBound="-1"
+          eType="#//infrastructure/SecurityGroup" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="networks" upperBound="-1"
+          eType="#//infrastructure/Network" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="rules" upperBound="-1"
+          eType="#//infrastructure/MonitoringRule" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="MonitoringRule" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="condition" lowerBound="1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="strategy" lowerBound="1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="strategyConfigurationString"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ComputingGroup" abstract="true" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="groupedNodes" upperBound="-1"
+          eType="#//infrastructure/ComputingNode" eOpposite="#//infrastructure/ComputingNode/group"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="AutoScalingGroup" eSuperTypes="#//infrastructure/ComputingGroup">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="machineDefinition" lowerBound="1"
+          eType="#//infrastructure/VirtualMachine" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="min" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"
+          defaultValueLiteral="1"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="max" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"
+          defaultValueLiteral="1"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="securityGroup" eType="#//infrastructure/SecurityGroup"
+          containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="loadBalancer" eType="#//infrastructure/LoadBalancerKind"
+          defaultValueLiteral="DEFAULT"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EEnum" name="LoadBalancerKind">
+      <eLiterals name="DEFAULT"/>
+      <eLiterals name="INTERNAL" value="1"/>
+      <eLiterals name="EXTERNAL" value="2"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Rule" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" eType="#//infrastructure/RuleKind"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="protocol" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="fromPort" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="toPort" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="cidr" upperBound="-1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EEnum" name="RuleKind">
+      <eLiterals name="EGRESS"/>
+      <eLiterals name="INGRESS" value="1"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="SecurityGroup" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="rules" upperBound="-1"
+          eType="#//infrastructure/Rule" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="ifaces" upperBound="-1"
+          eType="#//infrastructure/NetworkInterface" eOpposite="#//infrastructure/NetworkInterface/associated"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="AvailabilityGroup" eSuperTypes="#//infrastructure/ComputingGroup"/>
+    <eClassifiers xsi:type="ecore:EClass" name="InfrastructureElement" abstract="true"
+        eSuperTypes="#//commons/DOMLElement #//commons/DeployableElement"/>
+    <eClassifiers xsi:type="ecore:EClass" name="Node" abstract="true" eSuperTypes="#//infrastructure/InfrastructureElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="ifaces" upperBound="-1"
+          eType="#//infrastructure/NetworkInterface" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ComputingNode" abstract="true" eSuperTypes="#//infrastructure/Node">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="architecture" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="os" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="memory_mb" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="storage" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="cpu_count" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="location" eType="#//infrastructure/Location"
+          containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="credentials" eType="#//commons/Credentials"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="group" eType="#//infrastructure/ComputingGroup"
+          eOpposite="#//infrastructure/ComputingGroup/groupedNodes"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="disabledMonitorings"
+          upperBound="-1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ComputingNodeGenerator" abstract="true"
+        eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="uri" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" eType="#//infrastructure/GeneratorKind"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EEnum" name="GeneratorKind">
+      <eLiterals name="SCRIPT"/>
+      <eLiterals name="IMAGE" value="1"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="VMImage" eSuperTypes="#//infrastructure/ComputingNodeGenerator">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="generatedVMs" upperBound="-1"
+          eType="#//infrastructure/VirtualMachine" eOpposite="#//infrastructure/VirtualMachine/generatedFrom"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ContainerImage" eSuperTypes="#//infrastructure/ComputingNodeGenerator">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="generatedContainers"
+          upperBound="-1" eType="#//infrastructure/Container" eOpposite="#//infrastructure/Container/generatedFrom"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="PhysicalComputingNode" eSuperTypes="#//infrastructure/ComputingNode"/>
+    <eClassifiers xsi:type="ecore:EClass" name="VirtualMachine" eSuperTypes="#//infrastructure/ComputingNode">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="sizeDescription" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="generatedFrom" eType="#//infrastructure/VMImage"
+          eOpposite="#//infrastructure/VMImage/generatedVMs"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Location" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="region" lowerBound="1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="zone" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ContainerConfig" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="container_port" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="vm_port" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="host" eType="#//infrastructure/ComputingNode"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="iface" eType="#//infrastructure/NetworkInterface"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Container" eSuperTypes="#//infrastructure/ComputingNode">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="generatedFrom" eType="#//infrastructure/ContainerImage"
+          eOpposite="#//infrastructure/ContainerImage/generatedContainers"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="configs" upperBound="-1"
+          eType="#//infrastructure/ContainerConfig" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Network" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="protocol" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="addressRange" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="connectedIfaces" upperBound="-1"
+          eType="#//infrastructure/NetworkInterface" eOpposite="#//infrastructure/NetworkInterface/belongsTo"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="gateways" upperBound="-1"
+          eType="#//infrastructure/InternetGateway" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="subnets" upperBound="-1"
+          eType="#//infrastructure/Subnet" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Subnet" eSuperTypes="#//infrastructure/Network">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="connectedTo" upperBound="-1"
+          eType="#//infrastructure/Subnet"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="NetworkInterface" eSuperTypes="#//infrastructure/InfrastructureElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="speed" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="endPoint" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="belongsTo" eType="#//infrastructure/Network"
+          eOpposite="#//infrastructure/Network/connectedIfaces"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="associated" upperBound="-1"
+          eType="#//infrastructure/SecurityGroup" eOpposite="#//infrastructure/SecurityGroup/ifaces"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="InternetGateway" eSuperTypes="#//infrastructure/Node">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="address" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Storage" eSuperTypes="#//infrastructure/InfrastructureElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="label" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="size_gb" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="FunctionAsAService" eSuperTypes="#//infrastructure/InfrastructureElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EEnum" name="RoleKind">
+      <eLiterals name="NONE"/>
+      <eLiterals name="MANAGER" value="1"/>
+      <eLiterals name="WORKER" value="2"/>
+      <eLiterals name="MASTER" value="3"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="SwarmRole" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" eType="#//infrastructure/RoleKind"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="nodes" upperBound="-1"
+          eType="#//infrastructure/ComputingNode" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Swarm" eSuperTypes="#//infrastructure/ComputingGroup">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="roles" upperBound="-1"
+          eType="#//infrastructure/SwarmRole" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ExtInfrastructureElement" eSuperTypes="#//infrastructure/InfrastructureElement #//commons/ExtensionElement"/>
+  </eSubpackages>
+  <eSubpackages name="concrete" nsURI="http://www.piacere-project.eu/doml/concrete"
+      nsPrefix="concrete">
+    <eClassifiers xsi:type="ecore:EClass" name="ConcreteInfrastructure" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="providers" upperBound="-1"
+          eType="#//concrete/RuntimeProvider" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="RuntimeProvider" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="resources" upperBound="-1"
+          eType="#//concrete/GenericResource" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="vms" upperBound="-1"
+          eType="#//concrete/VirtualMachine" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="vmImages" upperBound="-1"
+          eType="#//concrete/VMImage" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="containerImages" upperBound="-1"
+          eType="#//concrete/ContainerImage" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="networks" upperBound="-1"
+          eType="#//concrete/Network" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="storages" upperBound="-1"
+          eType="#//concrete/Storage" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="faas" upperBound="-1"
+          eType="#//concrete/FunctionAsAService" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="group" upperBound="-1"
+          eType="#//concrete/ComputingGroup" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ConcreteElement" abstract="true" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="configurationScript"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="preexisting" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBooleanObject"
+          defaultValueLiteral="false"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="refs" upperBound="-1"
+          eType="#//concrete/ConcreteElement"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="GenericResource" eSuperTypes="#//concrete/ConcreteElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="type" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="gname" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="VirtualMachine" eSuperTypes="#//concrete/ConcreteElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/VirtualMachine"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="VMImage" eSuperTypes="#//concrete/ConcreteElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="image_name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/VMImage"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ContainerImage" eSuperTypes="#//concrete/ConcreteElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/ContainerImage"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Network" eSuperTypes="#//concrete/ConcreteElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/Network"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Storage" eSuperTypes="#//concrete/ConcreteElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/Storage"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="FunctionAsAService" eSuperTypes="#//concrete/ConcreteElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/FunctionAsAService"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ComputingGroup" eSuperTypes="#//concrete/ConcreteElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/ComputingGroup"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ExtConcreteElement" eSuperTypes="#//concrete/ConcreteElement #//commons/ExtensionElement"/>
+  </eSubpackages>
+  <eSubpackages name="optimization" nsURI="http://www.piacere-project.eu/doml/optimization"
+      nsPrefix="optimization">
+    <eClassifiers xsi:type="ecore:EClass" name="OptimizationLayer" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="startingHint" eType="#//commons/Configuration"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="solutions" upperBound="-1"
+          eType="#//optimization/OptimizationSolution" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="objectives" upperBound="-1"
+          eType="#//optimization/OptimizationObjective" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="nonfunctionalRequirements"
+          upperBound="-1" eType="#//commons/Requirement" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ObjectiveValue">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="availability" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="performance" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="OptimizationSolution" eSuperTypes="#//commons/Configuration">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="objectives" eType="#//optimization/ObjectiveValue"
+          containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="decisions" upperBound="-1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="OptimizationObjective" abstract="true"
+        eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" lowerBound="1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+          defaultValueLiteral="Max"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="property" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="CountObjective" eSuperTypes="#//optimization/OptimizationObjective"/>
+    <eClassifiers xsi:type="ecore:EClass" name="MeasurableObjective" eSuperTypes="#//optimization/OptimizationObjective"/>
+    <eClassifiers xsi:type="ecore:EClass" name="ExtOptimizationObjective" eSuperTypes="#//optimization/OptimizationObjective #//commons/ExtensionElement"/>
+  </eSubpackages>
+</ecore:EPackage>
diff --git a/mc_openapi/assets/metamodels/doml_v3.0.ecore b/mc_openapi/assets/metamodels/doml_v3.0.ecore
new file mode 100644
index 0000000000000000000000000000000000000000..3d4e249441ae848ac55cd694236ae2b4916329de
--- /dev/null
+++ b/mc_openapi/assets/metamodels/doml_v3.0.ecore
@@ -0,0 +1,424 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="doml" nsURI="http://www.piacere-project.eu/doml" nsPrefix="doml">
+  <eAnnotations source="emf.gen">
+    <details key="basePackage" value="eu.piacere.doml"/>
+    <details key="fileExtensions" value="domlx"/>
+    <details key="complianceLevel" value="JDK80"/>
+  </eAnnotations>
+  <eSubpackages name="commons" nsURI="http://www.piacere-project.eu/doml/commons"
+      nsPrefix="commons">
+    <eClassifiers xsi:type="ecore:EClass" name="DOMLModel" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="version" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+          defaultValueLiteral="3.0"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="application" eType="#//application/ApplicationLayer"
+          containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="infrastructure" eType="#//infrastructure/InfrastructureLayer"
+          containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="concretizations" upperBound="-1"
+          eType="#//concrete/ConcreteInfrastructure" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="optimization" eType="#//optimization/OptimizationLayer"
+          containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="configurations" upperBound="-1"
+          eType="#//commons/Configuration" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="activeConfiguration"
+          eType="#//commons/Configuration"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="activeInfrastructure"
+          eType="#//concrete/ConcreteInfrastructure"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="functionalRequirements"
+          upperBound="-1" eType="#//commons/Requirement" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Property" abstract="true">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="key" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="IProperty" eSuperTypes="#//commons/Property">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="SProperty" eSuperTypes="#//commons/Property">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="FProperty" eSuperTypes="#//commons/Property">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="BProperty" eSuperTypes="#//commons/Property">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBooleanObject"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ExtensionElement" abstract="true">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="metaclassName" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="DOMLElement" abstract="true">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="description" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="annotations" upperBound="-1"
+          eType="#//commons/Property" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="contributesTo" upperBound="-1"
+          eType="#//commons/Requirement" eOpposite="#//commons/Requirement/predicatesOn"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Configuration" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="deployments" upperBound="-1"
+          eType="#//commons/Deployment" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="DeployableElement" abstract="true"/>
+    <eClassifiers xsi:type="ecore:EClass" name="Deployment">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="component" lowerBound="1"
+          eType="#//commons/DeployableElement"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="node" lowerBound="1"
+          eType="#//infrastructure/InfrastructureElement"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Requirement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="description" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="property" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="predicatesOn" upperBound="-1"
+          eType="#//commons/DOMLElement" eOpposite="#//commons/DOMLElement/contributesTo"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="RangedRequirement" eSuperTypes="#//commons/Requirement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="min" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="max" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="EnumeratedRequirement" eSuperTypes="#//commons/Requirement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="values" upperBound="-1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="DeploymentRequirement" abstract="true"
+        eSuperTypes="#//commons/Requirement"/>
+    <eClassifiers xsi:type="ecore:EClass" name="DeploymentToNodeTypeRequirement" eSuperTypes="#//commons/DeploymentRequirement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="validTypes" upperBound="-1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="DeploymentToNodeWithPropertyRequirement"
+        eSuperTypes="#//commons/DeploymentRequirement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="min" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="max" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="values" upperBound="-1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="DeploymentToSpecificNodeRequirement"
+        eSuperTypes="#//commons/DeploymentRequirement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="validElements" upperBound="-1"
+          eType="#//infrastructure/InfrastructureElement"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Credentials" abstract="true" eSuperTypes="#//commons/DOMLElement"/>
+    <eClassifiers xsi:type="ecore:EClass" name="KeyPair" eSuperTypes="#//commons/Credentials">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="user" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="keyfile" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="algorithm" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="bits" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="UserPass" eSuperTypes="#//commons/Credentials">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="username" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="password" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Source" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="entry" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="backend" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+  </eSubpackages>
+  <eSubpackages name="application" nsURI="http://www.piacere-project.eu/doml/application"
+      nsPrefix="app">
+    <eClassifiers xsi:type="ecore:EClass" name="ApplicationLayer" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="components" upperBound="-1"
+          eType="#//application/ApplicationComponent" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ApplicationComponent" abstract="true"
+        eSuperTypes="#//commons/DOMLElement #//commons/DeployableElement"/>
+    <eClassifiers xsi:type="ecore:EClass" name="SoftwareComponent" eSuperTypes="#//application/ApplicationComponent">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="isPersistent" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBooleanObject"
+          defaultValueLiteral="false"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="licenseCost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="exposedInterfaces" upperBound="-1"
+          eType="#//application/SoftwareInterface" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="consumedInterfaces" upperBound="-1"
+          eType="#//application/SoftwareInterface"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="src" eType="#//commons/Source"
+          containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="DBMS" eSuperTypes="#//application/SoftwareComponent"/>
+    <eClassifiers xsi:type="ecore:EClass" name="SaaS" eSuperTypes="#//application/ApplicationComponent">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="licenseCost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="exposedInterfaces" upperBound="-1"
+          eType="#//application/SoftwareInterface" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="SaaSDBMS" eSuperTypes="#//application/SaaS"/>
+    <eClassifiers xsi:type="ecore:EClass" name="SoftwareInterface" eSuperTypes="#//application/ApplicationComponent">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="endPoint" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ExtApplicationComponent" eSuperTypes="#//application/ApplicationComponent #//commons/ExtensionElement"/>
+  </eSubpackages>
+  <eSubpackages name="infrastructure" nsURI="http://www.piacere-project.eu/doml/infrastructure"
+      nsPrefix="infra">
+    <eClassifiers xsi:type="ecore:EClass" name="InfrastructureLayer" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="nodes" upperBound="-1"
+          eType="#//infrastructure/ComputingNode" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="generators" upperBound="-1"
+          eType="#//infrastructure/ComputingNodeGenerator" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="storages" upperBound="-1"
+          eType="#//infrastructure/Storage" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="faas" upperBound="-1"
+          eType="#//infrastructure/FunctionAsAService" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="credentials" upperBound="-1"
+          eType="#//commons/Credentials" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="groups" upperBound="-1"
+          eType="#//infrastructure/ComputingGroup" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="securityGroups" upperBound="-1"
+          eType="#//infrastructure/SecurityGroup" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="networks" upperBound="-1"
+          eType="#//infrastructure/Network" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="rules" upperBound="-1"
+          eType="#//infrastructure/MonitoringRule" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="MonitoringRule" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="condition" lowerBound="1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="strategy" lowerBound="1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="strategyConfigurationString"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ComputingGroup" abstract="true" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="groupedNodes" upperBound="-1"
+          eType="#//infrastructure/ComputingNode" eOpposite="#//infrastructure/ComputingNode/group"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="AutoScalingGroup" eSuperTypes="#//infrastructure/ComputingGroup">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="machineDefinition" lowerBound="1"
+          eType="#//infrastructure/VirtualMachine" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="min" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"
+          defaultValueLiteral="1"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="max" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"
+          defaultValueLiteral="1"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="securityGroup" eType="#//infrastructure/SecurityGroup"
+          containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="loadBalancer" eType="#//infrastructure/LoadBalancerKind"
+          defaultValueLiteral="DEFAULT"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EEnum" name="LoadBalancerKind">
+      <eLiterals name="DEFAULT"/>
+      <eLiterals name="INTERNAL" value="1"/>
+      <eLiterals name="EXTERNAL" value="2"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Rule" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" eType="#//infrastructure/RuleKind"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="protocol" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="fromPort" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="toPort" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="cidr" upperBound="-1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EEnum" name="RuleKind">
+      <eLiterals name="EGRESS"/>
+      <eLiterals name="INGRESS" value="1"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="SecurityGroup" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="rules" upperBound="-1"
+          eType="#//infrastructure/Rule" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="ifaces" upperBound="-1"
+          eType="#//infrastructure/NetworkInterface" eOpposite="#//infrastructure/NetworkInterface/associated"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="AvailabilityGroup" eSuperTypes="#//infrastructure/ComputingGroup"/>
+    <eClassifiers xsi:type="ecore:EClass" name="InfrastructureElement" abstract="true"
+        eSuperTypes="#//commons/DOMLElement #//commons/DeployableElement"/>
+    <eClassifiers xsi:type="ecore:EClass" name="Node" abstract="true" eSuperTypes="#//infrastructure/InfrastructureElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="ifaces" upperBound="-1"
+          eType="#//infrastructure/NetworkInterface" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ComputingNode" abstract="true" eSuperTypes="#//infrastructure/Node">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="architecture" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="os" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="memory_mb" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="storage" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="cpu_count" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="location" eType="#//infrastructure/Location"
+          containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="credentials" eType="#//commons/Credentials"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="group" eType="#//infrastructure/ComputingGroup"
+          eOpposite="#//infrastructure/ComputingGroup/groupedNodes"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="nodeSpecificMonitoring"
+          upperBound="-1" eType="#//infrastructure/MonitoringRule"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="disabledMonitorings"
+          upperBound="-1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ComputingNodeGenerator" abstract="true"
+        eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="uri" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" eType="#//infrastructure/GeneratorKind"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EEnum" name="GeneratorKind">
+      <eLiterals name="SCRIPT"/>
+      <eLiterals name="IMAGE" value="1"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="VMImage" eSuperTypes="#//infrastructure/ComputingNodeGenerator">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="generatedVMs" upperBound="-1"
+          eType="#//infrastructure/VirtualMachine" eOpposite="#//infrastructure/VirtualMachine/generatedFrom"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ContainerImage" eSuperTypes="#//infrastructure/ComputingNodeGenerator">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="generatedContainers"
+          upperBound="-1" eType="#//infrastructure/Container" eOpposite="#//infrastructure/Container/generatedFrom"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="PhysicalComputingNode" eSuperTypes="#//infrastructure/ComputingNode"/>
+    <eClassifiers xsi:type="ecore:EClass" name="VirtualMachine" eSuperTypes="#//infrastructure/ComputingNode">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="sizeDescription" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="generatedFrom" eType="#//infrastructure/VMImage"
+          eOpposite="#//infrastructure/VMImage/generatedVMs"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Location" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="region" lowerBound="1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="zone" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ContainerConfig" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="container_port" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="vm_port" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="host" eType="#//infrastructure/ComputingNode"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="iface" eType="#//infrastructure/NetworkInterface"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Container" eSuperTypes="#//infrastructure/ComputingNode">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="generatedFrom" eType="#//infrastructure/ContainerImage"
+          eOpposite="#//infrastructure/ContainerImage/generatedContainers"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="configs" upperBound="-1"
+          eType="#//infrastructure/ContainerConfig" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Network" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="protocol" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="addressRange" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="connectedIfaces" upperBound="-1"
+          eType="#//infrastructure/NetworkInterface" eOpposite="#//infrastructure/NetworkInterface/belongsTo"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="gateways" upperBound="-1"
+          eType="#//infrastructure/InternetGateway" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="subnets" upperBound="-1"
+          eType="#//infrastructure/Subnet" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Subnet" eSuperTypes="#//infrastructure/Network">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="connectedTo" upperBound="-1"
+          eType="#//infrastructure/Subnet"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="NetworkInterface" eSuperTypes="#//infrastructure/InfrastructureElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="speed" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="endPoint" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="belongsTo" eType="#//infrastructure/Network"
+          eOpposite="#//infrastructure/Network/connectedIfaces"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="associated" upperBound="-1"
+          eType="#//infrastructure/SecurityGroup" eOpposite="#//infrastructure/SecurityGroup/ifaces"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="InternetGateway" eSuperTypes="#//infrastructure/Node">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="address" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Storage" eSuperTypes="#//infrastructure/InfrastructureElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="label" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="size_gb" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="FunctionAsAService" eSuperTypes="#//infrastructure/InfrastructureElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EEnum" name="RoleKind">
+      <eLiterals name="NONE"/>
+      <eLiterals name="MANAGER" value="1"/>
+      <eLiterals name="WORKER" value="2"/>
+      <eLiterals name="MASTER" value="3"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="SwarmRole" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" eType="#//infrastructure/RoleKind"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="nodes" upperBound="-1"
+          eType="#//infrastructure/ComputingNode" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Swarm" eSuperTypes="#//infrastructure/ComputingGroup">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="roles" upperBound="-1"
+          eType="#//infrastructure/SwarmRole" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ExtInfrastructureElement" eSuperTypes="#//infrastructure/InfrastructureElement #//commons/ExtensionElement"/>
+  </eSubpackages>
+  <eSubpackages name="concrete" nsURI="http://www.piacere-project.eu/doml/concrete"
+      nsPrefix="concrete">
+    <eClassifiers xsi:type="ecore:EClass" name="ConcreteInfrastructure" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="providers" upperBound="-1"
+          eType="#//concrete/RuntimeProvider" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="RuntimeProvider" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="resources" upperBound="-1"
+          eType="#//concrete/GenericResource" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="vms" upperBound="-1"
+          eType="#//concrete/VirtualMachine" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="vmImages" upperBound="-1"
+          eType="#//concrete/VMImage" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="containerImages" upperBound="-1"
+          eType="#//concrete/ContainerImage" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="networks" upperBound="-1"
+          eType="#//concrete/Network" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="storages" upperBound="-1"
+          eType="#//concrete/Storage" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="faas" upperBound="-1"
+          eType="#//concrete/FunctionAsAService" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="group" upperBound="-1"
+          eType="#//concrete/ComputingGroup" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ConcreteElement" abstract="true" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="configurationScript"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="preexisting" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBooleanObject"
+          defaultValueLiteral="false"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="refs" upperBound="-1"
+          eType="#//concrete/ConcreteElement"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="GenericResource" eSuperTypes="#//concrete/ConcreteElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="type" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="gname" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="VirtualMachine" eSuperTypes="#//concrete/ConcreteElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/VirtualMachine"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="VMImage" eSuperTypes="#//concrete/ConcreteElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="image_name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/VMImage"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ContainerImage" eSuperTypes="#//concrete/ConcreteElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/ContainerImage"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Network" eSuperTypes="#//concrete/ConcreteElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/Network"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Storage" eSuperTypes="#//concrete/ConcreteElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/Storage"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="FunctionAsAService" eSuperTypes="#//concrete/ConcreteElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/FunctionAsAService"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ComputingGroup" eSuperTypes="#//concrete/ConcreteElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/ComputingGroup"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ExtConcreteElement" eSuperTypes="#//concrete/ConcreteElement #//commons/ExtensionElement"/>
+  </eSubpackages>
+  <eSubpackages name="optimization" nsURI="http://www.piacere-project.eu/doml/optimization"
+      nsPrefix="optimization">
+    <eClassifiers xsi:type="ecore:EClass" name="OptimizationLayer" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="startingHint" eType="#//commons/Configuration"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="solutions" upperBound="-1"
+          eType="#//optimization/OptimizationSolution" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="objectives" upperBound="-1"
+          eType="#//optimization/OptimizationObjective" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="nonfunctionalRequirements"
+          upperBound="-1" eType="#//commons/Requirement" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ObjectiveValue">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="availability" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="performance" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="OptimizationSolution" eSuperTypes="#//commons/Configuration">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="objectives" eType="#//optimization/ObjectiveValue"
+          containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="decisions" upperBound="-1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="OptimizationObjective" abstract="true"
+        eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" lowerBound="1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+          defaultValueLiteral="Max"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="property" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="CountObjective" eSuperTypes="#//optimization/OptimizationObjective"/>
+    <eClassifiers xsi:type="ecore:EClass" name="MeasurableObjective" eSuperTypes="#//optimization/OptimizationObjective"/>
+    <eClassifiers xsi:type="ecore:EClass" name="ExtOptimizationObjective" eSuperTypes="#//optimization/OptimizationObjective #//commons/ExtensionElement"/>
+  </eSubpackages>
+</ecore:EPackage>
diff --git a/mc_openapi/assets/metamodels/doml_v3.1.ecore b/mc_openapi/assets/metamodels/doml_v3.1.ecore
new file mode 100644
index 0000000000000000000000000000000000000000..ce4f02e1e1cd9b8186b33d6ab0dd5a2452c699e8
--- /dev/null
+++ b/mc_openapi/assets/metamodels/doml_v3.1.ecore
@@ -0,0 +1,489 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="doml" nsURI="http://www.piacere-project.eu/doml" nsPrefix="doml">
+  <eAnnotations source="emf.gen">
+    <details key="basePackage" value="eu.piacere.doml"/>
+    <details key="fileExtensions" value="domlx"/>
+    <details key="complianceLevel" value="JDK80"/>
+  </eAnnotations>
+  <eSubpackages name="commons" nsURI="http://www.piacere-project.eu/doml/commons"
+      nsPrefix="commons">
+    <eClassifiers xsi:type="ecore:EClass" name="DOMLModel" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="version" lowerBound="1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+          defaultValueLiteral="3.1"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="application" eType="#//application/ApplicationLayer"
+          containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="infrastructure" eType="#//infrastructure/InfrastructureLayer"
+          containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="concretizations" upperBound="-1"
+          eType="#//concrete/ConcreteInfrastructure" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="optimization" eType="#//optimization/OptimizationLayer"
+          containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="configurations" upperBound="-1"
+          eType="#//commons/Configuration" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="activeConfiguration"
+          eType="#//commons/Configuration"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="activeInfrastructure"
+          eType="#//concrete/ConcreteInfrastructure"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="functionalRequirements"
+          upperBound="-1" eType="#//commons/Requirement" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Property" abstract="true">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="key" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ListProperty" eSuperTypes="#//commons/Property">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="values" upperBound="-1"
+          eType="#//commons/Property" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="IProperty" eSuperTypes="#//commons/Property">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="SProperty" eSuperTypes="#//commons/Property">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="FProperty" eSuperTypes="#//commons/Property">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="BProperty" eSuperTypes="#//commons/Property">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBooleanObject"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ExtensionElement" abstract="true">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="metaclassName" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="DOMLElement" abstract="true">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="description" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="annotations" upperBound="-1"
+          eType="#//commons/Property" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="contributesTo" upperBound="-1"
+          eType="#//commons/Requirement" eOpposite="#//commons/Requirement/predicatesOn"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Configuration" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="deployments" upperBound="-1"
+          eType="#//commons/Deployment" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="DeployableElement" abstract="true"/>
+    <eClassifiers xsi:type="ecore:EClass" name="Deployment">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="component" lowerBound="1"
+          eType="#//commons/DeployableElement"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="node" lowerBound="1"
+          eType="#//infrastructure/InfrastructureElement"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Requirement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="description" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="property" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="predicatesOn" upperBound="-1"
+          eType="#//commons/DOMLElement" eOpposite="#//commons/DOMLElement/contributesTo"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="RangedRequirement" eSuperTypes="#//commons/Requirement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="min" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="max" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="EnumeratedRequirement" eSuperTypes="#//commons/Requirement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="values" upperBound="-1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="DeploymentRequirement" abstract="true"
+        eSuperTypes="#//commons/Requirement"/>
+    <eClassifiers xsi:type="ecore:EClass" name="DeploymentToNodeTypeRequirement" eSuperTypes="#//commons/DeploymentRequirement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="validTypes" upperBound="-1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="DeploymentToNodeWithPropertyRequirement"
+        eSuperTypes="#//commons/DeploymentRequirement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="min" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="max" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="values" upperBound="-1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="DeploymentToSpecificNodeRequirement"
+        eSuperTypes="#//commons/DeploymentRequirement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="validElements" upperBound="-1"
+          eType="#//infrastructure/InfrastructureElement"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Credentials" abstract="true" eSuperTypes="#//commons/DOMLElement"/>
+    <eClassifiers xsi:type="ecore:EClass" name="KeyPair" eSuperTypes="#//commons/Credentials">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="user" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="key" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="algorithm" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="bits" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="UserPass" eSuperTypes="#//commons/Credentials">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="username" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="password" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Source" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="entry" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="inventory" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="backend" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+  </eSubpackages>
+  <eSubpackages name="application" nsURI="http://www.piacere-project.eu/doml/application"
+      nsPrefix="app">
+    <eClassifiers xsi:type="ecore:EClass" name="ApplicationLayer" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="components" upperBound="-1"
+          eType="#//application/ApplicationComponent" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ApplicationComponent" abstract="true"
+        eSuperTypes="#//commons/DOMLElement #//commons/DeployableElement"/>
+    <eClassifiers xsi:type="ecore:EClass" name="SoftwareComponent" eSuperTypes="#//application/ApplicationComponent">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="isPersistent" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBooleanObject"
+          defaultValueLiteral="false"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="licenseCost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="exposedInterfaces" upperBound="-1"
+          eType="#//application/SoftwareInterface" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="consumedInterfaces" upperBound="-1"
+          eType="#//application/SoftwareInterface"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="src" eType="#//commons/Source"
+          containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="DBMS" eSuperTypes="#//application/SoftwareComponent"/>
+    <eClassifiers xsi:type="ecore:EClass" name="SaaS" eSuperTypes="#//application/ApplicationComponent">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="licenseCost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="exposedInterfaces" upperBound="-1"
+          eType="#//application/SoftwareInterface" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="SaaSDBMS" eSuperTypes="#//application/SaaS">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="databaseName" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="engine" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="engineVersion" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="SoftwareInterface" eSuperTypes="#//application/ApplicationComponent">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="endPoint" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ExtApplicationComponent" eSuperTypes="#//application/ApplicationComponent #//commons/ExtensionElement"/>
+  </eSubpackages>
+  <eSubpackages name="infrastructure" nsURI="http://www.piacere-project.eu/doml/infrastructure"
+      nsPrefix="infra">
+    <eClassifiers xsi:type="ecore:EClass" name="InfrastructureLayer" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="nodes" upperBound="-1"
+          eType="#//infrastructure/ComputingNode" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="generators" upperBound="-1"
+          eType="#//infrastructure/ComputingNodeGenerator" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="storages" upperBound="-1"
+          eType="#//infrastructure/Storage" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="faas" upperBound="-1"
+          eType="#//infrastructure/FunctionAsAService" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="credentials" upperBound="-1"
+          eType="#//commons/Credentials" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="executionEnvironments"
+          upperBound="-1" eType="#//infrastructure/ExecutionEnvironment" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="groups" upperBound="-1"
+          eType="#//infrastructure/ComputingGroup" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="securityGroups" upperBound="-1"
+          eType="#//infrastructure/SecurityGroup" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="networks" upperBound="-1"
+          eType="#//infrastructure/Network" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="rules" upperBound="-1"
+          eType="#//infrastructure/MonitoringRule" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="MonitoringRule" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="condition" lowerBound="1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="strategy" lowerBound="1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="strategyConfigurationString"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ComputingGroup" abstract="true" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="groupedNodes" upperBound="-1"
+          eType="#//infrastructure/ComputingNode" eOpposite="#//infrastructure/ComputingNode/group"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="AutoScalingGroup" eSuperTypes="#//infrastructure/ComputingGroup">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="machineDefinition" lowerBound="1"
+          eType="#//infrastructure/VirtualMachine" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="min" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"
+          defaultValueLiteral="1"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="max" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"
+          defaultValueLiteral="1"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="loadBalancer" eType="#//infrastructure/LoadBalancerKind"
+          defaultValueLiteral="DEFAULT"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EEnum" name="LoadBalancerKind">
+      <eLiterals name="DEFAULT"/>
+      <eLiterals name="INTERNAL" value="1"/>
+      <eLiterals name="EXTERNAL" value="2"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Rule" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" eType="#//infrastructure/RuleKind"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="protocol" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="fromPort" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="toPort" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="cidr" upperBound="-1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EEnum" name="RuleKind">
+      <eLiterals name="EGRESS"/>
+      <eLiterals name="INGRESS" value="1"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="SecurityGroup" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="rules" upperBound="-1"
+          eType="#//infrastructure/Rule" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="ifaces" upperBound="-1"
+          eType="#//infrastructure/NetworkInterface" eOpposite="#//infrastructure/NetworkInterface/associated"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="InfrastructureElement" abstract="true"
+        eSuperTypes="#//commons/DOMLElement #//commons/DeployableElement"/>
+    <eClassifiers xsi:type="ecore:EClass" name="Node" abstract="true" eSuperTypes="#//infrastructure/InfrastructureElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="ifaces" upperBound="-1"
+          eType="#//infrastructure/NetworkInterface" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ComputingNode" abstract="true" eSuperTypes="#//infrastructure/Node">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="architecture" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="os" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="memory_mb" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="storage" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="cpu_count" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="location" eType="#//infrastructure/Location"
+          containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="credentials" eType="#//commons/Credentials"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="group" eType="#//infrastructure/ComputingGroup"
+          eOpposite="#//infrastructure/ComputingGroup/groupedNodes"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="nodeSpecificMonitoring"
+          upperBound="-1" eType="#//infrastructure/MonitoringRule"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="disabledMonitorings"
+          upperBound="-1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ComputingNodeGenerator" abstract="true"
+        eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="uri" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" eType="#//infrastructure/GeneratorKind"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EEnum" name="GeneratorKind">
+      <eLiterals name="SCRIPT"/>
+      <eLiterals name="IMAGE" value="1"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="VMImage" eSuperTypes="#//infrastructure/ComputingNodeGenerator">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="generatedVMs" upperBound="-1"
+          eType="#//infrastructure/VirtualMachine" eOpposite="#//infrastructure/VirtualMachine/generatedFrom"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ContainerImage" eSuperTypes="#//infrastructure/ComputingNodeGenerator">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="generatedContainers"
+          upperBound="-1" eType="#//infrastructure/Container" eOpposite="#//infrastructure/Container/generatedFrom"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="PhysicalComputingNode" eSuperTypes="#//infrastructure/ComputingNode">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="configInterface" eType="#//infrastructure/NetworkInterface"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="VirtualMachine" eSuperTypes="#//infrastructure/ComputingNode">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="sizeDescription" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="generatedFrom" eType="#//infrastructure/VMImage"
+          eOpposite="#//infrastructure/VMImage/generatedVMs"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="configInterface" eType="#//infrastructure/NetworkInterface"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Location" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="region" lowerBound="1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="zone" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ContainerConfig" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="container_port" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="vm_port" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EIntegerObject"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="iface" eType="#//infrastructure/NetworkInterface"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ContainerHostConfig" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="environment_variables"
+          upperBound="-1" eType="#//commons/SProperty" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="host" eType="#//infrastructure/ComputingNode"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="configurations" upperBound="-1"
+          eType="#//infrastructure/ContainerConfig" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Container" eSuperTypes="#//infrastructure/ComputingNode">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="generatedFrom" eType="#//infrastructure/ContainerImage"
+          eOpposite="#//infrastructure/ContainerImage/generatedContainers"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="hostConfigs" upperBound="-1"
+          eType="#//infrastructure/ContainerHostConfig" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="networks" upperBound="-1"
+          eType="#//infrastructure/ContainerNetwork"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="volumes" upperBound="-1"
+          eType="#//infrastructure/ContainerVolume"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="dependsOn" upperBound="-1"
+          eType="#//infrastructure/Container"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ContainerGroup" eSuperTypes="#//infrastructure/ComputingGroup">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="services" lowerBound="1"
+          upperBound="-1" eType="#//infrastructure/Container" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="networks" upperBound="-1"
+          eType="#//infrastructure/ContainerNetwork" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="volumes" upperBound="-1"
+          eType="#//infrastructure/ContainerVolume" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ContainerNetwork" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="containerNetworkName"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ContainerVolume" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="containerVolumeName"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="path" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ExecutionEnvironment" eSuperTypes="#//infrastructure/InfrastructureElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="size" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloat"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="maxSize" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloat"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="location" eType="#//infrastructure/Location"
+          containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="network" eType="#//infrastructure/Network"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="securityGroups" upperBound="-1"
+          eType="#//infrastructure/SecurityGroup"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Network" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="protocol" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+          defaultValueLiteral="TCP/IP"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="connectedIfaces" upperBound="-1"
+          eType="#//infrastructure/NetworkInterface" eOpposite="#//infrastructure/NetworkInterface/belongsTo"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="gateways" upperBound="-1"
+          eType="#//infrastructure/InternetGateway" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="subnets" upperBound="-1"
+          eType="#//infrastructure/Subnet" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Subnet" eSuperTypes="#//infrastructure/Network">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="connectedTo" upperBound="-1"
+          eType="#//infrastructure/Subnet"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="NetworkInterface" eSuperTypes="#//infrastructure/InfrastructureElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="speed" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="endPoint" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="belongsTo" eType="#//infrastructure/Network"
+          eOpposite="#//infrastructure/Network/connectedIfaces"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="associated" upperBound="-1"
+          eType="#//infrastructure/SecurityGroup" eOpposite="#//infrastructure/SecurityGroup/ifaces"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="InternetGateway" eSuperTypes="#//infrastructure/Node">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="address" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Storage" eSuperTypes="#//infrastructure/InfrastructureElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="label" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="size_gb" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="FunctionAsAService" eSuperTypes="#//infrastructure/InfrastructureElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EEnum" name="RoleKind">
+      <eLiterals name="NONE"/>
+      <eLiterals name="MANAGER" value="1"/>
+      <eLiterals name="WORKER" value="2"/>
+      <eLiterals name="MASTER" value="3"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="SwarmRole" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" eType="#//infrastructure/RoleKind"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="nodes" upperBound="-1"
+          eType="#//infrastructure/ComputingNode" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Swarm" eSuperTypes="#//infrastructure/ComputingGroup">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="roles" upperBound="-1"
+          eType="#//infrastructure/SwarmRole" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ExtInfrastructureElement" eSuperTypes="#//infrastructure/InfrastructureElement #//commons/ExtensionElement"/>
+  </eSubpackages>
+  <eSubpackages name="concrete" nsURI="http://www.piacere-project.eu/doml/concrete"
+      nsPrefix="concrete">
+    <eClassifiers xsi:type="ecore:EClass" name="ConcreteInfrastructure" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="providers" upperBound="-1"
+          eType="#//concrete/RuntimeProvider" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="RuntimeProvider" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="resources" upperBound="-1"
+          eType="#//concrete/GenericResource" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="vms" upperBound="-1"
+          eType="#//concrete/VirtualMachine" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="executionEnvironments"
+          upperBound="-1" eType="#//concrete/ExecutionEnvironment" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="vmImages" upperBound="-1"
+          eType="#//concrete/VMImage" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="containerImages" upperBound="-1"
+          eType="#//concrete/ContainerImage" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="networks" upperBound="-1"
+          eType="#//concrete/Network" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="storages" upperBound="-1"
+          eType="#//concrete/Storage" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="faas" upperBound="-1"
+          eType="#//concrete/FunctionAsAService" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="autoScalingGroups" upperBound="-1"
+          eType="#//concrete/AutoScalingGroup" containment="true"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ConcreteElement" abstract="true" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="resourceName" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="configurationScript"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="preexisting" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBooleanObject"
+          defaultValueLiteral="false"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="refs" upperBound="-1"
+          eType="#//concrete/ConcreteElement"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="GenericResource" eSuperTypes="#//concrete/ConcreteElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="type" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="VirtualMachine" eSuperTypes="#//concrete/ConcreteElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="vm_type" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/VirtualMachine"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="VMImage" eSuperTypes="#//concrete/ConcreteElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="image_name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/VMImage"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ContainerImage" eSuperTypes="#//concrete/ConcreteElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/ContainerImage"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ExecutionEnvironment" eSuperTypes="#//concrete/ConcreteElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="instance_type" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="storage_type" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/ExecutionEnvironment"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Network" eSuperTypes="#//concrete/ConcreteElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="protocol" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="addressRange" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="subnets" upperBound="-1"
+          eType="#//concrete/Subnet" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/Network"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="Subnet" eSuperTypes="#//concrete/Network"/>
+    <eClassifiers xsi:type="ecore:EClass" name="Storage" eSuperTypes="#//concrete/ConcreteElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/Storage"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="FunctionAsAService" eSuperTypes="#//concrete/ConcreteElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/FunctionAsAService"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="AutoScalingGroup" eSuperTypes="#//concrete/ConcreteElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="vm_type" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="maps" eType="#//infrastructure/AutoScalingGroup"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ExtConcreteElement" eSuperTypes="#//concrete/ConcreteElement #//commons/ExtensionElement"/>
+  </eSubpackages>
+  <eSubpackages name="optimization" nsURI="http://www.piacere-project.eu/doml/optimization"
+      nsPrefix="opt">
+    <eClassifiers xsi:type="ecore:EClass" name="OptimizationLayer" eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="startingHint" eType="#//commons/Configuration"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="solutions" upperBound="-1"
+          eType="#//optimization/OptimizationSolution" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="objectives" upperBound="-1"
+          eType="#//optimization/OptimizationObjective" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EReference" name="nonfunctionalRequirements"
+          upperBound="-1" eType="#//commons/Requirement" containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="runtime" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="ObjectiveValue">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="cost" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="availability" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="performance" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFloatObject"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="OptimizationSolution" eSuperTypes="#//commons/Configuration">
+      <eStructuralFeatures xsi:type="ecore:EReference" name="objectives" eType="#//optimization/ObjectiveValue"
+          containment="true"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="decisions" upperBound="-1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="OptimizationObjective" abstract="true"
+        eSuperTypes="#//commons/DOMLElement">
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="kind" lowerBound="1"
+          eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"
+          defaultValueLiteral="Max"/>
+      <eStructuralFeatures xsi:type="ecore:EAttribute" name="property" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    </eClassifiers>
+    <eClassifiers xsi:type="ecore:EClass" name="CountObjective" eSuperTypes="#//optimization/OptimizationObjective"/>
+    <eClassifiers xsi:type="ecore:EClass" name="MeasurableObjective" eSuperTypes="#//optimization/OptimizationObjective"/>
+    <eClassifiers xsi:type="ecore:EClass" name="ExtOptimizationObjective" eSuperTypes="#//optimization/OptimizationObjective #//commons/ExtensionElement"/>
+  </eSubpackages>
+</ecore:EPackage>
diff --git a/mc_openapi/assets/static/bulma.css.map b/mc_openapi/assets/static/bulma.css.map
new file mode 100644
index 0000000000000000000000000000000000000000..dbe97a3f8b86f760be5e2dca7572dc06c70b5874
--- /dev/null
+++ b/mc_openapi/assets/static/bulma.css.map
@@ -0,0 +1 @@
+{"version":3,"sources":["../bulma.sass","../sass/utilities/_all.sass","../sass/utilities/extends.sass","../sass/utilities/controls.sass","../sass/utilities/initial-variables.sass","bulma.css","../sass/utilities/mixins.sass","../sass/base/_all.sass","../sass/base/minireset.sass","../sass/base/generic.sass","../sass/utilities/derived-variables.sass","../sass/base/animations.sass","../sass/elements/_all.sass","../sass/elements/box.sass","../sass/elements/button.sass","../sass/utilities/functions.sass","../sass/elements/container.sass","../sass/elements/content.sass","../sass/elements/icon.sass","../sass/elements/image.sass","../sass/elements/notification.sass","../sass/elements/progress.sass","../sass/elements/table.sass","../sass/elements/tag.sass","../sass/elements/title.sass","../sass/elements/other.sass","../sass/form/_all.sass","../sass/form/shared.sass","../sass/form/input-textarea.sass","../sass/form/checkbox-radio.sass","../sass/form/select.sass","../sass/form/file.sass","../sass/form/tools.sass","../sass/components/_all.sass","../sass/components/breadcrumb.sass","../sass/components/card.sass","../sass/components/dropdown.sass","../sass/components/level.sass","../sass/components/media.sass","../sass/components/menu.sass","../sass/components/message.sass","../sass/components/modal.sass","../sass/components/navbar.sass","../sass/components/pagination.sass","../sass/components/panel.sass","../sass/components/tabs.sass","../sass/grid/_all.sass","../sass/grid/columns.sass","../sass/grid/tiles.sass","../sass/helpers/_all.sass","../sass/helpers/color.sass","../sass/helpers/flexbox.sass","../sass/helpers/float.sass","../sass/helpers/other.sass","../sass/helpers/overflow.sass","../sass/helpers/position.sass","../sass/helpers/spacing.sass","../sass/helpers/typography.sass","../sass/helpers/visibility.sass","../sass/layout/_all.sass","../sass/layout/hero.sass","../sass/layout/section.sass","../sass/layout/footer.sass"],"names":[],"mappings":"AACA,6DAAA;ACDA,oBAAA;ACEA;;;;;ECYE,qBAAqB;EACrB,wBAAwB;EACxB,mBAAmB;EACnB,6BAA+C;EAC/C,kBCoDU;EDnDV,gBAAgB;EAChB,oBAAoB;EACpB,eCgBW;EDfX,aAfoB;EAgBpB,2BAA2B;EAC3B,gBAhBuB;EAiBvB,iCAf+D;EAgB/D,gCAfkE;EAgBlE,iCAhBkE;EAiBlE,8BAlB+D;EAmB/D,kBAAkB;EAClB,mBAAmB;AENrB;;AFQE;;;;;;;;;;;;;;;;;EAIE,aAAa;AEQjB;;AFPE;;;;;;;;;;;;;;;;EAEE,mBAAmB;AEwBvB;;AH1DA;;;;EI4LE,2BAA2B;EAC3B,yBAAyB;EACzB,sBAAsB;EACtB,qBAAqB;EACrB,iBAAiB;AD3HnB;;AHlEA;EIgME,6BAD8B;EAE9B,kBAAkB;EAClB,eAAe;EACf,aAAa;EACb,YAAY;EACZ,cAAc;EACd,eAAe;EACf,qBAAqB;EACrB,oBAAoB;EACpB,kBAAkB;EAClB,QAAQ;EACR,yBAAyB;EACzB,wBAAwB;EACxB,cAAc;AD1HhB;;AC6HE;;EACE,qBFzKkB;ACgDtB;;AHlFA;EImLE,2BAA2B;EAC3B,yBAAyB;EACzB,sBAAsB;EACtB,qBAAqB;EACrB,iBAAiB;EAwBjB,qBAAqB;EACrB,wBAAwB;EACxB,uCF7N2B;EE8N3B,YAAY;EACZ,qBFzJqB;EE0JrB,eAAe;EACf,oBAAoB;EACpB,qBAAqB;EACrB,YAAY;EACZ,cAAc;EACd,YAAY;EACZ,YAAY;EACZ,gBAAgB;EAChB,eAAe;EACf,gBAAgB;EAChB,eAAe;EACf,aAAa;EACb,kBAAkB;EAClB,mBAAmB;EACnB,WAAW;ADpHb;;ACqHE;EAEE,uBFpO2B;EEqO3B,WAAW;EACX,cAAc;EACd,SAAS;EACT,kBAAkB;EAClB,QAAQ;EACR,0DAA0D;EAC1D,+BAA+B;ADnHnC;;ACoHE;EACE,WAAW;EACX,UAAU;ADjHd;;ACkHE;EACE,WAAW;EACX,UAAU;AD/Gd;;ACgHE;EAEE,uCFjQyB;ACmJ7B;;AC+GE;EACE,uCFnQyB;ACuJ7B;;AC8GE;EACE,YAAY;EACZ,gBAAgB;EAChB,eAAe;EACf,gBAAgB;EAChB,eAAe;EACf,WAAW;AD3Gf;;AC4GE;EACE,YAAY;EACZ,gBAAgB;EAChB,eAAe;EACf,gBAAgB;EAChB,eAAe;EACf,WAAW;ADzGf;;AC0GE;EACE,YAAY;EACZ,gBAAgB;EAChB,eAAe;EACf,gBAAgB;EAChB,eAAe;EACf,WAAW;ADvGf;;AHnKA;EI6QE,mDAA2C;UAA3C,2CAA2C;EAC3C,yBFrR4B;EEsR5B,qBFxNqB;EEyNrB,+BAA+B;EAC/B,6BAA6B;EAC7B,WAAW;EACX,cAAc;EACd,WAAW;EACX,kBAAkB;EAClB,UAAU;ADtGZ;;AH7KA;;;;;;;;;;;;;;;;;EIsRE,SADuB;EAEvB,OAFuB;EAGvB,kBAAkB;EAClB,QAJuB;EAKvB,MALuB;ADhFzB;;AHlMA;EIqDE,qBAAqB;EACrB,wBAAwB;EACxB,gBAAgB;EAChB,gBAAgB;EAChB,YAAY;EACZ,mBAAmB;EACnB,oBAAoB;EACpB,cAAc;EACd,SAAS;EACT,UAAU;ADiJZ;;AEtOA,eAAA;ACAA,0EAAA;AAEA;;;;;;;;;;;;;;;;;;;;;;;EAuBE,SAAS;EACT,UAAU;AHyOZ;;AGtOA;;;;;;EAME,eAAe;EACf,mBAAmB;AHyOrB;;AGtOA;EACE,gBAAgB;AHyOlB;;AGtOA;;;;EAIE,SAAS;AHyOX;;AGtOA;EACE,sBAAsB;AHyOxB;;AGvOA;EAII,mBAAmB;AHuOvB;;AGpOA;;EAEE,YAAY;EACZ,eAAe;AHuOjB;;AGpOA;EACE,SAAS;AHuOX;;AGpOA;EACE,yBAAyB;EACzB,iBAAiB;AHuOnB;;AGrOA;;EAEE,UAAU;AHwOZ;;AG1OA;;EAII,mBAAmB;AH2OvB;;AGvQA;EChBE,uBLnB6B;EKoB7B,eAhCc;EAiCd,kCAAkC;EAClC,mCAAmC;EACnC,gBAlCoB;EAmCpB,kBAhCsB;EAiCtB,kBAhCsB;EAiCtB,kCApCiC;EAqCjC,8BAAsB;KAAtB,2BAAsB;UAAtB,sBAAsB;AJ2RxB;;AIzRA;;;;;;;EAOE,cAAc;AJ4RhB;;AI1RA;;;;;;EAME,oLL/ByL;AC4T3L;;AI3RA;;EAEE,6BAA6B;EAC7B,4BAA4B;EAC5B,sBLpC0B;ACkU5B;;AI5RA;EACE,cL7D4B;EK8D5B,cA1DkB;EA2DlB,gBL7BiB;EK8BjB,gBA1DoB;AJyVtB;;AI3RA;EACE,cLtDgC;EKuDhC,eAAe;EACf,qBAAqB;AJ8RvB;;AIjSA;EAKI,mBAAmB;AJgSvB;;AIrSA;EAOI,cL5E0B;AC8W9B;;AIhSA;EACE,4BLxE4B;EKyE5B,cCnBsB;EDoBtB,kBArEiB;EAsEjB,mBAvEkB;EAwElB,4BAzEgC;AJ4WlC;;AIjSA;EACE,4BL/E4B;EKgF5B,YAAY;EACZ,cAAc;EACd,WAxEa;EAyEb,gBAxEkB;AJ4WpB;;AIlSA;EACE,YAAY;EACZ,eAAe;AJqSjB;;AInSA;;EAEE,wBAAwB;AJsS1B;;AIpSA;EACE,kBAvFuB;AJ8XzB;;AIrSA;EACE,mBAAmB;EACnB,oBAAoB;AJwStB;;AItSA;EACE,cL5G4B;EK6G5B,gBLvEe;ACgXjB;;AIrSA;EACE,YAAY;AJwSd;;AItSA;EHvDE,iCAAiC;EGyDjC,4BL/G4B;EKgH5B,cLtH4B;EKuH5B,kBAjGqB;EAkGrB,gBAAgB;EAChB,uBAlG0B;EAmG1B,gBAAgB;EAChB,iBAAiB;AJySnB;;AIjTA;EAUI,6BAA6B;EAC7B,mBAAmB;EACnB,cAvGoB;EAwGpB,UAAU;AJ2Sd;;AIzSA;;EAGI,mBAAmB;AJ2SvB;;AI9SA;;EAKM,mBAAmB;AJ8SzB;;AInTA;EAOI,cL1I0B;AC0b9B;;AMhcA;EACE;IACE,uBAAuB;ENmczB;EMlcA;IACE,yBAAyB;ENoc3B;AACF;;AMzcA;EACE;IACE,uBAAuB;ENmczB;EMlcA;IACE,yBAAyB;ENoc3B;AACF;;AOzcA,mBAAA;ACWA;EAEE,uBTE6B;ESD7B,kBTyDgB;ESxDhB,0FTb2B;ESc3B,cTT4B;ESU5B,cAAc;EACd,gBAZmB;AR6crB;;AQ/bA;EAGI,yETD8B;ACiclC;;AQncA;EAKI,oETH8B;ACqclC;;AS/ZA;EAGE,uBVhD6B;EUiD7B,qBVtD4B;EUuD5B,iBX5DwB;EW6DxB,cV5D4B;EU6D5B,eAAe;EAGf,uBAAuB;EACvB,iCA7D6D;EA8D7D,iBA7D6B;EA8D7B,kBA9D6B;EA+D7B,8BAhE6D;EAiE7D,kBAAkB;EAClB,mBAAmB;AT8ZrB;;AS9aA;EAkBI,cAAc;ATgalB;;ASlbA;EAwBM,aAAa;EACb,YAAY;AT8ZlB;;ASvbA;ERwHI,+BQ7FsG;ER6FtG,oBQ5FmE;ATgavE;;AS5bA;ERwHI,mBQ1FmE;ER0FnE,gCQzFsG;ATka1G;;ASjcA;EAiCM,+BAAiF;EACjF,gCAAkF;AToaxF;;AStcA;EAsCI,qBVzF0B;EU0F1B,cV7F0B;ACigB9B;;AS3cA;EA0CI,qBVhF8B;EUiF9B,cVjG0B;ACsgB9B;;AShdA;EA6CM,iDVnF4B;AC0flC;;ASpdA;EAgDI,qBVrG0B;EUsG1B,cVvG0B;AC+gB9B;;ASzdA;EAoDI,6BAA6B;EAC7B,yBAAyB;EACzB,cV3G0B;EU4G1B,0BA1F8B;ATmgBlC;;ASheA;EA4DM,4BV3GwB;EU4GxB,cVnHwB;AC2hB9B;;ASreA;EAgEM,yBChB2B;EDiB3B,cVvHwB;ACgiB9B;;AS1eA;;EAoEM,6BAA6B;EAC7B,yBAAyB;EACzB,gBAAgB;AT2atB;;ASjfA;EAwEI,gBAvG0B;EAwG1B,yBAvGmC;EAwGnC,cVhH8B;EUiH9B,qBAvG0B;ATohB9B;;ASxfA;EA8EM,cVpH4B;EUqH5B,0BAzGmC;ATuhBzC;;AS7fA;EAoFM,uBVjIyB;EUkIzB,yBAAyB;EACzB,cVhJuB;AC6jB7B;;ASngBA;EAyFQ,yBCzCyB;ED0CzB,yBAAyB;EACzB,cVrJqB;ACmkB7B;;ASzgBA;EA8FQ,yBAAyB;EACzB,cVzJqB;ACwkB7B;;AS9gBA;EAiGU,mDV9IqB;AC+jB/B;;ASlhBA;EAoGQ,yBCpDyB;EDqDzB,yBAAyB;EACzB,cVhKqB;ACklB7B;;ASxhBA;;EAyGQ,uBVtJuB;EUuJvB,mBVvJuB;EUwJvB,gBAAgB;ATobxB;;AS/hBA;EA6GQ,yBVvKqB;EUwKrB,YV3JuB;ACilB/B;;ASpiBA;EAiHU,uBCjEuB;AVwfjC;;ASxiBA;;EAoHU,yBV9KmB;EU+KnB,yBAAyB;EACzB,gBAAgB;EAChB,YVpKqB;AC6lB/B;;AShjBA;EA0HU,gEAA4E;AT0btF;;ASpjBA;EA4HQ,6BAA6B;EAC7B,mBV1KuB;EU2KvB,YV3KuB;ACumB/B;;AS1jBA;EAmIU,uBVhLqB;EUiLrB,mBVjLqB;EUkLrB,cV/LmB;AC0nB7B;;AShkBA;EAwIY,4DAA8D;AT4b1E;;ASpkBA;EA8Ic,gEAA4E;AT0b1F;;ASxkBA;;EAiJU,6BAA6B;EAC7B,mBV/LqB;EUgMrB,gBAAgB;EAChB,YVjMqB;AC6nB/B;;AShlBA;EAsJQ,6BAA6B;EAC7B,qBVjNqB;EUkNrB,cVlNqB;ACgpB7B;;AStlBA;EA6JU,yBVvNmB;EUwNnB,YV3MqB;ACwoB/B;;AS3lBA;EAqKc,4DAA8D;AT0b5E;;AS/lBA;;EAwKU,6BAA6B;EAC7B,qBVnOmB;EUoOnB,gBAAgB;EAChB,cVrOmB;ACiqB7B;;ASvmBA;EAoFM,yBV9IuB;EU+IvB,yBAAyB;EACzB,YVnIyB;AC0pB/B;;AS7mBA;EAyFQ,yBCzCyB;ED0CzB,yBAAyB;EACzB,YVxIuB;ACgqB/B;;ASnnBA;EA8FQ,yBAAyB;EACzB,YV5IuB;ACqqB/B;;ASxnBA;EAiGU,gDV3JmB;ACsrB7B;;AS5nBA;EAoGQ,uBCpDyB;EDqDzB,yBAAyB;EACzB,YVnJuB;AC+qB/B;;ASloBA;;EAyGQ,yBVnKqB;EUoKrB,qBVpKqB;EUqKrB,gBAAgB;AT8hBxB;;ASzoBA;EA6GQ,uBV1JuB;EU2JvB,cVxKqB;ACwsB7B;;AS9oBA;EAiHU,yBCjEuB;AVkmBjC;;ASlpBA;;EAoHU,uBVjKqB;EUkKrB,yBAAyB;EACzB,gBAAgB;EAChB,cVjLmB;ACotB7B;;AS1pBA;EA0HU,4DAA4E;AToiBtF;;AS9pBA;EA4HQ,6BAA6B;EAC7B,qBVvLqB;EUwLrB,cVxLqB;AC8tB7B;;ASpqBA;EAmIU,yBV7LmB;EU8LnB,qBV9LmB;EU+LnB,YVlLqB;ACutB/B;;AS1qBA;EAwIY,gEAA8D;ATsiB1E;;AS9qBA;EA8Ic,4DAA4E;AToiB1F;;ASlrBA;;EAiJU,6BAA6B;EAC7B,qBV5MmB;EU6MnB,gBAAgB;EAChB,cV9MmB;ACovB7B;;AS1rBA;EAsJQ,6BAA6B;EAC7B,mBVpMuB;EUqMvB,YVrMuB;AC6uB/B;;AShsBA;EA6JU,uBV1MqB;EU2MrB,cVxNmB;AC+vB7B;;ASrsBA;EAqKc,gEAA8D;AToiB5E;;ASzsBA;;EAwKU,6BAA6B;EAC7B,mBVtNqB;EUuNrB,gBAAgB;EAChB,YVxNqB;AC8vB/B;;ASjtBA;EAoFM,4BVnIwB;EUoIxB,yBAAyB;EACzB,yBClEe;AVmsBrB;;ASvtBA;EAyFQ,yBCzCyB;ED0CzB,yBAAyB;EACzB,yBCvEa;AVysBrB;;AS7tBA;EA8FQ,yBAAyB;EACzB,yBC3Ea;AV8sBrB;;ASluBA;EAiGU,mDVhJoB;ACqxB9B;;AStuBA;EAoGQ,yBCpDyB;EDqDzB,yBAAyB;EACzB,yBClFa;AVwtBrB;;AS5uBA;;EAyGQ,4BVxJsB;EUyJtB,wBVzJsB;EU0JtB,gBAAgB;ATwoBxB;;ASnvBA;EA6GQ,oCCzFa;ED0Fb,iBV7JsB;ACuyB9B;;ASxvBA;EAiHU,oCCjEuB;AV4sBjC;;AS5vBA;;EAoHU,oCChGW;EDiGX,yBAAyB;EACzB,gBAAgB;EAChB,iBVtKoB;ACmzB9B;;ASpwBA;EA0HU,sFAA4E;AT8oBtF;;ASxwBA;EA4HQ,6BAA6B;EAC7B,wBV5KsB;EU6KtB,iBV7KsB;AC6zB9B;;AS9wBA;EAmIU,4BVlLoB;EUmLpB,wBVnLoB;EUoLpB,yBCjHW;AVgwBrB;;ASpxBA;EAwIY,sEAA8D;ATgpB1E;;ASxxBA;EA8Ic,sFAA4E;AT8oB1F;;AS5xBA;;EAiJU,6BAA6B;EAC7B,wBVjMoB;EUkMpB,gBAAgB;EAChB,iBVnMoB;ACm1B9B;;ASpyBA;EAsJQ,6BAA6B;EAC7B,gCCnIa;EDoIb,yBCpIa;AVsxBrB;;AS1yBA;EA6JU,oCCzIW;ED0IX,iBV7MoB;AC81B9B;;AS/yBA;EAqKc,sEAA8D;AT8oB5E;;ASnzBA;;EAwKU,6BAA6B;EAC7B,gCCrJW;EDsJX,gBAAgB;EAChB,yBCvJW;AVuyBrB;;AS3zBA;EAoFM,yBV1IwB;EU2IxB,yBAAyB;EACzB,WChEU;AV2yBhB;;ASj0BA;EAyFQ,yBCzCyB;ED0CzB,yBAAyB;EACzB,WCrEQ;AVizBhB;;ASv0BA;EA8FQ,yBAAyB;EACzB,WCzEQ;AVszBhB;;AS50BA;EAiGU,gDVvJoB;ACs4B9B;;ASh1BA;EAoGQ,yBCpDyB;EDqDzB,yBAAyB;EACzB,WChFQ;AVg0BhB;;ASt1BA;;EAyGQ,yBV/JsB;EUgKtB,qBVhKsB;EUiKtB,gBAAgB;ATkvBxB;;AS71BA;EA6GQ,sBCvFQ;EDwFR,cVpKsB;ACw5B9B;;ASl2BA;EAiHU,yBCjEuB;AVszBjC;;ASt2BA;;EAoHU,sBC9FM;ED+FN,yBAAyB;EACzB,gBAAgB;EAChB,cV7KoB;ACo6B9B;;AS92BA;EA0HU,0DAA4E;ATwvBtF;;ASl3BA;EA4HQ,6BAA6B;EAC7B,qBVnLsB;EUoLtB,cVpLsB;AC86B9B;;ASx3BA;EAmIU,yBVzLoB;EU0LpB,qBV1LoB;EU2LpB,WC/GM;AVw2BhB;;AS93BA;EAwIY,gEAA8D;AT0vB1E;;ASl4BA;EA8Ic,0DAA4E;ATwvB1F;;ASt4BA;;EAiJU,6BAA6B;EAC7B,qBVxMoB;EUyMpB,gBAAgB;EAChB,cV1MoB;ACo8B9B;;AS94BA;EAsJQ,6BAA6B;EAC7B,kBCjIQ;EDkIR,WClIQ;AV83BhB;;ASp5BA;EA6JU,sBCvIM;EDwIN,cVpNoB;AC+8B9B;;ASz5BA;EAqKc,gEAA8D;ATwvB5E;;AS75BA;;EAwKU,6BAA6B;EAC7B,kBCnJM;EDoJN,gBAAgB;EAChB,WCrJM;AV+4BhB;;ASr6BA;EAoFM,yBV5H4B;EU6H5B,yBAAyB;EACzB,WChEU;AVq5BhB;;AS36BA;EAyFQ,yBCzCyB;ED0CzB,yBAAyB;EACzB,WCrEQ;AV25BhB;;ASj7BA;EA8FQ,yBAAyB;EACzB,WCzEQ;AVg6BhB;;ASt7BA;EAiGU,iDVzIwB;ACk+BlC;;AS17BA;EAoGQ,yBCpDyB;EDqDzB,yBAAyB;EACzB,WChFQ;AV06BhB;;ASh8BA;;EAyGQ,yBVjJ0B;EUkJ1B,qBVlJ0B;EUmJ1B,gBAAgB;AT41BxB;;ASv8BA;EA6GQ,sBCvFQ;EDwFR,cVtJ0B;ACo/BlC;;AS58BA;EAiHU,yBCjEuB;AVg6BjC;;ASh9BA;;EAoHU,sBC9FM;ED+FN,yBAAyB;EACzB,gBAAgB;EAChB,cV/JwB;ACggClC;;ASx9BA;EA0HU,0DAA4E;ATk2BtF;;AS59BA;EA4HQ,6BAA6B;EAC7B,qBVrK0B;EUsK1B,cVtK0B;AC0gClC;;ASl+BA;EAmIU,yBV3KwB;EU4KxB,qBV5KwB;EU6KxB,WC/GM;AVk9BhB;;ASx+BA;EAwIY,gEAA8D;ATo2B1E;;AS5+BA;EA8Ic,0DAA4E;ATk2B1F;;ASh/BA;;EAiJU,6BAA6B;EAC7B,qBV1LwB;EU2LxB,gBAAgB;EAChB,cV5LwB;ACgiClC;;ASx/BA;EAsJQ,6BAA6B;EAC7B,kBCjIQ;EDkIR,WClIQ;AVw+BhB;;AS9/BA;EA6JU,sBCvIM;EDwIN,cVtMwB;AC2iClC;;ASngCA;EAqKc,gEAA8D;ATk2B5E;;ASvgCA;;EAwKU,6BAA6B;EAC7B,kBCnJM;EDoJN,gBAAgB;EAChB,WCrJM;AVy/BhB;;AS/gCA;EAiLU,yBCpJsC;EDqJtC,cC7I2D;AV++BrE;;ASphCA;EAqLY,yBCrIqB;EDsIrB,yBAAyB;EACzB,cClJyD;AVq/BrE;;AS1hCA;EA0LY,yBC1IqB;ED2IrB,yBAAyB;EACzB,cCvJyD;AV2/BrE;;AShiCA;EAoFM,yBV1H4B;EU2H5B,yBAAyB;EACzB,WChEU;AVghChB;;AStiCA;EAyFQ,yBCzCyB;ED0CzB,yBAAyB;EACzB,WCrEQ;AVshChB;;AS5iCA;EA8FQ,yBAAyB;EACzB,WCzEQ;AV2hChB;;ASjjCA;EAiGU,iDVvIwB;AC2lClC;;ASrjCA;EAoGQ,yBCpDyB;EDqDzB,yBAAyB;EACzB,WChFQ;AVqiChB;;AS3jCA;;EAyGQ,yBV/I0B;EUgJ1B,qBVhJ0B;EUiJ1B,gBAAgB;ATu9BxB;;ASlkCA;EA6GQ,sBCvFQ;EDwFR,cVpJ0B;AC6mClC;;ASvkCA;EAiHU,yBCjEuB;AV2hCjC;;AS3kCA;;EAoHU,sBC9FM;ED+FN,yBAAyB;EACzB,gBAAgB;EAChB,cV7JwB;ACynClC;;ASnlCA;EA0HU,0DAA4E;AT69BtF;;ASvlCA;EA4HQ,6BAA6B;EAC7B,qBVnK0B;EUoK1B,cVpK0B;ACmoClC;;AS7lCA;EAmIU,yBVzKwB;EU0KxB,qBV1KwB;EU2KxB,WC/GM;AV6kChB;;ASnmCA;EAwIY,gEAA8D;AT+9B1E;;ASvmCA;EA8Ic,0DAA4E;AT69B1F;;AS3mCA;;EAiJU,6BAA6B;EAC7B,qBVxLwB;EUyLxB,gBAAgB;EAChB,cV1LwB;ACypClC;;ASnnCA;EAsJQ,6BAA6B;EAC7B,kBCjIQ;EDkIR,WClIQ;AVmmChB;;ASznCA;EA6JU,sBCvIM;EDwIN,cVpMwB;ACoqClC;;AS9nCA;EAqKc,gEAA8D;AT69B5E;;ASloCA;;EAwKU,6BAA6B;EAC7B,kBCnJM;EDoJN,gBAAgB;EAChB,WCrJM;AVonChB;;AS1oCA;EAiLU,yBCpJsC;EDqJtC,cC7I2D;AV0mCrE;;AS/oCA;EAqLY,yBCrIqB;EDsIrB,yBAAyB;EACzB,cClJyD;AVgnCrE;;ASrpCA;EA0LY,yBC1IqB;ED2IrB,yBAAyB;EACzB,cCvJyD;AVsnCrE;;AS3pCA;EAoFM,yBV3H4B;EU4H5B,yBAAyB;EACzB,WChEU;AV2oChB;;ASjqCA;EAyFQ,yBCzCyB;ED0CzB,yBAAyB;EACzB,WCrEQ;AVipChB;;ASvqCA;EA8FQ,yBAAyB;EACzB,WCzEQ;AVspChB;;AS5qCA;EAiGU,kDVxIwB;ACutClC;;AShrCA;EAoGQ,yBCpDyB;EDqDzB,yBAAyB;EACzB,WChFQ;AVgqChB;;AStrCA;;EAyGQ,yBVhJ0B;EUiJ1B,qBVjJ0B;EUkJ1B,gBAAgB;ATklCxB;;AS7rCA;EA6GQ,sBCvFQ;EDwFR,cVrJ0B;ACyuClC;;ASlsCA;EAiHU,yBCjEuB;AVspCjC;;AStsCA;;EAoHU,sBC9FM;ED+FN,yBAAyB;EACzB,gBAAgB;EAChB,cV9JwB;ACqvClC;;AS9sCA;EA0HU,0DAA4E;ATwlCtF;;ASltCA;EA4HQ,6BAA6B;EAC7B,qBVpK0B;EUqK1B,cVrK0B;AC+vClC;;ASxtCA;EAmIU,yBV1KwB;EU2KxB,qBV3KwB;EU4KxB,WC/GM;AVwsChB;;AS9tCA;EAwIY,gEAA8D;AT0lC1E;;ASluCA;EA8Ic,0DAA4E;ATwlC1F;;AStuCA;;EAiJU,6BAA6B;EAC7B,qBVzLwB;EU0LxB,gBAAgB;EAChB,cV3LwB;ACqxClC;;AS9uCA;EAsJQ,6BAA6B;EAC7B,kBCjIQ;EDkIR,WClIQ;AV8tChB;;ASpvCA;EA6JU,sBCvIM;EDwIN,cVrMwB;ACgyClC;;ASzvCA;EAqKc,gEAA8D;ATwlC5E;;AS7vCA;;EAwKU,6BAA6B;EAC7B,kBCnJM;EDoJN,gBAAgB;EAChB,WCrJM;AV+uChB;;ASrwCA;EAiLU,yBCpJsC;EDqJtC,cC7I2D;AVquCrE;;AS1wCA;EAqLY,yBCrIqB;EDsIrB,yBAAyB;EACzB,cClJyD;AV2uCrE;;AShxCA;EA0LY,yBC1IqB;ED2IrB,yBAAyB;EACzB,cCvJyD;AVivCrE;;AStxCA;EAoFM,yBV7H4B;EU8H5B,yBAAyB;EACzB,WChEU;AVswChB;;AS5xCA;EAyFQ,yBCzCyB;ED0CzB,yBAAyB;EACzB,WCrEQ;AV4wChB;;ASlyCA;EA8FQ,yBAAyB;EACzB,WCzEQ;AVixChB;;ASvyCA;EAiGU,kDV1IwB;ACo1ClC;;AS3yCA;EAoGQ,yBCpDyB;EDqDzB,yBAAyB;EACzB,WChFQ;AV2xChB;;ASjzCA;;EAyGQ,yBVlJ0B;EUmJ1B,qBVnJ0B;EUoJ1B,gBAAgB;AT6sCxB;;ASxzCA;EA6GQ,sBCvFQ;EDwFR,cVvJ0B;ACs2ClC;;AS7zCA;EAiHU,yBCjEuB;AVixCjC;;ASj0CA;;EAoHU,sBC9FM;ED+FN,yBAAyB;EACzB,gBAAgB;EAChB,cVhKwB;ACk3ClC;;ASz0CA;EA0HU,0DAA4E;ATmtCtF;;AS70CA;EA4HQ,6BAA6B;EAC7B,qBVtK0B;EUuK1B,cVvK0B;AC43ClC;;ASn1CA;EAmIU,yBV5KwB;EU6KxB,qBV7KwB;EU8KxB,WC/GM;AVm0ChB;;ASz1CA;EAwIY,gEAA8D;ATqtC1E;;AS71CA;EA8Ic,0DAA4E;ATmtC1F;;ASj2CA;;EAiJU,6BAA6B;EAC7B,qBV3LwB;EU4LxB,gBAAgB;EAChB,cV7LwB;ACk5ClC;;ASz2CA;EAsJQ,6BAA6B;EAC7B,kBCjIQ;EDkIR,WClIQ;AVy1ChB;;AS/2CA;EA6JU,sBCvIM;EDwIN,cVvMwB;AC65ClC;;ASp3CA;EAqKc,gEAA8D;ATmtC5E;;ASx3CA;;EAwKU,6BAA6B;EAC7B,kBCnJM;EDoJN,gBAAgB;EAChB,WCrJM;AV02ChB;;ASh4CA;EAiLU,yBCpJsC;EDqJtC,cC7I2D;AVg2CrE;;ASr4CA;EAqLY,yBCrIqB;EDsIrB,yBAAyB;EACzB,cClJyD;AVs2CrE;;AS34CA;EA0LY,yBC1IqB;ED2IrB,yBAAyB;EACzB,cCvJyD;AV42CrE;;ASj5CA;EAoFM,yBV9H4B;EU+H5B,yBAAyB;EACzB,yBClEe;AVm4CrB;;ASv5CA;EAyFQ,yBCzCyB;ED0CzB,yBAAyB;EACzB,yBCvEa;AVy4CrB;;AS75CA;EA8FQ,yBAAyB;EACzB,yBC3Ea;AV84CrB;;ASl6CA;EAiGU,mDV3IwB;ACg9ClC;;ASt6CA;EAoGQ,yBCpDyB;EDqDzB,yBAAyB;EACzB,yBClFa;AVw5CrB;;AS56CA;;EAyGQ,yBVnJ0B;EUoJ1B,qBVpJ0B;EUqJ1B,gBAAgB;ATw0CxB;;ASn7CA;EA6GQ,oCCzFa;ED0Fb,cVxJ0B;ACk+ClC;;ASx7CA;EAiHU,oCCjEuB;AV44CjC;;AS57CA;;EAoHU,oCChGW;EDiGX,yBAAyB;EACzB,gBAAgB;EAChB,cVjKwB;AC8+ClC;;ASp8CA;EA0HU,sFAA4E;AT80CtF;;ASx8CA;EA4HQ,6BAA6B;EAC7B,qBVvK0B;EUwK1B,cVxK0B;ACw/ClC;;AS98CA;EAmIU,yBV7KwB;EU8KxB,qBV9KwB;EU+KxB,yBCjHW;AVg8CrB;;ASp9CA;EAwIY,gEAA8D;ATg1C1E;;ASx9CA;EA8Ic,sFAA4E;AT80C1F;;AS59CA;;EAiJU,6BAA6B;EAC7B,qBV5LwB;EU6LxB,gBAAgB;EAChB,cV9LwB;AC8gDlC;;ASp+CA;EAsJQ,6BAA6B;EAC7B,gCCnIa;EDoIb,yBCpIa;AVs9CrB;;AS1+CA;EA6JU,oCCzIW;ED0IX,cVxMwB;ACyhDlC;;AS/+CA;EAqKc,gEAA8D;AT80C5E;;ASn/CA;;EAwKU,6BAA6B;EAC7B,gCCrJW;EDsJX,gBAAgB;EAChB,yBCvJW;AVu+CrB;;AS3/CA;EAiLU,yBCpJsC;EDqJtC,cC7I2D;AV29CrE;;AShgDA;EAqLY,yBCrIqB;EDsIrB,yBAAyB;EACzB,cClJyD;AVi+CrE;;AStgDA;EA0LY,yBC1IqB;ED2IrB,yBAAyB;EACzB,cCvJyD;AVu+CrE;;AS5gDA;EAoFM,yBVxH2B;EUyH3B,yBAAyB;EACzB,WChEU;AV4/ChB;;ASlhDA;EAyFQ,yBCzCyB;ED0CzB,yBAAyB;EACzB,WCrEQ;AVkgDhB;;ASxhDA;EA8FQ,yBAAyB;EACzB,WCzEQ;AVugDhB;;AS7hDA;EAiGU,kDVrIuB;ACqkDjC;;ASjiDA;EAoGQ,yBCpDyB;EDqDzB,yBAAyB;EACzB,WChFQ;AVihDhB;;ASviDA;;EAyGQ,yBV7IyB;EU8IzB,qBV9IyB;EU+IzB,gBAAgB;ATm8CxB;;AS9iDA;EA6GQ,sBCvFQ;EDwFR,cVlJyB;ACulDjC;;ASnjDA;EAiHU,yBCjEuB;AVugDjC;;ASvjDA;;EAoHU,sBC9FM;ED+FN,yBAAyB;EACzB,gBAAgB;EAChB,cV3JuB;ACmmDjC;;AS/jDA;EA0HU,0DAA4E;ATy8CtF;;ASnkDA;EA4HQ,6BAA6B;EAC7B,qBVjKyB;EUkKzB,cVlKyB;AC6mDjC;;ASzkDA;EAmIU,yBVvKuB;EUwKvB,qBVxKuB;EUyKvB,WC/GM;AVyjDhB;;AS/kDA;EAwIY,gEAA8D;AT28C1E;;ASnlDA;EA8Ic,0DAA4E;ATy8C1F;;ASvlDA;;EAiJU,6BAA6B;EAC7B,qBVtLuB;EUuLvB,gBAAgB;EAChB,cVxLuB;ACmoDjC;;AS/lDA;EAsJQ,6BAA6B;EAC7B,kBCjIQ;EDkIR,WClIQ;AV+kDhB;;ASrmDA;EA6JU,sBCvIM;EDwIN,cVlMuB;AC8oDjC;;AS1mDA;EAqKc,gEAA8D;ATy8C5E;;AS9mDA;;EAwKU,6BAA6B;EAC7B,kBCnJM;EDoJN,gBAAgB;EAChB,WCrJM;AVgmDhB;;AStnDA;EAiLU,yBCpJsC;EDqJtC,cC7I2D;AVslDrE;;AS3nDA;EAqLY,yBCrIqB;EDsIrB,yBAAyB;EACzB,cClJyD;AV4lDrE;;ASjoDA;EA0LY,yBC1IqB;ED2IrB,yBAAyB;EACzB,cCvJyD;AVkmDrE;;ASvoDA;EARE,kBVdc;ACiqDhB;;ASrpDE;EACE,kBVkBc;ACsoDlB;;AS/oDA;EANE,eVjBW;AC0qDb;;ASnpDA;EAJE,kBVpBc;AC+qDhB;;ASvpDA;EAFE,iBVvBa;ACorDf;;AS3pDA;;EAyMI,uBVtP2B;EUuP3B,qBV5P0B;EU6P1B,gBAjOyB;EAkOzB,YAjOyB;ATwrD7B;;ASnqDA;EA8MI,aAAa;EACb,WAAW;ATy9Cf;;ASxqDA;EAiNI,6BAA6B;EAC7B,oBAAoB;AT29CxB;;AS7qDA;ERnDE,kBAAkB;EAKhB,6BAAmC;EACnC,4BAAkC;EQmQhC,6BAA6B;AT89CnC;;ASprDA;EAwNI,4BVvQ0B;EUwQ1B,qBV3Q0B;EU4Q1B,cV9Q0B;EU+Q1B,gBAAgB;EAChB,oBAAoB;ATg+CxB;;AS5rDA;EA8NI,qBVlNmB;EUmNnB,gCAA0D;EAC1D,iCAA2D;ATk+C/D;;ASh+CA;EACE,mBAAmB;EACnB,aAAa;EACb,eAAe;EACf,2BAA2B;ATm+C7B;;ASv+CA;EAMI,qBAAqB;ATq+CzB;;AS3+CA;ER1GI,oBQkHwC;ATu+C5C;;AS/+CA;EAUI,sBAAsB;ATy+C1B;;ASn/CA;EAYI,mBAAmB;AT2+CvB;;ASv/CA;EA1OE,kBVdc;ACmvDhB;;ASvuDE;EACE,kBVkBc;ACwtDlB;;AS//CA;EAtOE,kBVpBc;AC6vDhB;;ASngDA;EApOE,iBVvBa;ACkwDf;;ASvgDA;EA0BQ,4BAA4B;EAC5B,yBAAyB;ATi/CjC;;AS5gDA;EA6BQ,6BAA6B;EAC7B,0BAA0B;ERxI9B,kBQyIwC;ATm/C5C;;ASlhDA;ER1GI,eQ2IqC;ATq/CzC;;ASthDA;EAoCQ,UAAU;ATs/ClB;;AS1hDA;EA0CQ,UAAU;ATo/ClB;;AS9hDA;EA4CU,UAAU;ATs/CpB;;ASliDA;EA8CQ,YAAY;EACZ,cAAc;ATw/CtB;;ASviDA;EAiDI,uBAAuB;AT0/C3B;;AS3iDA;EAoDQ,oBAAoB;EACpB,qBAAqB;AT2/C7B;;AShjDA;EAuDI,yBAAyB;AT6/C7B;;ASpjDA;EA0DQ,oBAAoB;EACpB,qBAAqB;AT8/C7B;;ACzvDE;EQiQM;IACE,oBAlTyD;ET8yDjE;ES1/CM;;IAEE,qBAtT0F;ETkzDlG;ESjgDM;IACE,kBV1TM;EC6zDd;ESpgDM;IACE,eV3TG;ECi0DX;AACF;;ACrwDE;EQ6PM;IACE,qBAlTyL;ET8zDjM;ES1gDM;;IAEE,kBV9TM;EC00Dd;ESjhDM;IACE,eV3TG;EC80DX;ESphDM;IACE,kBV5TM;ECk1Dd;AACF;;AWl3DA;EACE,YAAY;EACZ,cAAc;EACd,kBAAkB;EAClB,WAAW;AXq3Db;;AWz3DA;EAMI,0BAA0B;EAC1B,kBZyCM;EYxCN,mBZwCM;EYvCN,WAAW;AXu3Df;;AC/wDE;EUjHF;IAWI,gBAAuC;EX03DzC;AACF;;AC3wDI;EU3HJ;IAcM,iBAAqE;EX63DzE;AACF;;AClwDI;EU1IJ;IAiBM,iBAAiE;EXg4DrE;AACF;;AClxDI;EUhIJ;IAoBM,iBAAqE;EXm4DzE;AACF;;ACzwDI;EU/IJ;IAuBM,iBAAiE;EXs4DrE;AACF;;AY34DA;EAII,kBAAkB;AZ24DtB;;AY/4DA;;;;;;;EAcM,kBAhC2B;AZ26DjC;;AYz5DA;;;;;;EAqBI,cbvC0B;EawC1B,gBbHiB;EaIjB,kBA3C+B;AZw7DnC;;AYp6DA;EAyBI,cAAc;EACd,oBAAoB;AZ+4DxB;;AYz6DA;EA4BM,eAAe;AZi5DrB;;AY76DA;EA8BI,iBAAiB;EACjB,uBAAuB;AZm5D3B;;AYl7DA;EAiCM,oBAAoB;AZq5D1B;;AYt7DA;EAmCI,gBAAgB;EAChB,uBAAuB;AZu5D3B;;AY37DA;EAsCM,oBAAoB;AZy5D1B;;AY/7DA;EAwCI,iBAAiB;EACjB,oBAAoB;AZ25DxB;;AYp8DA;EA2CI,kBAAkB;EAClB,uBAAuB;AZ65D3B;;AYz8DA;EA8CI,cAAc;EACd,kBAAkB;AZ+5DtB;;AY98DA;EAiDI,4Bb5D0B;EEuK1B,8BF1K0B;EaiE1B,qBAjEqC;AZk+DzC;;AYp9DA;EAqDI,4BAA4B;EXuG5B,gBWtGmC;EACnC,eAAe;AZm6DnB;;AY19DA;EAyDM,wBAAwB;AZq6D9B;;AY99DA;EA2DQ,4BAA4B;AZu6DpC;;AYl+DA;EA6DQ,4BAA4B;AZy6DpC;;AYt+DA;EA+DQ,4BAA4B;AZ26DpC;;AY1+DA;EAiEQ,4BAA4B;AZ66DpC;;AY9+DA;EAmEI,wBAAwB;EXyFxB,gBWxFmC;EACnC,eAAe;AZ+6DnB;;AYp/DA;EAuEM,uBAAuB;EACvB,iBAAiB;AZi7DvB;;AYz/DA;EA0EQ,uBAAuB;AZm7D/B;;AY7/DA;EX4JI,gBWhFmC;AZq7DvC;;AYjgEA;EA8EI,gBAAgB;EAChB,iBAAiB;EACjB,kBAAkB;AZu7DtB;;AYvgEA;EAkFM,eAAe;AZy7DrB;;AY3gEA;EAoFM,kBAAkB;AZ27DxB;;AY/gEA;EAsFM,qBAAqB;AZ67D3B;;AYnhEA;EAwFM,kBAAkB;AZ+7DxB;;AYvhEA;EX2CE,iCAAiC;EWgD/B,gBAAgB;EAChB,qBAxG8B;EAyG9B,gBAAgB;EAChB,iBAAiB;AZi8DrB;;AY/hEA;;EAiGI,cAAc;AZm8DlB;;AYpiEA;EAmGI,WAAW;AZq8Df;;AYxiEA;;EAsGM,yBbpHwB;EaqHxB,qBAhHmC;EAiHnC,qBAhHmC;EAiHnC,mBAAmB;AZu8DzB;;AYhjEA;EA2GM,cb7HwB;ACskE9B;;AYpjEA;EA6GQ,mBAAmB;AZ28D3B;;AYxjEA;;EAiHQ,qBAvHsC;EAwHtC,cbpIsB;ACglE9B;;AY9jEA;;EAsHQ,qBAzHsC;EA0HtC,cbzIsB;ACslE9B;;AYpkEA;;EA6HY,sBAjI4C;AZ6kExD;;AYzkEA;EAgIM,aAAa;AZ68DnB;;AY7kEA;EAmII,kBbrHY;ACmkEhB;;AYjlEA;EAqII,ebxHS;ACwkEb;;AYrlEA;EAuII,kBb3HY;AC6kEhB;;AYzlEA;EAyII,iBb9HW;ACklEf;;Aa/mEA;EACE,mBAAmB;EACnB,oBAAoB;EACpB,uBAAuB;EACvB,cAVsB;EAWtB,aAXsB;Ab6nExB;;AavnEA;EAQI,YAbwB;EAcxB,WAdwB;AbioE5B;;Aa5nEA;EAWI,YAfyB;EAgBzB,WAhByB;AbqoE7B;;AajoEA;EAcI,YAjBwB;EAkBxB,WAlBwB;AbyoE5B;;AarnEA;EACE,uBAAuB;EACvB,cAAc;EACd,oBAAoB;EACpB,eAAe;EACf,mBA5BsB;EA6BtB,mBAAmB;AbwnErB;;Aa9nEA;EAQI,YAAY;EACZ,cAAc;Ab0nElB;;AanoEA;EAYQ,oBA/BkB;Ab0pE1B;;AavoEA;EAiBQ,mBApCkB;Ab8pE1B;;AatnEA;EACE,aAAa;AbynEf;;AclqEA;EACE,cAAc;EACd,kBAAkB;AdqqEpB;;AcvqEA;EAII,cAAc;EACd,YAAY;EACZ,WAAW;AduqEf;;Ac7qEA;EAQM,qBf4DiB;AC6mEvB;;AcjrEA;EAUI,WAAW;Ad2qEf;;AcrrEA;;;;;;;;;;;;;;;;;EA+BM,YAAY;EACZ,WAAW;Ad0qEjB;;Ac1sEA;EAmCI,iBAAiB;Ad2qErB;;Ac9sEA;EAqCI,gBAAgB;Ad6qEpB;;AcltEA;EAuCI,gBAAgB;Ad+qEpB;;ActtEA;EAyCI,qBAAqB;AdirEzB;;Ac1tEA;EA2CI,gBAAgB;AdmrEpB;;Ac9tEA;EA6CI,mBAAmB;AdqrEvB;;AcluEA;EA+CI,gBAAgB;AdurEpB;;ActuEA;EAiDI,qBAAqB;AdyrEzB;;Ac1uEA;EAmDI,iBAAiB;Ad2rErB;;Ac9uEA;EAqDI,sBAAsB;Ad6rE1B;;AclvEA;EAuDI,iBAAiB;Ad+rErB;;ActvEA;EAyDI,sBAAsB;AdisE1B;;Ac1vEA;EA2DI,sBAAsB;AdmsE1B;;Ac9vEA;EA6DI,iBAAiB;AdqsErB;;AclwEA;EA+DI,iBAAiB;AdusErB;;ActwEA;EAmEM,YAAwB;EACxB,WAAuB;AdusE7B;;Ac3wEA;EAmEM,YAAwB;EACxB,WAAuB;Ad4sE7B;;AchxEA;EAmEM,YAAwB;EACxB,WAAuB;AditE7B;;AcrxEA;EAmEM,YAAwB;EACxB,WAAuB;AdstE7B;;Ac1xEA;EAmEM,YAAwB;EACxB,WAAuB;Ad2tE7B;;Ac/xEA;EAmEM,YAAwB;EACxB,WAAuB;AdguE7B;;AcpyEA;EAmEM,aAAwB;EACxB,YAAuB;AdquE7B;;AelyEA;EAEE,4BhBA4B;EgBC5B,kBhBwDU;EgBvDV,kBAAkB;EAEhB,sCAXoD;Af8yExD;;AezyEA;EAUI,mBAAmB;EACnB,0BAA0B;AfmyE9B;;Ae9yEA;EAaI,mBAAmB;AfqyEvB;;AelzEA;;EAgBI,iBhBZ2B;ACmzE/B;;AevzEA;EAkBI,uBAAuB;AfyyE3B;;Ae3zEA;EdiLI,ac7J4B;EAC5B,kBAAkB;EAClB,WAAW;Af2yEf;;Aej0EA;;;EA0BI,mBAAmB;Af6yEvB;;Aev0EA;EAgCM,uBhB5ByB;EgB6BzB,chB1CuB;ACq1E7B;;Ae50EA;EAgCM,yBhBzCuB;EgB0CvB,YhB7ByB;AC60E/B;;Aej1EA;EAgCM,4BhB9BwB;EgB+BxB,yBLoCe;AVixErB;;Aet1EA;EAgCM,yBhBrCwB;EgBsCxB,WLsCU;AVoxEhB;;Ae31EA;EAgCM,yBhBvB4B;EgBwB5B,WLsCU;AVyxEhB;;Aeh2EA;EAuCU,yBLuCsC;EKtCtC,cL8C2D;AV+wErE;;Aer2EA;EAgCM,yBhBrB4B;EgBsB5B,WLsCU;AVmyEhB;;Ae12EA;EAuCU,yBLuCsC;EKtCtC,cL8C2D;AVyxErE;;Ae/2EA;EAgCM,yBhBtB4B;EgBuB5B,WLsCU;AV6yEhB;;Aep3EA;EAuCU,yBLuCsC;EKtCtC,cL8C2D;AVmyErE;;Aez3EA;EAgCM,yBhBxB4B;EgByB5B,WLsCU;AVuzEhB;;Ae93EA;EAuCU,yBLuCsC;EKtCtC,cL8C2D;AV6yErE;;Aen4EA;EAgCM,yBhBzB4B;EgB0B5B,yBLoCe;AVm0ErB;;Aex4EA;EAuCU,yBLuCsC;EKtCtC,cL8C2D;AVuzErE;;Ae74EA;EAgCM,yBhBnB2B;EgBoB3B,WLsCU;AV20EhB;;Ael5EA;EAuCU,yBLuCsC;EKtCtC,cL8C2D;AVi0ErE;;AgBx5EA;EAEE,qBAAqB;EACrB,wBAAwB;EACxB,YAAY;EACZ,qBjByDqB;EiBxDrB,cAAc;EACd,YjBoBW;EiBnBX,gBAAgB;EAChB,UAAU;EACV,WAAW;AhB05Eb;;AgBp6EA;EAYI,yBjBX2B;ACu6E/B;;AgBx6EA;EAcI,yBjBjB0B;AC+6E9B;;AgB56EA;EAgBI,yBjBnB0B;ACm7E9B;;AgBh7EA;EAkBI,yBjBrB0B;EiBsB1B,YAAY;AhBk6EhB;;AgBr7EA;EAyBQ,uBjBpBuB;ACo7E/B;;AgBz7EA;EA2BQ,uBjBtBuB;ACw7E/B;;AgB77EA;EA6BQ,uBjBxBuB;AC47E/B;;AgBj8EA;EA+BQ,mEAA2F;AhBs6EnG;;AgBr8EA;EAyBQ,yBjBjCqB;ACi9E7B;;AgBz8EA;EA2BQ,yBjBnCqB;ACq9E7B;;AgB78EA;EA6BQ,yBjBrCqB;ACy9E7B;;AgBj9EA;EA+BQ,qEAA2F;AhBs7EnG;;AgBr9EA;EAyBQ,4BjBtBsB;ACs9E9B;;AgBz9EA;EA2BQ,4BjBxBsB;AC09E9B;;AgB79EA;EA6BQ,4BjB1BsB;AC89E9B;;AgBj+EA;EA+BQ,wEAA2F;AhBs8EnG;;AgBr+EA;EAyBQ,yBjB7BsB;AC6+E9B;;AgBz+EA;EA2BQ,yBjB/BsB;ACi/E9B;;AgB7+EA;EA6BQ,yBjBjCsB;ACq/E9B;;AgBj/EA;EA+BQ,qEAA2F;AhBs9EnG;;AgBr/EA;EAyBQ,yBjBf0B;AC++ElC;;AgBz/EA;EA2BQ,yBjBjB0B;ACm/ElC;;AgB7/EA;EA6BQ,yBjBnB0B;ACu/ElC;;AgBjgFA;EA+BQ,qEAA2F;AhBs+EnG;;AgBrgFA;EAyBQ,yBjBb0B;AC6/ElC;;AgBzgFA;EA2BQ,yBjBf0B;ACigFlC;;AgB7gFA;EA6BQ,yBjBjB0B;ACqgFlC;;AgBjhFA;EA+BQ,qEAA2F;AhBs/EnG;;AgBrhFA;EAyBQ,yBjBd0B;AC8gFlC;;AgBzhFA;EA2BQ,yBjBhB0B;ACkhFlC;;AgB7hFA;EA6BQ,yBjBlB0B;ACshFlC;;AgBjiFA;EA+BQ,qEAA2F;AhBsgFnG;;AgBriFA;EAyBQ,yBjBhB0B;ACgiFlC;;AgBziFA;EA2BQ,yBjBlB0B;ACoiFlC;;AgB7iFA;EA6BQ,yBjBpB0B;ACwiFlC;;AgBjjFA;EA+BQ,qEAA2F;AhBshFnG;;AgBrjFA;EAyBQ,yBjBjB0B;ACijFlC;;AgBzjFA;EA2BQ,yBjBnB0B;ACqjFlC;;AgB7jFA;EA6BQ,yBjBrB0B;ACyjFlC;;AgBjkFA;EA+BQ,qEAA2F;AhBsiFnG;;AgBrkFA;EAyBQ,yBjBXyB;AC2jFjC;;AgBzkFA;EA2BQ,yBjBbyB;AC+jFjC;;AgB7kFA;EA6BQ,yBjBfyB;ACmkFjC;;AgBjlFA;EA+BQ,qEAA2F;AhBsjFnG;;AgBrlFA;EAkCI,gCAtCkC;UAsClC,wBAtCkC;EAuClC,2CAAmC;UAAnC,mCAAmC;EACnC,yCAAiC;UAAjC,iCAAiC;EACjC,yCAAiC;UAAjC,iCAAiC;EACjC,yBjBrC2B;EiBsC3B,qEAA0F;EAC1F,6BAA6B;EAC7B,4BAA4B;EAC5B,0BAA0B;AhBujF9B;;AgBjmFA;EA4CM,6BAA6B;AhByjFnC;;AgBrmFA;EA8CM,6BAA6B;AhB2jFnC;;AgBzmFA;EAgDM,oBAAoB;AhB6jF1B;;AgB7mFA;EAoDI,ejBxBY;ACqlFhB;;AgBjnFA;EAsDI,ejB5BY;AC2lFhB;;AgBrnFA;EAwDI,cjB/BW;ACgmFf;;AgB/jFA;EACE;IACE,2BAA2B;EhBkkF7B;EgBjkFA;IACE,4BAA4B;EhBmkF9B;AACF;;AgBxkFA;EACE;IACE,2BAA2B;EhBkkF7B;EgBjkFA;IACE,4BAA4B;EhBmkF9B;AACF;;AiB9mFA;EAEE,uBlBjB6B;EkBkB7B,clB3B4B;AC2oF9B;;AiBnnFA;;EAMI,yBlB1B0B;EkB2B1B,qBA/B6B;EAgC7B,qBA/B6B;EAgC7B,mBAAmB;AjBknFvB;;AiB3nFA;;EAeQ,uBlB9BuB;EkB+BvB,mBlB/BuB;EkBgCvB,clB7CqB;AC8pF7B;;AiBloFA;;EAeQ,yBlB3CqB;EkB4CrB,qBlB5CqB;EkB6CrB,YlBhCuB;ACwpF/B;;AiBzoFA;;EAeQ,4BlBhCsB;EkBiCtB,wBlBjCsB;EkBkCtB,yBPiCa;AV8lFrB;;AiBhpFA;;EAeQ,yBlBvCsB;EkBwCtB,qBlBxCsB;EkByCtB,WPmCQ;AVmmFhB;;AiBvpFA;;EAeQ,yBlBzB0B;EkB0B1B,qBlB1B0B;EkB2B1B,WPmCQ;AV0mFhB;;AiB9pFA;;EAeQ,yBlBvB0B;EkBwB1B,qBlBxB0B;EkByB1B,WPmCQ;AVinFhB;;AiBrqFA;;EAeQ,yBlBxB0B;EkByB1B,qBlBzB0B;EkB0B1B,WPmCQ;AVwnFhB;;AiB5qFA;;EAeQ,yBlB1B0B;EkB2B1B,qBlB3B0B;EkB4B1B,WPmCQ;AV+nFhB;;AiBnrFA;;EAeQ,yBlB3B0B;EkB4B1B,qBlB5B0B;EkB6B1B,yBPiCa;AVwoFrB;;AiB1rFA;;EAeQ,yBlBrByB;EkBsBzB,qBlBtByB;EkBuBzB,WPmCQ;AV6oFhB;;AiBjsFA;;EAoBM,mBAAmB;EACnB,SAAS;AjBkrFf;;AiBvsFA;;EAuBM,yBlBjC4B;EkBkC5B,WP4BU;AVypFhB;;AiB7sFA;;;;EA2BQ,mBAAmB;AjByrF3B;;AiBptFA;;EA6BM,sBAAsB;AjB4rF5B;;AiBztFA;EA+BI,clBvD0B;ACqvF9B;;AiB7tFA;EAiCM,gBAtDsB;AjBsvF5B;;AiBjuFA;EAoCM,yBlB9C4B;EkB+C5B,WPeU;AVkrFhB;;AiBtuFA;;EAwCQ,mBAAmB;AjBmsF3B;;AiB3uFA;;EA2CQ,kBPSQ;EORR,mBAAmB;AjBqsF3B;;AiBjvFA;EA8CI,6BA5DqC;AjBmwFzC;;AiBrvFA;;EAiDM,qBApEgC;EAqEhC,clB1EwB;ACmxF9B;;AiB3vFA;EAoDI,6BAhEqC;AjB2wFzC;;AiB/vFA;;EAuDM,qBAxEgC;EAyEhC,clBhFwB;AC6xF9B;;AiBrwFA;EA0DI,6BAvEqC;AjBsxFzC;;AiBzwFA;;EA+DU,sBAAsB;AjB+sFhC;;AiB9wFA;;EAoEM,iBAAiB;AjB+sFvB;;AiBnxFA;;EAyEU,wBAAwB;AjB+sFlC;;AiBxxFA;EA2EI,WAAW;AjBitFf;;AiB5xFA;EAgFU,yBlBhGoB;ACgzF9B;;AiBhyFA;EAqFY,yBlBrGkB;ACozF9B;;AiBpyFA;EAuFc,4BlBxGgB;ACyzF9B;;AiBxyFA;;EA2FM,qBAAqB;AjBktF3B;;AiB7yFA;EAgGU,yBlBhHoB;ACi0F9B;;AiB/sFA;EhB7DE,iCAAiC;EgBgEjC,cAAc;EACd,kBAAkB;EAClB,eAAe;AjBitFjB;;AkB70FA;EACE,mBAAmB;EACnB,aAAa;EACb,eAAe;EACf,2BAA2B;AlBg1F7B;;AkBp1FA;EAMI,qBAAqB;AlBk1FzB;;AkBx1FA;EjB2KI,oBiBnKwC;AlBo1F5C;;AkB51FA;EAUI,sBAAsB;AlBs1F1B;;AkBh2FA;EAYI,mBAAmB;AlBw1FvB;;AkBp2FA;EAgBM,enBYO;AC40Fb;;AkBx2FA;EAmBM,kBnBQU;ACi1FhB;;AkB52FA;EAqBI,uBAAuB;AlB21F3B;;AkBh3FA;EAuBM,qBAAqB;EACrB,oBAAoB;AlB61F1B;;AkBr3FA;EA0BI,yBAAyB;AlB+1F7B;;AkBz3FA;EA6BQ,mBAAmB;AlBg2F3B;;AkB73FA;EA+BQ,eAAe;AlBk2FvB;;AkBj4FA;EjB2KI,eiBzImC;AlBm2FvC;;AkBr4FA;EjB2KI,ciBvIqC;EAE/B,yBAAyB;EACzB,4BAA4B;AlBo2FtC;;AkB34FA;EA6CU,0BAA0B;EAC1B,6BAA6B;AlBk2FvC;;AkB71FA;EACE,mBAAmB;EACnB,4BnBjD4B;EmBkD5B,kBnBOU;EmBNV,cnBzD4B;EmB0D5B,oBAAoB;EACpB,kBnB5Bc;EmB6Bd,WAAW;EACX,uBAAuB;EACvB,gBAAgB;EAChB,oBAAoB;EACpB,qBAAqB;EACrB,mBAAmB;AlBg2FrB;;AkB52FA;EjBwHI,oBiB1GuC;EjB0GvC,uBiBzGyC;AlBk2F7C;;AkBj3FA;EAqBM,uBnBlEyB;EmBmEzB,cnBhFuB;ACg7F7B;;AkBt3FA;EAqBM,yBnB/EuB;EmBgFvB,YnBnEyB;ACw6F/B;;AkB33FA;EAqBM,4BnBpEwB;EmBqExB,yBRFe;AV42FrB;;AkBh4FA;EAqBM,yBnB3EwB;EmB4ExB,WRAU;AV+2FhB;;AkBr4FA;EAqBM,yBnB7D4B;EmB8D5B,WRAU;AVo3FhB;;AkB14FA;EA4BU,yBRCsC;EQAtC,cRQ2D;AV02FrE;;AkB/4FA;EAqBM,yBnB3D4B;EmB4D5B,WRAU;AV83FhB;;AkBp5FA;EA4BU,yBRCsC;EQAtC,cRQ2D;AVo3FrE;;AkBz5FA;EAqBM,yBnB5D4B;EmB6D5B,WRAU;AVw4FhB;;AkB95FA;EA4BU,yBRCsC;EQAtC,cRQ2D;AV83FrE;;AkBn6FA;EAqBM,yBnB9D4B;EmB+D5B,WRAU;AVk5FhB;;AkBx6FA;EA4BU,yBRCsC;EQAtC,cRQ2D;AVw4FrE;;AkB76FA;EAqBM,yBnB/D4B;EmBgE5B,yBRFe;AV85FrB;;AkBl7FA;EA4BU,yBRCsC;EQAtC,cRQ2D;AVk5FrE;;AkBv7FA;EAqBM,yBnBzD2B;EmB0D3B,WRAU;AVs6FhB;;AkB57FA;EA4BU,yBRCsC;EQAtC,cRQ2D;AV45FrE;;AkBj8FA;EAgCI,kBnBtDY;AC29FhB;;AkBr8FA;EAkCI,enBzDS;ACg+Fb;;AkBz8FA;EAoCI,kBnB5DY;ACq+FhB;;AkB78FA;EjBwHI,qBiBjF0C;EjBiF1C,sBiBhF0C;AlB06F9C;;AkBl9FA;EjBwHI,qBiB9E0C;EjB8E1C,sBiB7E0C;AlB46F9C;;AkBv9FA;EjBwHI,qBiB3E0C;EjB2E1C,sBiB1E0C;AlB86F9C;;AkB59FA;EjBwHI,gBiB/KmB;EAyGnB,UAAU;EACV,kBAAkB;EAClB,UAAU;AlB+6Fd;;AkBn+FA;EAuDM,8BAA8B;EAC9B,WAAW;EACX,cAAc;EACd,SAAS;EACT,kBAAkB;EAClB,QAAQ;EACR,0DAA0D;EAC1D,+BAA+B;AlBg7FrC;;AkB9+FA;EAgEM,WAAW;EACX,UAAU;AlBk7FhB;;AkBn/FA;EAmEM,WAAW;EACX,UAAU;AlBo7FhB;;AkBx/FA;EAuEM,yBAAmD;AlBq7FzD;;AkB5/FA;EAyEM,yBAAoD;AlBu7F1D;;AkBhgGA;EA2EI,qBnB/DmB;ACw/FvB;;AkBv7FA;EAEI,0BAA0B;AlBy7F9B;;AmB/iGA;;EAGE,sBAAsB;AnBijGxB;;AmBpjGA;;;;EAMI,oBAAoB;AnBqjGxB;;AmB3jGA;;EAQI,iBApBmB;AnB4kGvB;;AmBhkGA;;EAUI,iBArBmB;AnBglGvB;;AmBrkGA;;EAYI,sBAAsB;AnB8jG1B;;AmB5jGA;EACE,cpB9B4B;EoBiC5B,epBLW;EoBMX,gBpBGmB;EoBFnB,kBAnCuB;AnBgmGzB;;AmBnkGA;EAQI,cApCwB;EAqCxB,oBApCyB;AnBmmG7B;;AmBxkGA;EAWI,oBA3B+B;AnB4lGnC;;AmB5kGA;EAgBM,epBnBO;ACmlGb;;AmBhlGA;EAgBM,iBpBlBS;ACslGf;;AmBplGA;EAgBM,epBjBO;ACylGb;;AmBxlGA;EAgBM,iBpBhBS;AC4lGf;;AmB5lGA;EAgBM,kBpBfU;AC+lGhB;;AmBhmGA;EAgBM,epBdO;ACkmGb;;AmBpmGA;EAgBM,kBpBbU;ACqmGhB;;AmBtlGA;EACE,cpB/C4B;EoBkD5B,kBpBrBc;EoBsBd,gBpBjBiB;EoBkBjB,iBA3CyB;AnBkoG3B;;AmB7lGA;EAQI,cpBvD0B;EoBwD1B,gBpBnBiB;AC4mGrB;;AmBlmGA;EAWI,oBA7C+B;AnBwoGnC;;AmBtmGA;EAgBM,epBrCO;AC+nGb;;AmB1mGA;EAgBM,iBpBpCS;ACkoGf;;AmB9mGA;EAgBM,epBnCO;ACqoGb;;AmBlnGA;EAgBM,iBpBlCS;ACwoGf;;AmBtnGA;EAgBM,kBpBjCU;AC2oGhB;;AmB1nGA;EAgBM,epBhCO;AC8oGb;;AmB9nGA;EAgBM,kBpB/BU;ACipGhB;;AoB/qGA;EACE,cAAc;EACd,eAAe;EACf,mBAAmB;EACnB,kBAAkB;EAClB,yBAAyB;ApBkrG3B;;AoB7qGA;EACE,mBAAmB;EACnB,4BrBP4B;EqBQ5B,qBrBmDqB;EqBlDrB,oBAAoB;EACpB,kBrBac;EqBZd,WAAW;EACX,uBAAuB;EACvB,oBAAoB;EACpB,gBAAgB;EAChB,uBAAuB;EACvB,kBAAkB;EAClB,mBAAmB;ApBgrGrB;;AqB9sGA,eAAA;AC0DA;EAxBE,uBvBnB6B;EuBoB7B,qBvBzB4B;EuB0B5B,kBvBkCU;EuBjCV,cvB/B4B;ACgtG9B;;AC9oGI;EqBjCA,4BvBjC0B;ACotG9B;;AClpGI;EqBjCA,4BvBjC0B;ACwtG9B;;ACtpGI;EqBjCA,4BvBjC0B;AC4tG9B;;AC1pGI;EqBjCA,4BvBjC0B;ACguG9B;;AsB9rGE;EAEE,qBvBjC0B;ACiuG9B;;AsB/rGE;EAIE,qBvBzB8B;EuB0B9B,iDvB1B8B;ACytGlC;;AsB9rGE;;;;;EAEE,4BvBtC0B;EuBuC1B,wBvBvC0B;EuBwC1B,gBAAgB;EAChB,cvB9C0B;ACkvG9B;;AClrGI;;;;;EqBhBE,+BvBhDwB;AC0vG9B;;AC1rGI;;;;;EqBhBE,+BvBhDwB;ACkwG9B;;AClsGI;;;;;EqBhBE,+BvBhDwB;AC0wG9B;;AC1sGI;;;;;EqBhBE,+BvBhDwB;ACkxG9B;;AuBpxGA;EAEE,2DxBN2B;EwBO3B,eAAe;EACf,WAAW;AvBsxGb;;AuBrxGE;EACE,gBAAgB;AvBwxGpB;;AuBpxGI;EACE,mBxBFyB;ACyxG/B;;AuBxxGK;EAMG,mDxBPuB;AC6xG/B;;AuB5xGI;EACE,qBxBfuB;AC8yG7B;;AuBhyGK;EAMG,gDxBpBqB;ACkzG7B;;AuBpyGI;EACE,wBxBJwB;AC2yG9B;;AuBxyGK;EAMG,mDxBTsB;AC+yG9B;;AuB5yGI;EACE,qBxBXwB;AC0zG9B;;AuBhzGK;EAMG,gDxBhBsB;AC8zG9B;;AuBpzGI;EACE,qBxBG4B;ACozGlC;;AuBxzGK;EAMG,iDxBF0B;ACwzGlC;;AuB5zGI;EACE,qBxBK4B;AC0zGlC;;AuBh0GK;EAMG,iDxBA0B;AC8zGlC;;AuBp0GI;EACE,qBxBI4B;ACm0GlC;;AuBx0GK;EAMG,kDxBD0B;ACu0GlC;;AuB50GI;EACE,qBxBE4B;AC60GlC;;AuBh1GK;EAMG,kDxBH0B;ACi1GlC;;AuBp1GI;EACE,qBxBC4B;ACs1GlC;;AuBx1GK;EAMG,mDxBJ0B;AC01GlC;;AuB51GI;EACE,qBxBO2B;ACw1GjC;;AuBh2GK;EAMG,kDxBEyB;AC41GjC;;AuB51GE;EzBmBA,kBC0BgB;EDzBhB,kBCNc;ACm1GhB;;AuB/1GE;EzBoBA,kBCVc;ACy1GhB;;AuBj2GE;EzBoBA,iBCba;AC81Gf;;AuBl2GE;EACE,cAAc;EACd,WAAW;AvBq2Gf;;AuBp2GE;EACE,eAAe;EACf,WAAW;AvBu2Gf;;AuBr2GA;EAGI,qBxB+BmB;EwB9BnB,gDAA4D;EAC5D,iDAA6D;AvBs2GjE;;AuB32GA;EAOI,6BAA6B;EAC7B,yBAAyB;EACzB,gBAAgB;EAChB,eAAe;EACf,gBAAgB;AvBw2GpB;;AuBt2GA;EAEE,cAAc;EACd,eAAe;EACf,eAAe;EACf,2BzB7CkE;EyB8ClE,gBAAgB;AvBw2GlB;;AuB92GA;EAQI,gBA1DsB;EA2DtB,eA1DqB;AvBo6GzB;;AuBn3GA;EAWI,eAAe;AvB42GnB;;AuBv3GA;EAcI,YAAY;AvB62GhB;;AwB96GA;EACE,eAAe;EACf,qBAAqB;EACrB,iBAAiB;EACjB,kBAAkB;AxBi7GpB;;AwBh7GE;EACE,eAAe;AxBm7GnB;;AwBl7GE;EACE,czBF0B;ACu7G9B;;AwBp7GE;;;;;EAGE,czBJ0B;EyBK1B,mBAAmB;AxBy7GvB;;AwBp7GA;EvBkKI,kBuB/JqC;AxBq7GzC;;AyBx8GA;EACE,qBAAqB;EACrB,eAAe;EACf,kBAAkB;EAClB,mBAAmB;AzB28GrB;;AyB/8GA;EAMI,a3BDkB;AE88GtB;;AyBn9GA;EAUM,qB1BU4B;EEsK9B,cwB/K+B;EAC7B,UAAU;AzB68GhB;;AyBz9GA;EAeM,qB1BuDiB;EE4GnB,iBwBlKsC;AzB88G1C;;AyB99GA;EAmBI,eAAe;EACf,cAAc;EACd,cAAc;EACd,eAAe;EACf,aAAa;AzB+8GjB;;AyBt+GA;EAyBM,aAAa;AzBi9GnB;;AyB1+GA;;EA4BM,wB1BjBwB;ACo+G9B;;AyB/+GA;ExBkLI,oBwBpJwC;AzBq9G5C;;AyBn/GA;EAgCM,YAAY;EACZ,UAAU;AzBu9GhB;;AyBx/GA;EAmCQ,kBAAkB;AzBy9G1B;;AyB5/GA;EAuCM,qB1BnCwB;AC4/G9B;;AyBhgHA;EA6CQ,mB1BhCuB;ACu/G/B;;AyBpgHA;EA+CQ,mB1BlCuB;AC2/G/B;;AyBxgHA;EAkDU,qBfwDuB;AVk6GjC;;AyB5gHA;EAuDU,mD1B1CqB;ACmgH/B;;AyBhhHA;EA6CQ,qB1B7CqB;ACohH7B;;AyBphHA;EA+CQ,qB1B/CqB;ACwhH7B;;AyBxhHA;EAkDU,mBfwDuB;AVk7GjC;;AyB5hHA;EAuDU,gD1BvDmB;ACgiH7B;;AyBhiHA;EA6CQ,wB1BlCsB;ACyhH9B;;AyBpiHA;EA+CQ,wB1BpCsB;AC6hH9B;;AyBxiHA;EAkDU,qBfwDuB;AVk8GjC;;AyB5iHA;EAuDU,mD1B5CoB;ACqiH9B;;AyBhjHA;EA6CQ,qB1BzCsB;ACgjH9B;;AyBpjHA;EA+CQ,qB1B3CsB;ACojH9B;;AyBxjHA;EAkDU,qBfwDuB;AVk9GjC;;AyB5jHA;EAuDU,gD1BnDoB;AC4jH9B;;AyBhkHA;EA6CQ,qB1B3B0B;ACkjHlC;;AyBpkHA;EA+CQ,qB1B7B0B;ACsjHlC;;AyBxkHA;EAkDU,qBfwDuB;AVk+GjC;;AyB5kHA;EAuDU,iD1BrCwB;AC8jHlC;;AyBhlHA;EA6CQ,qB1BzB0B;ACgkHlC;;AyBplHA;EA+CQ,qB1B3B0B;ACokHlC;;AyBxlHA;EAkDU,qBfwDuB;AVk/GjC;;AyB5lHA;EAuDU,iD1BnCwB;AC4kHlC;;AyBhmHA;EA6CQ,qB1B1B0B;ACilHlC;;AyBpmHA;EA+CQ,qB1B5B0B;ACqlHlC;;AyBxmHA;EAkDU,qBfwDuB;AVkgHjC;;AyB5mHA;EAuDU,kD1BpCwB;AC6lHlC;;AyBhnHA;EA6CQ,qB1B5B0B;ACmmHlC;;AyBpnHA;EA+CQ,qB1B9B0B;ACumHlC;;AyBxnHA;EAkDU,qBfwDuB;AVkhHjC;;AyB5nHA;EAuDU,kD1BtCwB;AC+mHlC;;AyBhoHA;EA6CQ,qB1B7B0B;AConHlC;;AyBpoHA;EA+CQ,qB1B/B0B;ACwnHlC;;AyBxoHA;EAkDU,qBfwDuB;AVkiHjC;;AyB5oHA;EAuDU,mD1BvCwB;ACgoHlC;;AyBhpHA;EA6CQ,qB1BvByB;AC8nHjC;;AyBppHA;EA+CQ,qB1BzByB;ACkoHjC;;AyBxpHA;EAkDU,qBfwDuB;AVkjHjC;;AyB5pHA;EAuDU,kD1BjCuB;AC0oHjC;;AyBhqHA;E3ByCE,kBC0BgB;EDzBhB,kBCNc;ACioHhB;;AyBrqHA;E3B4CE,kBCVc;ACuoHhB;;AyBzqHA;E3B8CE,iBCba;AC4oHf;;AyB7qHA;EAkEM,gCAA8C;EAC9C,YAAY;AzB+mHlB;;AyBlrHA;EAqEI,WAAW;AzBinHf;;AyBtrHA;EAuEM,WAAW;AzBmnHjB;;AyB1rHA;EA2EM,aAAa;EACb,kBAAkB;ExB8GpB,cwB7G+B;EAC7B,YAAY;EACZ,eAAe;AzBmnHrB;;AyBlsHA;EAiFM,kB1B7CU;ACkqHhB;;AyBtsHA;EAmFM,kB1BjDU;ACwqHhB;;AyB1sHA;EAqFM,iB1BpDS;AC6qHf;;A0BjsHA;EAEE,oBAAoB;EACpB,aAAa;EACb,2BAA2B;EAC3B,kBAAkB;A1BmsHpB;;A0BxsHA;EAYQ,uB3BZuB;E2BavB,yBAAyB;EACzB,c3B3BqB;AC2tH7B;;A0B9sHA;EAkBU,yBhB2EuB;EgB1EvB,yBAAyB;EACzB,c3BjCmB;ACiuH7B;;A0BptHA;EAwBU,yBAAyB;EACzB,+C3BzBqB;E2B0BrB,c3BvCmB;ACuuH7B;;A0B1tHA;EA8BU,yBhB+DuB;EgB9DvB,yBAAyB;EACzB,c3B7CmB;AC6uH7B;;A0BhuHA;EAYQ,yB3BzBqB;E2B0BrB,yBAAyB;EACzB,Y3BduB;ACsuH/B;;A0BtuHA;EAkBU,yBhB2EuB;EgB1EvB,yBAAyB;EACzB,Y3BpBqB;AC4uH/B;;A0B5uHA;EAwBU,yBAAyB;EACzB,4C3BtCmB;E2BuCnB,Y3B1BqB;ACkvH/B;;A0BlvHA;EA8BU,uBhB+DuB;EgB9DvB,yBAAyB;EACzB,Y3BhCqB;ACwvH/B;;A0BxvHA;EAYQ,4B3BdsB;E2BetB,yBAAyB;EACzB,yBhBmDa;AV6rHrB;;A0B9vHA;EAkBU,yBhB2EuB;EgB1EvB,yBAAyB;EACzB,yBhB6CW;AVmsHrB;;A0BpwHA;EAwBU,yBAAyB;EACzB,+C3B3BoB;E2B4BpB,yBhBuCW;AVysHrB;;A0B1wHA;EA8BU,yBhB+DuB;EgB9DvB,yBAAyB;EACzB,yBhBiCW;AV+sHrB;;A0BhxHA;EAYQ,yB3BrBsB;E2BsBtB,yBAAyB;EACzB,WhBqDQ;AVmtHhB;;A0BtxHA;EAkBU,yBhB2EuB;EgB1EvB,yBAAyB;EACzB,WhB+CM;AVytHhB;;A0B5xHA;EAwBU,yBAAyB;EACzB,4C3BlCoB;E2BmCpB,WhByCM;AV+tHhB;;A0BlyHA;EA8BU,yBhB+DuB;EgB9DvB,yBAAyB;EACzB,WhBmCM;AVquHhB;;A0BxyHA;EAYQ,yB3BP0B;E2BQ1B,yBAAyB;EACzB,WhBqDQ;AV2uHhB;;A0B9yHA;EAkBU,yBhB2EuB;EgB1EvB,yBAAyB;EACzB,WhB+CM;AVivHhB;;A0BpzHA;EAwBU,yBAAyB;EACzB,6C3BpBwB;E2BqBxB,WhByCM;AVuvHhB;;A0B1zHA;EA8BU,yBhB+DuB;EgB9DvB,yBAAyB;EACzB,WhBmCM;AV6vHhB;;A0Bh0HA;EAYQ,yB3BL0B;E2BM1B,yBAAyB;EACzB,WhBqDQ;AVmwHhB;;A0Bt0HA;EAkBU,yBhB2EuB;EgB1EvB,yBAAyB;EACzB,WhB+CM;AVywHhB;;A0B50HA;EAwBU,yBAAyB;EACzB,6C3BlBwB;E2BmBxB,WhByCM;AV+wHhB;;A0Bl1HA;EA8BU,yBhB+DuB;EgB9DvB,yBAAyB;EACzB,WhBmCM;AVqxHhB;;A0Bx1HA;EAYQ,yB3BN0B;E2BO1B,yBAAyB;EACzB,WhBqDQ;AV2xHhB;;A0B91HA;EAkBU,yBhB2EuB;EgB1EvB,yBAAyB;EACzB,WhB+CM;AViyHhB;;A0Bp2HA;EAwBU,yBAAyB;EACzB,8C3BnBwB;E2BoBxB,WhByCM;AVuyHhB;;A0B12HA;EA8BU,yBhB+DuB;EgB9DvB,yBAAyB;EACzB,WhBmCM;AV6yHhB;;A0Bh3HA;EAYQ,yB3BR0B;E2BS1B,yBAAyB;EACzB,WhBqDQ;AVmzHhB;;A0Bt3HA;EAkBU,yBhB2EuB;EgB1EvB,yBAAyB;EACzB,WhB+CM;AVyzHhB;;A0B53HA;EAwBU,yBAAyB;EACzB,8C3BrBwB;E2BsBxB,WhByCM;AV+zHhB;;A0Bl4HA;EA8BU,yBhB+DuB;EgB9DvB,yBAAyB;EACzB,WhBmCM;AVq0HhB;;A0Bx4HA;EAYQ,yB3BT0B;E2BU1B,yBAAyB;EACzB,yBhBmDa;AV60HrB;;A0B94HA;EAkBU,yBhB2EuB;EgB1EvB,yBAAyB;EACzB,yBhB6CW;AVm1HrB;;A0Bp5HA;EAwBU,yBAAyB;EACzB,+C3BtBwB;E2BuBxB,yBhBuCW;AVy1HrB;;A0B15HA;EA8BU,yBhB+DuB;EgB9DvB,yBAAyB;EACzB,yBhBiCW;AV+1HrB;;A0Bh6HA;EAYQ,yB3BHyB;E2BIzB,yBAAyB;EACzB,WhBqDQ;AVm2HhB;;A0Bt6HA;EAkBU,yBhB2EuB;EgB1EvB,yBAAyB;EACzB,WhB+CM;AVy2HhB;;A0B56HA;EAwBU,yBAAyB;EACzB,8C3BhBuB;E2BiBvB,WhByCM;AV+2HhB;;A0Bl7HA;EA8BU,yBhB+DuB;EgB9DvB,yBAAyB;EACzB,WhBmCM;AVq3HhB;;A0Bx7HA;EAmCI,kB3BZY;ACq6HhB;;A0B57HA;EAqCI,e3BfS;AC06Hb;;A0Bh8HA;EAuCI,kB3BlBY;AC+6HhB;;A0Bp8HA;EA0CQ,eAAe;A1B85HvB;;A0Bx8HA;EA4CI,iB3BxBW;ACw7Hf;;A0B58HA;EA+CQ,eAAe;A1Bi6HvB;;A0Bh9HA;EAmDM,6BAA6B;EAC7B,0BAA0B;A1Bi6HhC;;A0Br9HA;EAsDM,4BAA4B;EAC5B,yBAAyB;A1Bm6H/B;;A0B19HA;EA0DQ,kB3BHI;ACu6HZ;;A0B99HA;EA4DQ,aAAa;A1Bs6HrB;;A0Bl+HA;EA+DM,sBAAsB;A1Bu6H5B;;A0Bt+HA;EAiEM,sBAAsB;EACtB,YAAY;EACZ,gBAAgB;A1By6HtB;;A0B5+HA;EAqEM,uBAAuB;A1B26H7B;;A0Bh/HA;EAuEM,aAAa;EACb,YAAY;A1B66HlB;;A0Br/HA;EA0EQ,eAAe;A1B+6HvB;;A0Bz/HA;EA6EQ,eAAe;A1Bg7HvB;;A0B7/HA;EAgFQ,eAAe;A1Bi7HvB;;A0BjgIA;EAmFQ,eAAe;A1Bk7HvB;;A0BrgIA;EAsFQ,0BAA4C;A1Bm7HpD;;A0BzgIA;EAwFQ,0B3BjCI;E2BkCJ,uBAAuB;A1Bq7H/B;;A0B9gIA;EA2FI,uBAAuB;A1Bu7H3B;;A0BlhIA;EA8FM,WAAW;A1Bw7HjB;;A0BthIA;EAgGM,YAAY;EACZ,eAAe;A1B07HrB;;A0B3hIA;EAmGI,yBAAyB;A1B47H7B;;A0B/hIA;EAqGM,0BAA4C;A1B87HlD;;A0BniIA;EAuGM,0B3BhDM;E2BiDN,2BAA2B;EAC3B,SAAS;A1Bg8Hf;;A0B97HA;EACE,oBAAoB;EACpB,aAAa;EACb,eAAe;EACf,2BAA2B;EAC3B,gBAAgB;EAChB,kBAAkB;A1Bi8HpB;;A0Bv8HA;EASM,yBhBvB2B;EgBwB3B,c3B9HwB;ACgkI9B;;A0B58HA;EAYM,qBhB1B2B;AV89HjC;;A0Bh9HA;EAeM,yBhB7B2B;EgB8B3B,c3BpIwB;ACykI9B;;A0Br9HA;EAkBM,qBhBhC2B;AVu+HjC;;A0Br8HA;EACE,YAAY;EACZ,OAAO;EACP,UAAU;EACV,aAAa;EACb,kBAAkB;EAClB,MAAM;EACN,WAAW;A1Bw8Hb;;A0Bt8HA;;EAGE,qB3BhJ4B;E2BiJ5B,kB3BrFU;E2BsFV,cAAc;EACd,iBAAiB;EACjB,kBAAkB;EAClB,mBAAmB;A1Bw8HrB;;A0Bt8HA;EACE,4B3BrJ4B;E2BsJ5B,c3B5J4B;ACqmI9B;;A0Bv8HA;EACE,qB3B5J4B;E2B6J5B,mBA9J4B;EA+J5B,2BA9JoC;EA+JpC,cAAc;EACd,eA/JwB;EAgKxB,gBAAgB;EAChB,mBAAmB;EACnB,uBAAuB;A1B08HzB;;A0Bx8HA;EACE,mBAAmB;EACnB,aAAa;EACb,WAAW;EACX,uBAAuB;EzBCrB,mByBAmC;EACrC,UAAU;A1B28HZ;;A0Bj9HA;EAQI,eAAe;A1B68HnB;;A2B7nIA;EACE,c5BF4B;E4BG5B,cAAc;EACd,e5B2BW;E4B1BX,gB5BiCe;AC+lIjB;;A2BpoIA;EAMI,oBAAoB;A3BkoIxB;;A2BxoIA;EASI,kB5BsBY;AC6mIhB;;A2B5oIA;EAWI,kB5BkBY;ACmnIhB;;A2BhpIA;EAaI,iB5BeW;ACwnIf;;A2BroIA;EACE,cAAc;EACd,kB5Bcc;E4Bbd,mBAAmB;A3BwoIrB;;A2B3oIA;EAOM,Y5BdyB;ACspI/B;;A2B/oIA;EAOM,c5B3BuB;ACuqI7B;;A2BnpIA;EAOM,iB5BhBwB;ACgqI9B;;A2BvpIA;EAOM,c5BvBwB;AC2qI9B;;A2B3pIA;EAOM,c5BT4B;ACiqIlC;;A2B/pIA;EAOM,c5BP4B;ACmqIlC;;A2BnqIA;EAOM,c5BR4B;ACwqIlC;;A2BvqIA;EAOM,c5BV4B;AC8qIlC;;A2B3qIA;EAOM,c5BX4B;ACmrIlC;;A2B/qIA;EAOM,c5BL2B;ACirIjC;;A2BxqIA;EAEI,sBAAsB;A3B0qI1B;;A2B5qIA;EAKI,aAAa;EACb,2BAA2B;A3B2qI/B;;A2BjrIA;E1BmJI,kB0B1IwC;A3B4qI5C;;A2BrrIA;;;EAcU,gBAAgB;A3B6qI1B;;A2B3rIA;;;EAoBY,6BAA6B;EAC7B,0BAA0B;A3B6qItC;;A2BlsIA;;;EA8BY,4BAA4B;EAC5B,yBAAyB;A3B0qIrC;;A2BzsIA;;;;;EAyCY,UAAU;A3BwqItB;;A2BjtIA;;;;;;;;;EA8CY,UAAU;A3B+qItB;;A2B7tIA;;;;;;;;;EAgDc,UAAU;A3ByrIxB;;A2BzuIA;EAkDQ,YAAY;EACZ,cAAc;A3B2rItB;;A2B9uIA;EAqDM,uBAAuB;A3B6rI7B;;A2BlvIA;EAuDM,yBAAyB;A3B+rI/B;;A2BtvIA;EA0DQ,YAAY;EACZ,cAAc;A3BgsItB;;A2B3vIA;EA6DI,aAAa;EACb,2BAA2B;A3BksI/B;;A2BhwIA;EAgEM,cAAc;A3BosIpB;;A2BpwIA;EAkEQ,gBAAgB;E1BiFpB,qB0BhF2C;A3BssI/C;;A2BzwIA;EAqEQ,YAAY;EACZ,cAAc;A3BwsItB;;A2B9wIA;EAwEM,uBAAuB;A3B0sI7B;;A2BlxIA;EA0EM,yBAAyB;A3B4sI/B;;A2BtxIA;EA4EM,eAAe;A3B8sIrB;;A2B1xIA;EAgFU,sBAAsB;A3B8sIhC;;A2B9xIA;EAkFQ,uBAAuB;A3BgtI/B;;A2BlyIA;EAoFQ,gBAAgB;A3BktIxB;;AC7tIE;E0BzEF;IAuFM,aAAa;E3BotIjB;AACF;;A2BntIA;EAEI,kBAAkB;A3BqtItB;;AC3uIE;E0BoBF;IAII,qBAAqB;E3BwtIvB;AACF;;AC7uIE;E0BgBF;IAMI,aAAa;IACb,YAAY;IACZ,cAAc;I1BkDd,oB0BjDsC;IACtC,iBAAiB;E3B4tInB;E2BtuIF;IAYM,kB5BhGU;I4BiGV,oBAAoB;E3B6tIxB;E2B1uIF;IAeM,oBAAoB;E3B8tIxB;E2B7uIF;IAiBM,kB5BvGU;I4BwGV,oBAAoB;E3B+tIxB;E2BjvIF;IAoBM,iB5B3GS;I4B4GT,oBAAoB;E3BguIxB;AACF;;A2B/tIA;EAEI,gBAAgB;A3BiuIpB;;AC1wIE;E0BuCF;IAII,aAAa;IACb,aAAa;IACb,YAAY;IACZ,cAAc;E3BouIhB;E2B3uIF;IASM,gBAAgB;E3BquIpB;E2B9uIF;IAWM,cAAc;E3BsuIlB;E2BjvIF;IAaQ,YAAY;E3BuuIlB;E2BpvIF;I1BmCI,qB0BpB2C;E3BwuI7C;AACF;;A2BvuIA;EACE,sBAAsB;EACtB,WAAW;EACX,e5BhIW;E4BiIX,kBAAkB;EAClB,mBAAmB;A3B0uIrB;;A2B/uIA;;;EAaU,c5BxKoB;ACg5I9B;;A2BrvIA;;;EAeQ,kB5B3IQ;ACu3IhB;;A2B3vIA;;;EAiBQ,kB5B/IQ;AC+3IhB;;A2BjwIA;;;EAmBQ,iB5BlJO;ACs4If;;A2BvwIA;EAqBM,c5B7KwB;E4B8KxB,a7BjLgB;E6BkLhB,oBAAoB;EACpB,kBAAkB;EAClB,MAAM;EACN,Y7BrLgB;E6BsLhB,UAAU;A3BsvIhB;;A2BjxIA;;EA+BM,mB7B1LgB;AEi7ItB;;A2BtxIA;EAiCM,OAAO;A3ByvIb;;A2B1xIA;;EAqCM,oB7BhMgB;AE07ItB;;A2B/xIA;EAuCM,QAAQ;A3B4vId;;A2BnyIA;EA2CM,6BAA6B;E1BjB/B,c0BkB+B;EAC7B,YAAY;EACZ,UAAU;A3B4vIhB;;A2B1yIA;EAgDM,kB5B5KU;AC06IhB;;A2B9yIA;EAkDM,kB5BhLU;ACg7IhB;;A2BlzIA;EAoDM,iB5BnLS;ACq7If;;A4Bx9IA,qBAAA;ACWA;EAGE,e9BuBW;E8BtBX,mBAAmB;A7B+8IrB;;A6Bn9IA;EAMI,mBAAmB;EACnB,c9BI8B;E8BH9B,aAAa;EACb,uBAAuB;EACvB,iBAduC;A7B+9I3C;;A6B39IA;EAYM,c9BjBwB;ACo+I9B;;A6B/9IA;EAcI,mBAAmB;EACnB,aAAa;A7Bq9IjB;;A6Bp+IA;E5ByKI,e4BxJoC;A7Bu9IxC;;A6Bx+IA;EAoBQ,c9BzBsB;E8B0BtB,eAAe;EACf,oBAAoB;A7Bw9I5B;;A6B9+IA;EAwBM,c9B1BwB;E8B2BxB,iBAAiB;A7B09IvB;;A6Bn/IA;;EA4BI,uBAAuB;EACvB,aAAa;EACb,eAAe;EACf,2BAA2B;A7B49I/B;;A6B3/IA;E5ByKI,mB4BvIuC;A7B69I3C;;A6B//IA;E5ByKI,kB4BrIuC;A7B+9I3C;;A6BngJA;;EAyCM,uBAAuB;A7B+9I7B;;A6BxgJA;;EA6CM,yBAAyB;A7Bg+I/B;;A6B7gJA;EAgDI,kB9BrBY;ACs/IhB;;A6BjhJA;EAkDI,kB9BzBY;AC4/IhB;;A6BrhJA;EAoDI,iB9B5BW;ACigJf;;A6BzhJA;EAwDM,iBAAiB;A7Bq+IvB;;A6B7hJA;EA2DM,iBAAiB;A7Bs+IvB;;A6BjiJA;EA8DM,iBAAiB;A7Bu+IvB;;A6BriJA;EAiEM,iBAAiB;A7Bw+IvB;;A8B9hJA;EACE,uB/BR6B;E+BS7B,sBAnBmB;EAoBnB,0F/BvB2B;E+BwB3B,c/BnB4B;E+BoB5B,eAAe;EACf,kBAAkB;A9BiiJpB;;A8B9hJE;EACE,+BA3BiB;EA4BjB,gCA5BiB;A9B6jJrB;;A8BhiJE;EACE,kCA9BiB;EA+BjB,mCA/BiB;A9BkkJrB;;A8BjiJA;EAEE,6BAjCwC;EAkCxC,oBAAoB;EACpB,kD/BxC2B;E+ByC3B,aAAa;A9BmiJf;;A8BjiJA;EACE,mBAAmB;EACnB,c/BzC4B;E+B0C5B,aAAa;EACb,YAAY;EACZ,gB/BNe;E+BOf,qBA1CgC;A9B8kJlC;;A8B1iJA;EAQI,uBAAuB;A9BsiJ3B;;A8BpiJA;E7BqBE,qBAAqB;EACrB,wBAAwB;EACxB,gBAAgB;EAChB,gBAAgB;EAChB,YAAY;EACZ,mBAAmB;EACnB,oBAAoB;EACpB,cAAc;EACd,SAAS;EACT,UAAU;E6B5BV,mBAAmB;EACnB,eAAe;EACf,aAAa;EACb,uBAAuB;EACvB,qBApDgC;A9BomJlC;;A8B9iJA;EACE,cAAc;EACd,kBAAkB;A9BijJpB;;A8BnjJA;EAKM,+BA/De;EAgEf,gCAhEe;A9BknJrB;;A8BxjJA;EASM,kCAnEe;EAoEf,mCApEe;A9BunJrB;;A8BjjJA;EAEE,6BAhEyC;EAiEzC,eAhE2B;A9BmnJ7B;;A8BjjJA;EAEE,6BAlEwC;EAmExC,6B/BxE6B;E+ByE7B,oBAAoB;EACpB,aAAa;A9BmjJf;;A8BjjJA;EACE,mBAAmB;EACnB,aAAa;EACb,aAAa;EACb,YAAY;EACZ,cAAc;EACd,uBAAuB;EACvB,gBA5E2B;A9BgoJ7B;;A8B3jJA;E7B6FI,+BFzK2B;AC2oJ/B;;A8BljJA;EAEI,qB/BtDkB;AC0mJtB;;A+BroJA;EACE,oBAAoB;EACpB,kBAAkB;EAClB,mBAAmB;A/BwoJrB;;A+B3oJA;EAOM,cAAc;A/BwoJpB;;A+B/oJA;EAUM,UAAU;EACV,QAAQ;A/ByoJd;;A+BppJA;EAcM,YAAY;EACZ,mBA9BuB;EA+BvB,oBAAoB;EACpB,SAAS;A/B0oJf;;A+BxoJA;EACE,aAAa;E9BmJX,O8BlJqB;EACvB,gBAzC6B;EA0C7B,gBAtC2B;EAuC3B,kBAAkB;EAClB,SAAS;EACT,WApCqB;A/B+qJvB;;A+BzoJA;EACE,uBhCnC6B;EgCoC7B,kBhCmBU;EgClBV,0FhClD2B;EgCmD3B,sBA9CsC;EA+CtC,mBA9CmC;A/B0rJrC;;Ae9qJgB;EgBqCd,chClD4B;EgCmD5B,cAAc;EACd,mBAAmB;EACnB,gBAAgB;EAChB,sBAAsB;EACtB,kBAAkB;A/B6oJpB;;A+B3oJA;;E9BoHI,mB8BlHmC;EACrC,mBAAmB;EACnB,mBAAmB;EACnB,WAAW;A/B8oJb;;A+BnpJA;;EAOI,4BhC1D0B;EgC2D1B,chCtEyB;ACutJ7B;;A+BzpJA;;EAUI,yBhCpD8B;EgCqD9B,WrBOY;AV6oJhB;;A+BlpJA;EACE,yBhCnE6B;EgCoE7B,YAAY;EACZ,cAAc;EACd,WAAW;EACX,gBAAgB;A/BqpJlB;;AgCnuJA;EAEE,mBAAmB;EACnB,8BAA8B;AhCquJhC;;AgCxuJA;EAKI,kBjC6DQ;AC0qJZ;;AgC5uJA;EAOI,qBAAqB;EACrB,mBAAmB;AhCyuJvB;;AgCjvJA;EAWI,aAAa;AhC0uJjB;;AgCrvJA;;EAcM,aAAa;AhC4uJnB;;AgC1vJA;EAgBM,aAAa;AhC8uJnB;;AgC9vJA;EAmBQ,gBAAgB;E/B6JpB,qB+BlLuC;AhCqwJ3C;;AgCnwJA;EAsBQ,YAAY;AhCivJpB;;ACjqJE;E+BtGF;IAyBI,aAAa;EhCmvJf;EgC5wJF;IA4BQ,YAAY;EhCmvJlB;AACF;;AgClvJA;EACE,mBAAmB;EACnB,aAAa;EACb,gBAAgB;EAChB,YAAY;EACZ,cAAc;EACd,uBAAuB;AhCqvJzB;;AgC3vJA;;EASI,gBAAgB;AhCuvJpB;;AC5rJE;E+BpEF;IAaM,sBA7CqC;EhCqyJzC;AACF;;AgCvvJA;;EAEE,gBAAgB;EAChB,YAAY;EACZ,cAAc;AhC0vJhB;;AgC9vJA;;EAQM,YAAY;AhC2vJlB;;AC1sJE;E+BzDF;;I/BmII,qB+BlLuC;EhCwzJzC;AACF;;AgC5vJA;EACE,mBAAmB;EACnB,2BAA2B;AhC+vJ7B;;AC1tJE;E+BvCF;IAMM,kBAAkB;EhCgwJtB;AACF;;AC5tJE;E+B3CF;IAQI,aAAa;EhCowJf;AACF;;AgCnwJA;EACE,mBAAmB;EACnB,yBAAyB;AhCswJ3B;;ACvuJE;E+BjCF;IAKI,aAAa;EhCwwJf;AACF;;AiC50JA;EACE,uBAAuB;EACvB,aAAa;EACb,mBAAmB;AjC+0JrB;;AiCl1JA;EAKI,sBAV2B;AjC21J/B;;AiCt1JA;EAOI,8ClCR0B;EkCS1B,aAAa;EACb,oBAb2B;AjCg2J/B;;AiC51JA;;EAYM,qBAfgC;AjCo2JtC;;AiCj2JA;EAcM,mBAhBwB;AjCu2J9B;;AiCr2JA;EAgBQ,kBAlBsB;AjC22J9B;;AiCz2JA;EAkBI,8ClCnB0B;EkCoB1B,gBA1BgB;EA2BhB,iBA3BgB;AjCs3JpB;;AiC/2JA;EAwBM,kBA9BsB;EA+BtB,mBA/BsB;AjC03J5B;;AiCz1JA;;EAEE,gBAAgB;EAChB,YAAY;EACZ,cAAc;AjC41JhB;;AiC11JA;EhCwII,kBgChLgB;AjCs4JpB;;AiC31JA;EhCqII,iBgChLgB;AjC04JpB;;AiC51JA;EACE,gBAAgB;EAChB,YAAY;EACZ,cAAc;EACd,mBAAmB;AjC+1JrB;;AC/yJE;EgCpDF;IAQI,gBAAgB;EjCg2JlB;AACF;;AkCv4JA;EACE,enCgBW;AC03Jb;;AkC34JA;EAII,kBnCcY;AC63JhB;;AkC/4JA;EAMI,kBnCUY;ACm4JhB;;AkCn5JA;EAQI,iBnCOW;ACw4Jf;;AkC74JA;EACE,iBArB0B;AlCq6J5B;;AkCj5JA;EAGI,kBnCoCc;EmCnCd,cnC3B0B;EmC4B1B,cAAc;EACd,qBAzBiC;AlC26JrC;;AkCx5JA;EAQM,4BnCzBwB;EmC0BxB,cnCjCwB;ACq7J9B;;AkC75JA;EAYM,yBnCpB4B;EmCqB5B,WxBuCU;AV82JhB;;AkCl6JA;EjCsJI,8BF1K0B;EmCqCxB,cAnC0B;EjCwK5B,oBiCvKkC;AlCy7JtC;;AkCp5JA;EACE,cnC3C4B;EmC4C5B,iBApC2B;EAqC3B,qBApC+B;EAqC/B,yBAAyB;AlCu5J3B;;AkC35JA;EAMI,eAtCoB;AlC+7JxB;;AkC/5JA;EAQI,kBAxCoB;AlCm8JxB;;AmC97JA;EAEE,4BpCZ4B;EoCa5B,kBpC4CU;EoC3CV,epCUW;ACs7Jb;;AmCp8JA;EAMI,mBAAmB;AnCk8JvB;;AmCx8JA;EAQI,mBAAmB;EACnB,0BAA0B;AnCo8J9B;;AmC78JA;EAYI,kBpCGY;ACk8JhB;;AmCj9JA;EAcI,kBpCDY;ACw8JhB;;AmCr9JA;EAgBI,iBpCJW;AC68Jf;;AmCz9JA;EAsCM,uBAH+C;AnC07JrD;;AmC79JA;EAwCQ,uBpChDuB;EoCiDvB,cpC9DqB;ACu/J7B;;AmCl+JA;EA2CQ,mBpCnDuB;AC8+J/B;;AmCt+JA;EAsCM,yBAH+C;AnCu8JrD;;AmC1+JA;EAwCQ,yBpC7DqB;EoC8DrB,YpCjDuB;ACu/J/B;;AmC/+JA;EA2CQ,qBpChEqB;ACwgK7B;;AmCn/JA;EAsCM,yBAH+C;AnCo9JrD;;AmCv/JA;EAwCQ,4BpClDsB;EoCmDtB,yBzBgBa;AVm8JrB;;AmC5/JA;EA2CQ,wBpCrDsB;AC0gK9B;;AmChgKA;EAsCM,yBAH+C;AnCi+JrD;;AmCpgKA;EAwCQ,yBpCzDsB;EoC0DtB,WzBkBQ;AV88JhB;;AmCzgKA;EA2CQ,qBpC5DsB;AC8hK9B;;AmC7gKA;EAsCM,yBzB4B0C;AV+8JhD;;AmCjhKA;EAwCQ,yBpC3C0B;EoC4C1B,WzBkBQ;AV29JhB;;AmCthKA;EA2CQ,qBpC9C0B;EoC+C1B,czB8B6D;AVi9JrE;;AmC3hKA;EAsCM,yBzB4B0C;AV69JhD;;AmC/hKA;EAwCQ,yBpCzC0B;EoC0C1B,WzBkBQ;AVy+JhB;;AmCpiKA;EA2CQ,qBpC5C0B;EoC6C1B,czB8B6D;AV+9JrE;;AmCziKA;EAsCM,yBzB4B0C;AV2+JhD;;AmC7iKA;EAwCQ,yBpC1C0B;EoC2C1B,WzBkBQ;AVu/JhB;;AmCljKA;EA2CQ,qBpC7C0B;EoC8C1B,czB8B6D;AV6+JrE;;AmCvjKA;EAsCM,yBzB4B0C;AVy/JhD;;AmC3jKA;EAwCQ,yBpC5C0B;EoC6C1B,WzBkBQ;AVqgKhB;;AmChkKA;EA2CQ,qBpC/C0B;EoCgD1B,czB8B6D;AV2/JrE;;AmCrkKA;EAsCM,yBzB4B0C;AVugKhD;;AmCzkKA;EAwCQ,yBpC7C0B;EoC8C1B,yBzBgBa;AVqhKrB;;AmC9kKA;EA2CQ,qBpChD0B;EoCiD1B,czB8B6D;AVygKrE;;AmCnlKA;EAsCM,yBzB4B0C;AVqhKhD;;AmCvlKA;EAwCQ,yBpCvCyB;EoCwCzB,WzBkBQ;AViiKhB;;AmC5lKA;EA2CQ,qBpC1CyB;EoC2CzB,czB8B6D;AVuhKrE;;AmCnjKA;EACE,mBAAmB;EACnB,yBpChE4B;EoCiE5B,0BAAgE;EAChE,WzBSc;EyBRd,aAAa;EACb,gBpC/Be;EoCgCf,8BAA8B;EAC9B,iBAAiB;EACjB,mBAtEiC;EAuEjC,kBAAkB;AnCsjKpB;;AmChkKA;EAYI,YAAY;EACZ,cAAc;ElCkGd,mBkCjGsC;AnCwjK1C;;AmCtkKA;EAgBI,eAjEgC;EAkEhC,yBAAyB;EACzB,0BAA0B;AnC0jK9B;;AmCxjKA;EACE,qBpChF4B;EoCiF5B,kBpCrBU;EoCsBV,mBAAmB;EACnB,uBAjFmC;EAkFnC,cpCvF4B;EoCwF5B,qBAjFiC;AnC4oKnC;;AmCjkKA;;EASI,uBpCnF2B;ACgpK/B;;AmCtkKA;EAWI,6BAlFgD;AnCipKpD;;AoCjoKA;EAEE,mBAAmB;EACnB,aAAa;EACb,sBAAsB;EACtB,uBAAuB;EACvB,gBAAgB;EAChB,eAAe;EACf,WAxCU;ApC2qKZ;;AoC3oKA;EAWI,aAAa;ApCooKjB;;AoCloKA;EAEE,wCrC/C2B;ACmrK7B;;AoCloKA;;EAEE,cA9CgC;EA+ChC,+BAA0D;EAC1D,cAAc;EACd,kBAAkB;EAClB,WAAW;ApCqoKb;;ACpmKE;EmCvCF;;IASI,cAAc;IACd,8BAA0D;IAC1D,YAxDuB;EpCgsKzB;AACF;;AoCvoKA;EAEE,gBAAgB;EAChB,YAxD2B;EAyD3B,eAAe;EnCwHb,WmChLoB;EA0DtB,SAzDoB;EA0DpB,WA5D2B;ApCqsK7B;;AoCvoKA;EACE,aAAa;EACb,sBAAsB;EACtB,8BAAgD;EAChD,gBAAgB;EAChB,uBAAuB;ApC0oKzB;;AoCxoKA;;EAEE,mBAAmB;EACnB,4BrCtE4B;EqCuE5B,aAAa;EACb,cAAc;EACd,2BAA2B;EAC3B,aApE4B;EAqE5B,kBAAkB;ApC2oKpB;;AoCzoKA;EACE,gCrCjF4B;EqCkF5B,2BrCrBgB;EqCsBhB,4BrCtBgB;ACkqKlB;;AoC1oKA;EACE,crC1F4B;EqC2F5B,YAAY;EACZ,cAAc;EACd,iBrChEa;EqCiEb,cA7E8B;ApC0tKhC;;AoC3oKA;EACE,8BrChCgB;EqCiChB,+BrCjCgB;EqCkChB,6BrC/F4B;AC6uK9B;;AoCjpKA;EnC8EI,mBmCxEuC;ApC+oK3C;;AoC7oKA;EnC3CE,iCAAiC;EmC6CjC,uBrCjG6B;EqCkG7B,YAAY;EACZ,cAAc;EACd,cAAc;EACd,aAtF4B;ApCsuK9B;;AqC1sKA;EACE,uBtC5C6B;EsC6C7B,mBAvDqB;EAwDrB,kBAAkB;EAClB,WAtDW;ArCmwKb;;AqCjtKA;EASM,uBtCpDyB;EsCqDzB,ctClEuB;AC8wK7B;;AqCttKA;;EAcU,ctCtEmB;ACmxK7B;;AqC3tKA;;;;EAoBY,yB3B8BqB;E2B7BrB,ctC7EiB;AC2xK7B;;AqCnuKA;EAwBY,qBtChFiB;AC+xK7B;;AqCvuKA;EA0BQ,ctClFqB;ACmyK7B;;AC3sKE;EoChCF;;;;IAgCY,ctCxFiB;EC2yK3B;EqCnvKF;;;;;;;;;;IAsCc,yB3BYmB;I2BXnB,ctC/Fe;ECwzK3B;EqChwKF;;IA0Cc,qBtClGe;EC4zK3B;EqCpwKF;;;IA8CU,yB3BIuB;I2BHvB,ctCvGmB;ECk0K3B;EqC1wKF;IAmDc,uBtC9FiB;IsC+FjB,ctC5Ge;ECs0K3B;AACF;;AqC/wKA;EASM,yBtCjEuB;EsCkEvB,YtCrDyB;AC+zK/B;;AqCpxKA;;EAcU,YtCzDqB;ACo0K/B;;AqCzxKA;;;;EAoBY,uB3B8BqB;E2B7BrB,YtChEmB;AC40K/B;;AqCjyKA;EAwBY,mBtCnEmB;ACg1K/B;;AqCryKA;EA0BQ,YtCrEuB;ACo1K/B;;ACzwKE;EoChCF;;;;IAgCY,YtC3EmB;EC41K7B;EqCjzKF;;;;;;;;;;IAsCc,uB3BYmB;I2BXnB,YtClFiB;ECy2K7B;EqC9zKF;;IA0Cc,mBtCrFiB;EC62K7B;EqCl0KF;;;IA8CU,uB3BIuB;I2BHvB,YtC1FqB;ECm3K7B;EqCx0KF;IAmDc,yBtC3Ge;IsC4Gf,YtC/FiB;ECu3K7B;AACF;;AqC70KA;EASM,4BtCtDwB;EsCuDxB,yB3BYe;AV4zKrB;;AqCl1KA;;EAcU,yB3BQW;AVi0KrB;;AqCv1KA;;;;EAoBY,yB3B8BqB;E2B7BrB,yB3BCS;AVy0KrB;;AqC/1KA;EAwBY,gC3BFS;AV60KrB;;AqCn2KA;EA0BQ,yB3BJa;AVi1KrB;;ACv0KE;EoChCF;;;;IAgCY,yB3BVS;EVy1KnB;EqC/2KF;;;;;;;;;;IAsCc,yB3BYmB;I2BXnB,yB3BjBO;EVs2KnB;EqC53KF;;IA0Cc,gC3BpBO;EV02KnB;EqCh4KF;;;IA8CU,yB3BIuB;I2BHvB,yB3BzBW;EVg3KnB;EqCt4KF;IAmDc,4BtChGgB;IsCiGhB,yB3B9BO;EVo3KnB;AACF;;AqC34KA;EASM,yBtC7DwB;EsC8DxB,W3BcU;AVw3KhB;;AqCh5KA;;EAcU,W3BUM;AV63KhB;;AqCr5KA;;;;EAoBY,yB3B8BqB;E2B7BrB,W3BGI;AVq4KhB;;AqC75KA;EAwBY,kB3BAI;AVy4KhB;;AqCj6KA;EA0BQ,W3BFQ;AV64KhB;;ACr4KE;EoChCF;;;;IAgCY,W3BRI;EVq5Kd;EqC76KF;;;;;;;;;;IAsCc,yB3BYmB;I2BXnB,W3BfE;EVk6Kd;EqC17KF;;IA0Cc,kB3BlBE;EVs6Kd;EqC97KF;;;IA8CU,yB3BIuB;I2BHvB,W3BvBM;EV46Kd;EqCp8KF;IAmDc,yBtCvGgB;IsCwGhB,W3B5BE;EVg7Kd;AACF;;AqCz8KA;EASM,yBtC/C4B;EsCgD5B,W3BcU;AVs7KhB;;AqC98KA;;EAcU,W3BUM;AV27KhB;;AqCn9KA;;;;EAoBY,yB3B8BqB;E2B7BrB,W3BGI;AVm8KhB;;AqC39KA;EAwBY,kB3BAI;AVu8KhB;;AqC/9KA;EA0BQ,W3BFQ;AV28KhB;;ACn8KE;EoChCF;;;;IAgCY,W3BRI;EVm9Kd;EqC3+KF;;;;;;;;;;IAsCc,yB3BYmB;I2BXnB,W3BfE;EVg+Kd;EqCx/KF;;IA0Cc,kB3BlBE;EVo+Kd;EqC5/KF;;;IA8CU,yB3BIuB;I2BHvB,W3BvBM;EV0+Kd;EqClgLF;IAmDc,yBtCzFoB;IsC0FpB,W3B5BE;EV8+Kd;AACF;;AqCvgLA;EASM,yBtC7C4B;EsC8C5B,W3BcU;AVo/KhB;;AqC5gLA;;EAcU,W3BUM;AVy/KhB;;AqCjhLA;;;;EAoBY,yB3B8BqB;E2B7BrB,W3BGI;AVigLhB;;AqCzhLA;EAwBY,kB3BAI;AVqgLhB;;AqC7hLA;EA0BQ,W3BFQ;AVygLhB;;ACjgLE;EoChCF;;;;IAgCY,W3BRI;EVihLd;EqCziLF;;;;;;;;;;IAsCc,yB3BYmB;I2BXnB,W3BfE;EV8hLd;EqCtjLF;;IA0Cc,kB3BlBE;EVkiLd;EqC1jLF;;;IA8CU,yB3BIuB;I2BHvB,W3BvBM;EVwiLd;EqChkLF;IAmDc,yBtCvFoB;IsCwFpB,W3B5BE;EV4iLd;AACF;;AqCrkLA;EASM,yBtC9C4B;EsC+C5B,W3BcU;AVkjLhB;;AqC1kLA;;EAcU,W3BUM;AVujLhB;;AqC/kLA;;;;EAoBY,yB3B8BqB;E2B7BrB,W3BGI;AV+jLhB;;AqCvlLA;EAwBY,kB3BAI;AVmkLhB;;AqC3lLA;EA0BQ,W3BFQ;AVukLhB;;AC/jLE;EoChCF;;;;IAgCY,W3BRI;EV+kLd;EqCvmLF;;;;;;;;;;IAsCc,yB3BYmB;I2BXnB,W3BfE;EV4lLd;EqCpnLF;;IA0Cc,kB3BlBE;EVgmLd;EqCxnLF;;;IA8CU,yB3BIuB;I2BHvB,W3BvBM;EVsmLd;EqC9nLF;IAmDc,yBtCxFoB;IsCyFpB,W3B5BE;EV0mLd;AACF;;AqCnoLA;EASM,yBtChD4B;EsCiD5B,W3BcU;AVgnLhB;;AqCxoLA;;EAcU,W3BUM;AVqnLhB;;AqC7oLA;;;;EAoBY,yB3B8BqB;E2B7BrB,W3BGI;AV6nLhB;;AqCrpLA;EAwBY,kB3BAI;AVioLhB;;AqCzpLA;EA0BQ,W3BFQ;AVqoLhB;;AC7nLE;EoChCF;;;;IAgCY,W3BRI;EV6oLd;EqCrqLF;;;;;;;;;;IAsCc,yB3BYmB;I2BXnB,W3BfE;EV0pLd;EqClrLF;;IA0Cc,kB3BlBE;EV8pLd;EqCtrLF;;;IA8CU,yB3BIuB;I2BHvB,W3BvBM;EVoqLd;EqC5rLF;IAmDc,yBtC1FoB;IsC2FpB,W3B5BE;EVwqLd;AACF;;AqCjsLA;EASM,yBtCjD4B;EsCkD5B,yB3BYe;AVgrLrB;;AqCtsLA;;EAcU,yB3BQW;AVqrLrB;;AqC3sLA;;;;EAoBY,yB3B8BqB;E2B7BrB,yB3BCS;AV6rLrB;;AqCntLA;EAwBY,gC3BFS;AVisLrB;;AqCvtLA;EA0BQ,yB3BJa;AVqsLrB;;AC3rLE;EoChCF;;;;IAgCY,yB3BVS;EV6sLnB;EqCnuLF;;;;;;;;;;IAsCc,yB3BYmB;I2BXnB,yB3BjBO;EV0tLnB;EqChvLF;;IA0Cc,gC3BpBO;EV8tLnB;EqCpvLF;;;IA8CU,yB3BIuB;I2BHvB,yB3BzBW;EVouLnB;EqC1vLF;IAmDc,yBtC3FoB;IsC4FpB,yB3B9BO;EVwuLnB;AACF;;AqC/vLA;EASM,yBtC3C2B;EsC4C3B,W3BcU;AV4uLhB;;AqCpwLA;;EAcU,W3BUM;AVivLhB;;AqCzwLA;;;;EAoBY,yB3B8BqB;E2B7BrB,W3BGI;AVyvLhB;;AqCjxLA;EAwBY,kB3BAI;AV6vLhB;;AqCrxLA;EA0BQ,W3BFQ;AViwLhB;;ACzvLE;EoChCF;;;;IAgCY,W3BRI;EVywLd;EqCjyLF;;;;;;;;;;IAsCc,yB3BYmB;I2BXnB,W3BfE;EVsxLd;EqC9yLF;;IA0Cc,kB3BlBE;EV0xLd;EqClzLF;;;IA8CU,yB3BIuB;I2BHvB,W3BvBM;EVgyLd;EqCxzLF;IAmDc,yBtCrFmB;IsCsFnB,W3B5BE;EVoyLd;AACF;;AqC7zLA;EAsDI,oBAAoB;EACpB,aAAa;EACb,mBA7GmB;EA8GnB,WAAW;ArC2wLf;;AqCp0LA;EA2DI,gCtCxG0B;ACq3L9B;;AqCx0LA;EALE,OAAO;EACP,eAAe;EACf,QAAQ;EACR,WA/CiB;ArCg4LnB;;AqC/0LA;EAgEI,SAAS;ArCmxLb;;AqCn1LA;EAkEM,iCtC/GwB;ACo4L9B;;AqCv1LA;EAoEI,MAAM;ArCuxLV;;AqCrxLA;;EAGI,oBA9HmB;ArCq5LvB;;AqC1xLA;;EAKI,uBAhImB;ArC05LvB;;AqCxxLA;;EAEE,oBAAoB;EACpB,aAAa;EACb,cAAc;EACd,mBAvIqB;ArCk6LvB;;AqCzxLA;EAIM,6BAA6B;ArCyxLnC;;AqCvxLA;EpCjFE,iCAAiC;EoCmFjC,gBAAgB;EAChB,gBAAgB;EAChB,kBAAkB;ArC0xLpB;;AqCxxLA;EAEE,ctCrJ4B;EEoB5B,qBAAqB;EACrB,wBAAwB;EACxB,gBAAgB;EAChB,gBAAgB;EAChB,YAAY;EACZ,eAAe;EACf,cAAc;EACd,eoC7BqB;EpC8BrB,kBAAkB;EAClB,coC/BqB;EpC+KnB,iBoCtBkC;ArCmyLtC;;AC55LE;EACE,8BAA8B;EAC9B,cAAc;EACd,WAAW;EACX,qBAAqB;EACrB,kBAAkB;EAClB,wBAAwB;EACxB,yBF6BQ;EE5BR,yDAAyD;EACzD,oCFsBa;EErBb,WAAW;AD+5Lf;;AC95LI;EACE,oBAAoB;ADi6L1B;;ACh6LI;EACE,oBAAoB;ADm6L1B;;ACl6LI;EACE,oBAAoB;ADq6L1B;;ACp6LE;EACE,qCAAiC;ADu6LrC;;ACn6LM;EACE,wCAAwC;ADs6LhD;;ACr6LM;EACE,UAAU;ADw6LlB;;ACv6LM;EACE,0CAA0C;AD06LlD;;AqC10LA;EACE,aAAa;ArC60Lf;;AqC30LA;;EAEE,ctC9J4B;EsC+J5B,cAAc;EACd,gBAAgB;EAChB,uBAAuB;EACvB,kBAAkB;ArC80LpB;;AqCp1LA;;EASM,qBAAqB;EACrB,sBAAsB;ArCg1L5B;;AqC90LA;;EAEE,eAAe;ArCi1LjB;;AqCn1LA;;;;;EAOI,yBtCxK0B;EsCyK1B,ctCjK8B;ACq/LlC;;AqCl1LA;EACE,YAAY;EACZ,cAAc;ArCq1LhB;;AqCv1LA;EAII,mBA7KgC;ArCogMpC;;AqC31LA;EAMI,UAAU;ArCy1Ld;;AqC/1LA;EAQI,YAAY;EACZ,cAAc;ArC21LlB;;AqCp2LA;EAWI,oCAAoC;EACpC,mBAhMmB;EAiMnB,kCAAkC;ArC61LtC;;AqC12LA;EAgBM,6BArLyC;EAsLzC,4BtCpL4B;ACkhMlC;;AqC/2LA;EAmBM,6BArL0C;EAsL1C,4BtCvL4B;EsCwL5B,0BArLuC;EAsLvC,wBArLqC;EAsLrC,ctC1L4B;EsC2L5B,kCAAwE;ArCg2L9E;;AqC91LA;EACE,YAAY;EACZ,cAAc;ArCi2LhB;;AqC/1LA;EpCnCI,oBoCoCoC;ArCk2LxC;;AqCn2LA;EAII,qBtCrM8B;EsCsM9B,oBAAoB;EpChCpB,coCiC6B;ArCm2LjC;;AqCj2LA;EACE,mBAAmB;EACnB,sBAAsB;EACtB,mBAAmB;ArCo2LrB;;AqCv2LA;EAKI,oBAAoB;EACpB,qBAAqB;ArCs2LzB;;AqCp2LA;EACE,4BtC3N4B;EsC4N5B,YAAY;EACZ,aAAa;EACb,WA/LyB;EAgMzB,gBAAgB;ArCu2LlB;;ACr/LE;EoCpCF;IAsLI,cAAc;ErCw2LhB;EqCv2LA;;IAGI,mBAAmB;IACnB,aAAa;ErCw2LjB;EqCv2LA;IAEI,aAAa;ErCw2LjB;EqCh8LF;IA0FI,uBtC3O2B;IsC4O3B,4CtCzPyB;IsC0PzB,iBAAiB;ErCy2LnB;EqC52LA;IAKI,cAAc;ErC02LlB;EqCx2LA;IA3MA,OAAO;IACP,eAAe;IACf,QAAQ;IACR,WA/CiB;ErCqmMjB;EqC92LA;IAKI,SAAS;ErC42Lb;EqCj3LA;IAOM,4CtCrQqB;ECknM3B;EqCp3LA;IASI,MAAM;ErC82LV;EqCv3LA;IpC7LA,iCAAiC;IoC2M3B,iCAA2C;IAC3C,cAAc;ErC62LpB;EqC52LA;;IAGI,oBA9QiB;ErC2nMrB;EqCh3LA;;IAKI,uBAhRiB;ErC+nMrB;AACF;;AC3iME;EoC8LA;;;;IAIE,oBAAoB;IACpB,aAAa;ErCi3Lf;EqCplMF;IAqOI,mBA1RmB;ErC4oMrB;EqCn3LA;IAGI,kBA1R0B;ErC6oM9B;EqCt3LA;;IAMM,mBAAmB;ErCo3LzB;EqC13LA;;IASM,kBtCjOI;ECslMV;EqC93LA;;;;IAgBQ,wCAAwC;ErCo3LhD;EqCp4LA;IAuBU,wCAAwC;ErCg3LlD;EqCv4LA;IA4BU,4BtC7SkB;IsC8SlB,ctCzTiB;ECuqM3B;EqC34LA;IA+BU,4BtChTkB;IsCiTlB,ctCxSsB;ECupMhC;EqCnhMF;IAsKI,aAAa;ErCg3Lf;EqC7gMF;;IAgKI,mBAAmB;IACnB,aAAa;ErCi3Lf;EqC5/LF;IA8IM,oBAAoB;ErCi3LxB;EqCn3LA;IAKM,oDAAoD;ErCi3L1D;EqCt3LA;IAOM,gCtClUsB;IsCmUtB,0BAAkE;IAClE,gBAAgB;IAChB,YAAY;IACZ,4CtC9UqB;IsC+UrB,SAAS;ErCk3Lf;EqC93LA;IAkBM,cAAc;ErC+2LpB;EqC92LM;IAEE,UAAU;IACV,oBAAoB;IACpB,wBAAwB;ErC+2LhC;EqC3iMF;IA8LI,YAAY;IACZ,cAAc;ErCg3LhB;EqC/2LA;IACE,2BAA2B;IpC7K3B,kBoC8KoC;ErCi3LtC;EqCh3LA;IACE,yBAAyB;IpChLzB,iBoCiLoC;ErCk3LtC;EqCx/LF;IAwII,uBtCxV2B;IsCyV3B,8BtCjSc;IsCkSd,+BtClSc;IsCmSd,6BtChW0B;IsCiW1B,2CtCzWyB;IsC0WzB,aAAa;IACb,mBAAmB;IpCjLnB,OoCkLuB;IACvB,eAAe;IACf,kBAAkB;IAClB,SAAS;IACT,WAjVkB;ErCosMpB;EqCtgMF;IAqJM,sBAAsB;IACtB,mBAAmB;ErCo3LvB;EqCn4LA;IpClLE,mBoCmMuC;ErCq3LzC;EqCt4LA;IAoBM,4BtC7WsB;IsC8WtB,ctCzXqB;EC8uM3B;EqC14LA;IAuBM,4BtChXsB;IsCiXtB,ctCxW0B;EC8tMhC;EqCr3LE;IAEE,kBtC1TY;IsC2TZ,gBAAgB;IAChB,4EtCjYuB;IsCkYvB,cAAc;IACd,UAAU;IACV,oBAAoB;IACpB,wBAA8C;IAC9C,2BAA2B;IAC3B,yBtChUM;IsCiUN,uCAAuC;ErCs3L3C;EqC15LA;IAsCI,UAAU;IACV,QAAQ;ErCu3LZ;EqC7hMF;IAwKI,cAAc;ErCw3LhB;EqCv3LA;;IpC5NE,qBoC+NyC;ErCw3L3C;EqC33LA;;IpC5NE,sBoCiOyC;ErC03L3C;EqCx3LA;IAlWA,OAAO;IACP,eAAe;IACf,QAAQ;IACR,WA/CiB;ErC4wMjB;EqC93LA;IAKI,SAAS;ErC43Lb;EqCj4LA;IAOM,4CtC5ZqB;ECyxM3B;EqCp4LA;IASI,MAAM;ErC83LV;EqC73LA;;IAGI,oBA/ZiB;ErC6xMrB;EqCj4LA;;IAKI,uBAjaiB;ErCiyMrB;EqCr4LA;;IAOI,oBAA4D;ErCk4LhE;EqCz4LA;;IASI,uBAA+D;ErCo4LnE;EqCl4LA;;IAGI,ctC7auB;ECgzM3B;EqCt4LA;;IAKI,6BAla2C;ErCuyM/C;EqCp4LA;IAKM,yBtCzasB;EC2yM5B;AACF;;AqC/3LA;EAEI,iCAA2C;ArCi4L/C;;AsCzxMA;EAEE,evCFW;EuCGX,gBAnC0B;AtC8zM5B;;AsC9xMA;EAMI,kBvCLY;ACiyMhB;;AsClyMA;EAQI,kBvCTY;ACuyMhB;;AsCtyMA;EAUI,iBvCZW;AC4yMf;;AsC1yMA;;EAcM,iBAAiB;EACjB,kBAAkB;EAClB,qBvCmBiB;AC8wMvB;;AsCjzMA;EAkBM,qBvCiBiB;ACkxMvB;;AsCjyMA;;EAEE,mBAAmB;EACnB,aAAa;EACb,uBAAuB;EACvB,kBAAkB;AtCoyMpB;;AsClyMA;;;;EAME,cA9D6B;EA+D7B,uBAAuB;EACvB,eA/D8B;EAgE9B,mBA/DkC;EAgElC,oBA/DmC;EAgEnC,kBAAkB;AtCmyMpB;;AsCjyMA;;;EAGE,qBvCtE4B;EuCuE5B,cvC3E4B;EuC4E5B,gBxC3EoB;AE+2MtB;;AsCzyMA;;;EAOI,qBvC3E0B;EuC4E1B,cvC/E0B;ACu3M9B;;AsChzMA;;;EAUI,qBvCjE8B;AC62MlC;;AsCtzMA;;;EAYI,iDvCvFyB;ACu4M7B;;AsC5zMA;;;;;EAeI,yBvClF0B;EuCmF1B,qBvCnF0B;EuCoF1B,gBAAgB;EAChB,cvCvF0B;EuCwF1B,YAAY;AtCqzMhB;;AsCnzMA;;EAEE,oBAvFkC;EAwFlC,qBAvFmC;EAwFnC,mBAAmB;AtCszMrB;;AsCpzMA;EAEI,yBvCpF8B;EuCqF9B,qBvCrF8B;EuCsF9B,W5B1BY;AVg1MhB;;AsCpzMA;EACE,cvCtG4B;EuCuG5B,oBAAoB;AtCuzMtB;;AsCrzMA;EACE,eAAe;AtCwzMjB;;AsCzzMA;EAGI,gBAAgB;AtC0zMpB;;ACz0ME;EqCjEF;IAoFI,eAAe;EtC2zMjB;EsCl1MF;;IA0BI,YAAY;IACZ,cAAc;EtC4zMhB;EsCv0MF;IAcM,YAAY;IACZ,cAAc;EtC4zMlB;AACF;;ACp1ME;EqCQF;IAmBI,YAAY;IACZ,cAAc;IACd,2BAA2B;IAC3B,QAAQ;EtC8zMV;EsCt4MF;;;;IA6EI,gBAAgB;IAChB,aAAa;EtC+zMf;EsC9zMA;IACE,QAAQ;EtCg0MV;EsC/zMA;IACE,QAAQ;EtCi0MV;EsC96MF;IA+GI,8BAA8B;IAC9B,gBAAgB;IAChB,aAAa;EtCk0Mf;EsCr0MA;IAMM,QAAQ;EtCk0Md;EsCx0MA;IAQM,uBAAuB;IACvB,QAAQ;EtCm0Md;EsC50MA;IAWM,QAAQ;EtCo0Md;EsC/0MA;IAcM,QAAQ;EtCo0Md;EsCl1MA;IAgBM,QAAQ;EtCq0Md;EsCr1MA;IAkBM,yBAAyB;IACzB,QAAQ;EtCs0Md;AACF;;AuC78MA;EACE,kBxCsCgB;EwCrChB,0FxChC2B;EwCiC3B,exCEW;AC88Mb;;AuCn9MA;EAKI,qBxCWkB;ACu8MtB;;AuCv9MA;EAYQ,uBxC7BuB;EwC8BvB,cxC3CqB;AC0/M7B;;AuC59MA;EAeQ,0BxChCuB;ACi/M/B;;AuCh+MA;EAiBQ,YxClCuB;ACq/M/B;;AuCp+MA;EAYQ,yBxC1CqB;EwC2CrB,YxC9BuB;AC0/M/B;;AuCz+MA;EAeQ,4BxC7CqB;AC2gN7B;;AuC7+MA;EAiBQ,cxC/CqB;AC+gN7B;;AuCj/MA;EAYQ,4BxC/BsB;EwCgCtB,yB7BmCa;AVs8MrB;;AuCt/MA;EAeQ,+BxClCsB;AC6gN9B;;AuC1/MA;EAiBQ,iBxCpCsB;ACihN9B;;AuC9/MA;EAYQ,yBxCtCsB;EwCuCtB,W7BqCQ;AVi9MhB;;AuCngNA;EAeQ,4BxCzCsB;ACiiN9B;;AuCvgNA;EAiBQ,cxC3CsB;ACqiN9B;;AuC3gNA;EAYQ,yBxCxB0B;EwCyB1B,W7BqCQ;AV89MhB;;AuChhNA;EAeQ,4BxC3B0B;ACgiNlC;;AuCphNA;EAiBQ,cxC7B0B;ACoiNlC;;AuCxhNA;EAYQ,yBxCtB0B;EwCuB1B,W7BqCQ;AV2+MhB;;AuC7hNA;EAeQ,4BxCzB0B;AC2iNlC;;AuCjiNA;EAiBQ,cxC3B0B;AC+iNlC;;AuCriNA;EAYQ,yBxCvB0B;EwCwB1B,W7BqCQ;AVw/MhB;;AuC1iNA;EAeQ,4BxC1B0B;ACyjNlC;;AuC9iNA;EAiBQ,cxC5B0B;AC6jNlC;;AuCljNA;EAYQ,yBxCzB0B;EwC0B1B,W7BqCQ;AVqgNhB;;AuCvjNA;EAeQ,4BxC5B0B;ACwkNlC;;AuC3jNA;EAiBQ,cxC9B0B;AC4kNlC;;AuC/jNA;EAYQ,yBxC1B0B;EwC2B1B,yB7BmCa;AVohNrB;;AuCpkNA;EAeQ,4BxC7B0B;ACslNlC;;AuCxkNA;EAiBQ,cxC/B0B;AC0lNlC;;AuC5kNA;EAYQ,yBxCpByB;EwCqBzB,W7BqCQ;AV+hNhB;;AuCjlNA;EAeQ,4BxCvByB;AC6lNjC;;AuCrlNA;EAiBQ,cxCzByB;ACimNjC;;AuCtkNA;;EAGI,gCxC3C2B;ACmnN/B;;AuCtkNA;EACE,yBxC9C6B;EwC+C7B,0BAA8C;EAC9C,cxCrD4B;EwCsD5B,iBAhDyB;EAiDzB,gBxCjBe;EwCkBf,iBArD8B;EAsD9B,mBArDgC;AvC8nNlC;;AuCvkNA;EACE,qBAAqB;EACrB,aAAa;EACb,kBArD4B;EAsD5B,uBAAuB;AvC0kNzB;;AuC9kNA;EAMI,gCxC7D0B;EwC8D1B,mBAAmB;EACnB,cAAc;AvC4kNlB;;AuCplNA;EAWM,4BxCrEwB;EwCsExB,cxCvEwB;ACopN9B;;AuC3kNA;EAEI,cxC1E0B;ACupN9B;;AuC/kNA;EAIM,cxC7D4B;AC4oNlC;;AuC7kNA;EACE,mBAAmB;EACnB,cxCjF4B;EwCkF5B,aAAa;EACb,2BAA2B;EAC3B,qBAAqB;AvCglNvB;;AuCrlNA;EtC+FI,oBsCxFsC;AvCklN1C;;AuCzlNA;EASI,YAAY;EACZ,cAAc;EACd,WAAW;AvColNf;;AuC/lNA;EAaI,eAAe;AvCslNnB;;AuCnmNA;EAeI,0BxC9E8B;EwC+E9B,cxC/F0B;ACurN9B;;AuCxmNA;EAkBM,cxCjF4B;AC2qNlC;;AuC5mNA;EAoBI,8BxClCc;EwCmCd,+BxCnCc;AC+nNlB;;AuC1lNA;;EAEE,eAAe;AvC6lNjB;;AuC/lNA;;EAII,4BxCnG0B;ACmsN9B;;AuC9lNA;EtChGE,qBAAqB;EACrB,esCgGgB;EtC/FhB,WsC+FqB;EtC9FrB,gBsC8FqB;EtC7FrB,kBAAkB;EAClB,mBAAmB;EACnB,UsC2FqB;EACrB,cxC5G4B;EE4K1B,oBsC/DoC;AvCumNxC;;AuC1mNA;EAKI,kBAAkB;EAClB,oBAAoB;AvCymNxB;;AwCnsNA;EvCqCE,iCAAiC;EuCjCjC,oBAAoB;EACpB,aAAa;EACb,ezCCW;EyCAX,8BAA8B;EAC9B,gBAAgB;EAChB,gBAAgB;EAChB,mBAAmB;AxCosNrB;;AwC9sNA;EAYI,mBAAmB;EACnB,4BzCjC0B;EyCkC1B,0BAzC4B;EA0C5B,wBAzC0B;EA0C1B,czCvC0B;EyCwC1B,aAAa;EACb,uBAAuB;EACvB,mBAA6C;EAC7C,kBAxCyB;EAyCzB,mBAAmB;AxCssNvB;;AwC3tNA;EAuBM,4BzC/CwB;EyCgDxB,czChDwB;ACwvN9B;;AwChuNA;EA0BI,cAAc;AxC0sNlB;;AwCpuNA;EA6BQ,4BzCrC0B;EyCsC1B,czCtC0B;ACivNlC;;AwCzuNA;EAgCI,mBAAmB;EACnB,4BzCrD0B;EyCsD1B,0BA7D4B;EA8D5B,wBA7D0B;EA8D1B,aAAa;EACb,YAAY;EACZ,cAAc;EACd,2BAA2B;AxC6sN/B;;AwCpvNA;EAyCM,qBAAqB;AxC+sN3B;;AwCxvNA;EA2CM,UAAU;EACV,uBAAuB;EACvB,oBAAoB;EACpB,qBAAqB;AxCitN3B;;AwC/vNA;EAgDM,yBAAyB;EACzB,oBAAoB;AxCmtN1B;;AwCpwNA;EvCsJI,mBuClGuC;AxCotN3C;;AwCxwNA;EvCsJI,kBuChGuC;AxCstN3C;;AwC5wNA;EA0DM,uBAAuB;AxCstN7B;;AwChxNA;EA6DM,yBAAyB;AxCutN/B;;AwCpxNA;EAiEM,6BAA6B;EAE3B,0BAAkE;AxCstN1E;;AwCzxNA;EAuEQ,4BzCxFsB;EyCyFtB,4BzC5FsB;ACkzN9B;;AwC9xNA;EA4EU,uBzC3FqB;EyC4FrB,qBzCjGoB;EyCkGpB,2CAA2E;AxCstNrF;;AwCpyNA;EAiFM,YAAY;EACZ,cAAc;AxCutNpB;;AwCzyNA;EAqFM,qBzCzGwB;EyC0GxB,mBA/F+B;EAgG/B,iBA/F6B;EAgG7B,gBAAgB;EAChB,kBAAkB;AxCwtNxB;;AwCjzNA;EA2FQ,4BzC5GsB;EyC6GtB,qBzCjHsB;EyCkHtB,UAAU;AxC0tNlB;;AwCvzNA;EvCsJI,iBuCtDuE;AxC2tN3E;;AwC3zNA;EAmGU,2BzC3DE;EyC4DF,8BzC5DE;ACwxNZ;;AwCh0NA;EA0GU,4BzClEE;EyCmEF,+BzCnEE;AC6xNZ;;AwCr0NA;EAiHU,yBzCzHwB;EyC0HxB,qBzC1HwB;EyC2HxB,W9B/DM;E8BgEN,UAAU;AxCwtNpB;;AwC50NA;EAsHM,mBAAmB;AxC0tNzB;;AwCh1NA;EA2HY,iCzCjFW;EyCkFX,8BzClFW;EyCmFX,oBAAoB;AxCytNhC;;AwCt1NA;EAoIY,kCzC1FW;EyC2FX,+BzC3FW;EyC4FX,qBAAqB;AxCstNjC;;AwC51NA;EA6II,kBzCrIY;ACw1NhB;;AwCh2NA;EA+II,kBzCzIY;AC81NhB;;AwCp2NA;EAiJI,iBzC5IW;ACm2Nf;;AyCt4NA,eAAA;ACIA;EACE,cAAc;EACd,aAAa;EACb,YAAY;EACZ,cAAc;EACd,gBAPkB;A1C64NpB;;A0Cr4NE;EACE,UAAU;EACV,YAAY;A1Cw4NhB;;A0Cv4NE;EACE,UAAU;EACV,WAAW;A1C04Nf;;A0Cz4NE;EACE,UAAU;EACV,UAAU;A1C44Nd;;A0C34NE;EACE,UAAU;EACV,eAAe;A1C84NnB;;A0C74NE;EACE,UAAU;EACV,UAAU;A1Cg5Nd;;A0C/4NE;EACE,UAAU;EACV,eAAe;A1Ck5NnB;;A0Cj5NE;EACE,UAAU;EACV,UAAU;A1Co5Nd;;A0Cn5NE;EACE,UAAU;EACV,UAAU;A1Cs5Nd;;A0Cr5NE;EACE,UAAU;EACV,UAAU;A1Cw5Nd;;A0Cv5NE;EACE,UAAU;EACV,UAAU;A1C05Nd;;A0Cz5NE;EACE,UAAU;EACV,UAAU;A1C45Nd;;A0C35NE;EzCyIE,gByCxImC;A1C85NvC;;A0C75NE;EzCuIE,qByCtIwC;A1Cg6N5C;;A0C/5NE;EzCqIE,gByCpImC;A1Ck6NvC;;A0Cj6NE;EzCmIE,qByClIwC;A1Co6N5C;;A0Cn6NE;EzCiIE,gByChImC;A1Cs6NvC;;A0Cr6NE;EzC+HE,gByC9HmC;A1Cw6NvC;;A0Cv6NE;EzC6HE,gByC5HmC;A1C06NvC;;A0Cz6NE;EzC2HE,gByC1HmC;A1C46NvC;;A0C36NE;EzCyHE,gByCxHmC;A1C86NvC;;A0C56NI;EACE,UAAU;EACV,SAAiC;A1C+6NvC;;A0C96NI;EzCmHA,eyClH4D;A1Ci7NhE;;A0Cr7NI;EACE,UAAU;EACV,eAAiC;A1Cw7NvC;;A0Cv7NI;EzCmHA,qByClH4D;A1C07NhE;;A0C97NI;EACE,UAAU;EACV,gBAAiC;A1Ci8NvC;;A0Ch8NI;EzCmHA,sByClH4D;A1Cm8NhE;;A0Cv8NI;EACE,UAAU;EACV,UAAiC;A1C08NvC;;A0Cz8NI;EzCmHA,gByClH4D;A1C48NhE;;A0Ch9NI;EACE,UAAU;EACV,gBAAiC;A1Cm9NvC;;A0Cl9NI;EzCmHA,sByClH4D;A1Cq9NhE;;A0Cz9NI;EACE,UAAU;EACV,gBAAiC;A1C49NvC;;A0C39NI;EzCmHA,sByClH4D;A1C89NhE;;A0Cl+NI;EACE,UAAU;EACV,UAAiC;A1Cq+NvC;;A0Cp+NI;EzCmHA,gByClH4D;A1Cu+NhE;;A0C3+NI;EACE,UAAU;EACV,gBAAiC;A1C8+NvC;;A0C7+NI;EzCmHA,sByClH4D;A1Cg/NhE;;A0Cp/NI;EACE,UAAU;EACV,gBAAiC;A1Cu/NvC;;A0Ct/NI;EzCmHA,sByClH4D;A1Cy/NhE;;A0C7/NI;EACE,UAAU;EACV,UAAiC;A1CggOvC;;A0C//NI;EzCmHA,gByClH4D;A1CkgOhE;;A0CtgOI;EACE,UAAU;EACV,gBAAiC;A1CygOvC;;A0CxgOI;EzCmHA,sByClH4D;A1C2gOhE;;A0C/gOI;EACE,UAAU;EACV,gBAAiC;A1CkhOvC;;A0CjhOI;EzCmHA,sByClH4D;A1CohOhE;;A0CxhOI;EACE,UAAU;EACV,WAAiC;A1C2hOvC;;A0C1hOI;EzCmHA,iByClH4D;A1C6hOhE;;ACz/NE;EyClGF;IAiEM,UAAU;IACV,YAAY;E1C+hOhB;E0CjmOF;IAoEM,UAAU;IACV,WAAW;E1CgiOf;E0CrmOF;IAuEM,UAAU;IACV,UAAU;E1CiiOd;E0CzmOF;IA0EM,UAAU;IACV,eAAe;E1CkiOnB;E0C7mOF;IA6EM,UAAU;IACV,UAAU;E1CmiOd;E0CjnOF;IAgFM,UAAU;IACV,eAAe;E1CoiOnB;E0CrnOF;IAmFM,UAAU;IACV,UAAU;E1CqiOd;E0CznOF;IAsFM,UAAU;IACV,UAAU;E1CsiOd;E0C7nOF;IAyFM,UAAU;IACV,UAAU;E1CuiOd;E0CjoOF;IA4FM,UAAU;IACV,UAAU;E1CwiOd;E0CroOF;IA+FM,UAAU;IACV,UAAU;E1CyiOd;E0CzoOF;IzCgLI,gByC9EqC;E1C0iOvC;E0C5oOF;IzCgLI,qByC5E0C;E1C2iO5C;E0C/oOF;IzCgLI,gByC1EqC;E1C4iOvC;E0ClpOF;IzCgLI,qByCxE0C;E1C6iO5C;E0CrpOF;IzCgLI,gByCtEqC;E1C8iOvC;E0CxpOF;IzCgLI,gByCpEqC;E1C+iOvC;E0C3pOF;IzCgLI,gByClEqC;E1CgjOvC;E0C9pOF;IzCgLI,gByChEqC;E1CijOvC;E0CjqOF;IzCgLI,gByC9DqC;E1CkjOvC;E0CpqOF;IAqHQ,UAAU;IACV,SAAiC;E1CkjOvC;E0CxqOF;IzCgLI,eyCxD8D;E1CmjOhE;E0C3qOF;IAqHQ,UAAU;IACV,eAAiC;E1CyjOvC;E0C/qOF;IzCgLI,qByCxD8D;E1C0jOhE;E0ClrOF;IAqHQ,UAAU;IACV,gBAAiC;E1CgkOvC;E0CtrOF;IzCgLI,sByCxD8D;E1CikOhE;E0CzrOF;IAqHQ,UAAU;IACV,UAAiC;E1CukOvC;E0C7rOF;IzCgLI,gByCxD8D;E1CwkOhE;E0ChsOF;IAqHQ,UAAU;IACV,gBAAiC;E1C8kOvC;E0CpsOF;IzCgLI,sByCxD8D;E1C+kOhE;E0CvsOF;IAqHQ,UAAU;IACV,gBAAiC;E1CqlOvC;E0C3sOF;IzCgLI,sByCxD8D;E1CslOhE;E0C9sOF;IAqHQ,UAAU;IACV,UAAiC;E1C4lOvC;E0CltOF;IzCgLI,gByCxD8D;E1C6lOhE;E0CrtOF;IAqHQ,UAAU;IACV,gBAAiC;E1CmmOvC;E0CztOF;IzCgLI,sByCxD8D;E1ComOhE;E0C5tOF;IAqHQ,UAAU;IACV,gBAAiC;E1C0mOvC;E0ChuOF;IzCgLI,sByCxD8D;E1C2mOhE;E0CnuOF;IAqHQ,UAAU;IACV,UAAiC;E1CinOvC;E0CvuOF;IzCgLI,gByCxD8D;E1CknOhE;E0C1uOF;IAqHQ,UAAU;IACV,gBAAiC;E1CwnOvC;E0C9uOF;IzCgLI,sByCxD8D;E1CynOhE;E0CjvOF;IAqHQ,UAAU;IACV,gBAAiC;E1C+nOvC;E0CrvOF;IzCgLI,sByCxD8D;E1CgoOhE;E0CxvOF;IAqHQ,UAAU;IACV,WAAiC;E1CsoOvC;E0C5vOF;IzCgLI,iByCxD8D;E1CuoOhE;AACF;;AC1pOE;EyCtGF;IA4HM,UAAU;IACV,YAAY;E1CyoOhB;E0CtwOF;IAgIM,UAAU;IACV,WAAW;E1CyoOf;E0C1wOF;IAoIM,UAAU;IACV,UAAU;E1CyoOd;E0C9wOF;IAwIM,UAAU;IACV,eAAe;E1CyoOnB;E0ClxOF;IA4IM,UAAU;IACV,UAAU;E1CyoOd;E0CtxOF;IAgJM,UAAU;IACV,eAAe;E1CyoOnB;E0C1xOF;IAoJM,UAAU;IACV,UAAU;E1CyoOd;E0C9xOF;IAwJM,UAAU;IACV,UAAU;E1CyoOd;E0ClyOF;IA4JM,UAAU;IACV,UAAU;E1CyoOd;E0CtyOF;IAgKM,UAAU;IACV,UAAU;E1CyoOd;E0C1yOF;IAoKM,UAAU;IACV,UAAU;E1CyoOd;E0C9yOF;IzCgLI,gByCRqC;E1CyoOvC;E0CjzOF;IzCgLI,qByCL0C;E1CyoO5C;E0CpzOF;IzCgLI,gByCFqC;E1CyoOvC;E0CvzOF;IzCgLI,qByCC0C;E1CyoO5C;E0C1zOF;IzCgLI,gByCIqC;E1CyoOvC;E0C7zOF;IzCgLI,gByCOqC;E1CyoOvC;E0Ch0OF;IzCgLI,gByCUqC;E1CyoOvC;E0Cn0OF;IzCgLI,gByCaqC;E1CyoOvC;E0Ct0OF;IzCgLI,gByCgBqC;E1CyoOvC;E0Cz0OF;IAoMQ,UAAU;IACV,SAAiC;E1CwoOvC;E0C70OF;IzCgLI,eyCwB8D;E1CwoOhE;E0Ch1OF;IAoMQ,UAAU;IACV,eAAiC;E1C+oOvC;E0Cp1OF;IzCgLI,qByCwB8D;E1C+oOhE;E0Cv1OF;IAoMQ,UAAU;IACV,gBAAiC;E1CspOvC;E0C31OF;IzCgLI,sByCwB8D;E1CspOhE;E0C91OF;IAoMQ,UAAU;IACV,UAAiC;E1C6pOvC;E0Cl2OF;IzCgLI,gByCwB8D;E1C6pOhE;E0Cr2OF;IAoMQ,UAAU;IACV,gBAAiC;E1CoqOvC;E0Cz2OF;IzCgLI,sByCwB8D;E1CoqOhE;E0C52OF;IAoMQ,UAAU;IACV,gBAAiC;E1C2qOvC;E0Ch3OF;IzCgLI,sByCwB8D;E1C2qOhE;E0Cn3OF;IAoMQ,UAAU;IACV,UAAiC;E1CkrOvC;E0Cv3OF;IzCgLI,gByCwB8D;E1CkrOhE;E0C13OF;IAoMQ,UAAU;IACV,gBAAiC;E1CyrOvC;E0C93OF;IzCgLI,sByCwB8D;E1CyrOhE;E0Cj4OF;IAoMQ,UAAU;IACV,gBAAiC;E1CgsOvC;E0Cr4OF;IzCgLI,sByCwB8D;E1CgsOhE;E0Cx4OF;IAoMQ,UAAU;IACV,UAAiC;E1CusOvC;E0C54OF;IzCgLI,gByCwB8D;E1CusOhE;E0C/4OF;IAoMQ,UAAU;IACV,gBAAiC;E1C8sOvC;E0Cn5OF;IzCgLI,sByCwB8D;E1C8sOhE;E0Ct5OF;IAoMQ,UAAU;IACV,gBAAiC;E1CqtOvC;E0C15OF;IzCgLI,sByCwB8D;E1CqtOhE;E0C75OF;IAoMQ,UAAU;IACV,WAAiC;E1C4tOvC;E0Cj6OF;IzCgLI,iByCwB8D;E1C4tOhE;AACF;;ACvzOE;EyC9GF;IA2MM,UAAU;IACV,YAAY;E1C+tOhB;E0C36OF;IA8MM,UAAU;IACV,WAAW;E1CguOf;E0C/6OF;IAiNM,UAAU;IACV,UAAU;E1CiuOd;E0Cn7OF;IAoNM,UAAU;IACV,eAAe;E1CkuOnB;E0Cv7OF;IAuNM,UAAU;IACV,UAAU;E1CmuOd;E0C37OF;IA0NM,UAAU;IACV,eAAe;E1CouOnB;E0C/7OF;IA6NM,UAAU;IACV,UAAU;E1CquOd;E0Cn8OF;IAgOM,UAAU;IACV,UAAU;E1CsuOd;E0Cv8OF;IAmOM,UAAU;IACV,UAAU;E1CuuOd;E0C38OF;IAsOM,UAAU;IACV,UAAU;E1CwuOd;E0C/8OF;IAyOM,UAAU;IACV,UAAU;E1CyuOd;E0Cn9OF;IzCgLI,gByC4DqC;E1C0uOvC;E0Ct9OF;IzCgLI,qByC8D0C;E1C2uO5C;E0Cz9OF;IzCgLI,gByCgEqC;E1C4uOvC;E0C59OF;IzCgLI,qByCkE0C;E1C6uO5C;E0C/9OF;IzCgLI,gByCoEqC;E1C8uOvC;E0Cl+OF;IzCgLI,gByCsEqC;E1C+uOvC;E0Cr+OF;IzCgLI,gByCwEqC;E1CgvOvC;E0Cx+OF;IzCgLI,gByC0EqC;E1CivOvC;E0C3+OF;IzCgLI,gByC4EqC;E1CkvOvC;E0C9+OF;IA+PQ,UAAU;IACV,SAAiC;E1CkvOvC;E0Cl/OF;IzCgLI,eyCkF8D;E1CmvOhE;E0Cr/OF;IA+PQ,UAAU;IACV,eAAiC;E1CyvOvC;E0Cz/OF;IzCgLI,qByCkF8D;E1C0vOhE;E0C5/OF;IA+PQ,UAAU;IACV,gBAAiC;E1CgwOvC;E0ChgPF;IzCgLI,sByCkF8D;E1CiwOhE;E0CngPF;IA+PQ,UAAU;IACV,UAAiC;E1CuwOvC;E0CvgPF;IzCgLI,gByCkF8D;E1CwwOhE;E0C1gPF;IA+PQ,UAAU;IACV,gBAAiC;E1C8wOvC;E0C9gPF;IzCgLI,sByCkF8D;E1C+wOhE;E0CjhPF;IA+PQ,UAAU;IACV,gBAAiC;E1CqxOvC;E0CrhPF;IzCgLI,sByCkF8D;E1CsxOhE;E0CxhPF;IA+PQ,UAAU;IACV,UAAiC;E1C4xOvC;E0C5hPF;IzCgLI,gByCkF8D;E1C6xOhE;E0C/hPF;IA+PQ,UAAU;IACV,gBAAiC;E1CmyOvC;E0CniPF;IzCgLI,sByCkF8D;E1CoyOhE;E0CtiPF;IA+PQ,UAAU;IACV,gBAAiC;E1C0yOvC;E0C1iPF;IzCgLI,sByCkF8D;E1C2yOhE;E0C7iPF;IA+PQ,UAAU;IACV,UAAiC;E1CizOvC;E0CjjPF;IzCgLI,gByCkF8D;E1CkzOhE;E0CpjPF;IA+PQ,UAAU;IACV,gBAAiC;E1CwzOvC;E0CxjPF;IzCgLI,sByCkF8D;E1CyzOhE;E0C3jPF;IA+PQ,UAAU;IACV,gBAAiC;E1C+zOvC;E0C/jPF;IzCgLI,sByCkF8D;E1Cg0OhE;E0ClkPF;IA+PQ,UAAU;IACV,WAAiC;E1Cs0OvC;E0CtkPF;IzCgLI,iByCkF8D;E1Cu0OhE;AACF;;ACx9OE;EyClHF;IAqQM,UAAU;IACV,YAAY;E1C00OhB;E0ChlPF;IAwQM,UAAU;IACV,WAAW;E1C20Of;E0CplPF;IA2QM,UAAU;IACV,UAAU;E1C40Od;E0CxlPF;IA8QM,UAAU;IACV,eAAe;E1C60OnB;E0C5lPF;IAiRM,UAAU;IACV,UAAU;E1C80Od;E0ChmPF;IAoRM,UAAU;IACV,eAAe;E1C+0OnB;E0CpmPF;IAuRM,UAAU;IACV,UAAU;E1Cg1Od;E0CxmPF;IA0RM,UAAU;IACV,UAAU;E1Ci1Od;E0C5mPF;IA6RM,UAAU;IACV,UAAU;E1Ck1Od;E0ChnPF;IAgSM,UAAU;IACV,UAAU;E1Cm1Od;E0CpnPF;IAmSM,UAAU;IACV,UAAU;E1Co1Od;E0CxnPF;IzCgLI,gByCsHqC;E1Cq1OvC;E0C3nPF;IzCgLI,qByCwH0C;E1Cs1O5C;E0C9nPF;IzCgLI,gByC0HqC;E1Cu1OvC;E0CjoPF;IzCgLI,qByC4H0C;E1Cw1O5C;E0CpoPF;IzCgLI,gByC8HqC;E1Cy1OvC;E0CvoPF;IzCgLI,gByCgIqC;E1C01OvC;E0C1oPF;IzCgLI,gByCkIqC;E1C21OvC;E0C7oPF;IzCgLI,gByCoIqC;E1C41OvC;E0ChpPF;IzCgLI,gByCsIqC;E1C61OvC;E0CnpPF;IAyTQ,UAAU;IACV,SAAiC;E1C61OvC;E0CvpPF;IzCgLI,eyC4I8D;E1C81OhE;E0C1pPF;IAyTQ,UAAU;IACV,eAAiC;E1Co2OvC;E0C9pPF;IzCgLI,qByC4I8D;E1Cq2OhE;E0CjqPF;IAyTQ,UAAU;IACV,gBAAiC;E1C22OvC;E0CrqPF;IzCgLI,sByC4I8D;E1C42OhE;E0CxqPF;IAyTQ,UAAU;IACV,UAAiC;E1Ck3OvC;E0C5qPF;IzCgLI,gByC4I8D;E1Cm3OhE;E0C/qPF;IAyTQ,UAAU;IACV,gBAAiC;E1Cy3OvC;E0CnrPF;IzCgLI,sByC4I8D;E1C03OhE;E0CtrPF;IAyTQ,UAAU;IACV,gBAAiC;E1Cg4OvC;E0C1rPF;IzCgLI,sByC4I8D;E1Ci4OhE;E0C7rPF;IAyTQ,UAAU;IACV,UAAiC;E1Cu4OvC;E0CjsPF;IzCgLI,gByC4I8D;E1Cw4OhE;E0CpsPF;IAyTQ,UAAU;IACV,gBAAiC;E1C84OvC;E0CxsPF;IzCgLI,sByC4I8D;E1C+4OhE;E0C3sPF;IAyTQ,UAAU;IACV,gBAAiC;E1Cq5OvC;E0C/sPF;IzCgLI,sByC4I8D;E1Cs5OhE;E0CltPF;IAyTQ,UAAU;IACV,UAAiC;E1C45OvC;E0CttPF;IzCgLI,gByC4I8D;E1C65OhE;E0CztPF;IAyTQ,UAAU;IACV,gBAAiC;E1Cm6OvC;E0C7tPF;IzCgLI,sByC4I8D;E1Co6OhE;E0ChuPF;IAyTQ,UAAU;IACV,gBAAiC;E1C06OvC;E0CpuPF;IzCgLI,sByC4I8D;E1C26OhE;E0CvuPF;IAyTQ,UAAU;IACV,WAAiC;E1Ci7OvC;E0C3uPF;IzCgLI,iByC4I8D;E1Ck7OhE;AACF;;AC9mPI;EyCjIJ;IA+TM,UAAU;IACV,YAAY;E1Cq7OhB;E0CrvPF;IAkUM,UAAU;IACV,WAAW;E1Cs7Of;E0CzvPF;IAqUM,UAAU;IACV,UAAU;E1Cu7Od;E0C7vPF;IAwUM,UAAU;IACV,eAAe;E1Cw7OnB;E0CjwPF;IA2UM,UAAU;IACV,UAAU;E1Cy7Od;E0CrwPF;IA8UM,UAAU;IACV,eAAe;E1C07OnB;E0CzwPF;IAiVM,UAAU;IACV,UAAU;E1C27Od;E0C7wPF;IAoVM,UAAU;IACV,UAAU;E1C47Od;E0CjxPF;IAuVM,UAAU;IACV,UAAU;E1C67Od;E0CrxPF;IA0VM,UAAU;IACV,UAAU;E1C87Od;E0CzxPF;IA6VM,UAAU;IACV,UAAU;E1C+7Od;E0C7xPF;IzCgLI,gByCgLqC;E1Cg8OvC;E0ChyPF;IzCgLI,qByCkL0C;E1Ci8O5C;E0CnyPF;IzCgLI,gByCoLqC;E1Ck8OvC;E0CtyPF;IzCgLI,qByCsL0C;E1Cm8O5C;E0CzyPF;IzCgLI,gByCwLqC;E1Co8OvC;E0C5yPF;IzCgLI,gByC0LqC;E1Cq8OvC;E0C/yPF;IzCgLI,gByC4LqC;E1Cs8OvC;E0ClzPF;IzCgLI,gByC8LqC;E1Cu8OvC;E0CrzPF;IzCgLI,gByCgMqC;E1Cw8OvC;E0CxzPF;IAmXQ,UAAU;IACV,SAAiC;E1Cw8OvC;E0C5zPF;IzCgLI,eyCsM8D;E1Cy8OhE;E0C/zPF;IAmXQ,UAAU;IACV,eAAiC;E1C+8OvC;E0Cn0PF;IzCgLI,qByCsM8D;E1Cg9OhE;E0Ct0PF;IAmXQ,UAAU;IACV,gBAAiC;E1Cs9OvC;E0C10PF;IzCgLI,sByCsM8D;E1Cu9OhE;E0C70PF;IAmXQ,UAAU;IACV,UAAiC;E1C69OvC;E0Cj1PF;IzCgLI,gByCsM8D;E1C89OhE;E0Cp1PF;IAmXQ,UAAU;IACV,gBAAiC;E1Co+OvC;E0Cx1PF;IzCgLI,sByCsM8D;E1Cq+OhE;E0C31PF;IAmXQ,UAAU;IACV,gBAAiC;E1C2+OvC;E0C/1PF;IzCgLI,sByCsM8D;E1C4+OhE;E0Cl2PF;IAmXQ,UAAU;IACV,UAAiC;E1Ck/OvC;E0Ct2PF;IzCgLI,gByCsM8D;E1Cm/OhE;E0Cz2PF;IAmXQ,UAAU;IACV,gBAAiC;E1Cy/OvC;E0C72PF;IzCgLI,sByCsM8D;E1C0/OhE;E0Ch3PF;IAmXQ,UAAU;IACV,gBAAiC;E1CggPvC;E0Cp3PF;IzCgLI,sByCsM8D;E1CigPhE;E0Cv3PF;IAmXQ,UAAU;IACV,UAAiC;E1CugPvC;E0C33PF;IzCgLI,gByCsM8D;E1CwgPhE;E0C93PF;IAmXQ,UAAU;IACV,gBAAiC;E1C8gPvC;E0Cl4PF;IzCgLI,sByCsM8D;E1C+gPhE;E0Cr4PF;IAmXQ,UAAU;IACV,gBAAiC;E1CqhPvC;E0Cz4PF;IzCgLI,sByCsM8D;E1CshPhE;E0C54PF;IAmXQ,UAAU;IACV,WAAiC;E1C4hPvC;E0Ch5PF;IzCgLI,iByCsM8D;E1C6hPhE;AACF;;ACpwPI;EyChJJ;IAyXM,UAAU;IACV,YAAY;E1CgiPhB;E0C15PF;IA4XM,UAAU;IACV,WAAW;E1CiiPf;E0C95PF;IA+XM,UAAU;IACV,UAAU;E1CkiPd;E0Cl6PF;IAkYM,UAAU;IACV,eAAe;E1CmiPnB;E0Ct6PF;IAqYM,UAAU;IACV,UAAU;E1CoiPd;E0C16PF;IAwYM,UAAU;IACV,eAAe;E1CqiPnB;E0C96PF;IA2YM,UAAU;IACV,UAAU;E1CsiPd;E0Cl7PF;IA8YM,UAAU;IACV,UAAU;E1CuiPd;E0Ct7PF;IAiZM,UAAU;IACV,UAAU;E1CwiPd;E0C17PF;IAoZM,UAAU;IACV,UAAU;E1CyiPd;E0C97PF;IAuZM,UAAU;IACV,UAAU;E1C0iPd;E0Cl8PF;IzCgLI,gByC0OqC;E1C2iPvC;E0Cr8PF;IzCgLI,qByC4O0C;E1C4iP5C;E0Cx8PF;IzCgLI,gByC8OqC;E1C6iPvC;E0C38PF;IzCgLI,qByCgP0C;E1C8iP5C;E0C98PF;IzCgLI,gByCkPqC;E1C+iPvC;E0Cj9PF;IzCgLI,gByCoPqC;E1CgjPvC;E0Cp9PF;IzCgLI,gByCsPqC;E1CijPvC;E0Cv9PF;IzCgLI,gByCwPqC;E1CkjPvC;E0C19PF;IzCgLI,gByC0PqC;E1CmjPvC;E0C79PF;IA6aQ,UAAU;IACV,SAAiC;E1CmjPvC;E0Cj+PF;IzCgLI,eyCgQ8D;E1CojPhE;E0Cp+PF;IA6aQ,UAAU;IACV,eAAiC;E1C0jPvC;E0Cx+PF;IzCgLI,qByCgQ8D;E1C2jPhE;E0C3+PF;IA6aQ,UAAU;IACV,gBAAiC;E1CikPvC;E0C/+PF;IzCgLI,sByCgQ8D;E1CkkPhE;E0Cl/PF;IA6aQ,UAAU;IACV,UAAiC;E1CwkPvC;E0Ct/PF;IzCgLI,gByCgQ8D;E1CykPhE;E0Cz/PF;IA6aQ,UAAU;IACV,gBAAiC;E1C+kPvC;E0C7/PF;IzCgLI,sByCgQ8D;E1CglPhE;E0ChgQF;IA6aQ,UAAU;IACV,gBAAiC;E1CslPvC;E0CpgQF;IzCgLI,sByCgQ8D;E1CulPhE;E0CvgQF;IA6aQ,UAAU;IACV,UAAiC;E1C6lPvC;E0C3gQF;IzCgLI,gByCgQ8D;E1C8lPhE;E0C9gQF;IA6aQ,UAAU;IACV,gBAAiC;E1ComPvC;E0ClhQF;IzCgLI,sByCgQ8D;E1CqmPhE;E0CrhQF;IA6aQ,UAAU;IACV,gBAAiC;E1C2mPvC;E0CzhQF;IzCgLI,sByCgQ8D;E1C4mPhE;E0C5hQF;IA6aQ,UAAU;IACV,UAAiC;E1CknPvC;E0ChiQF;IzCgLI,gByCgQ8D;E1CmnPhE;E0CniQF;IA6aQ,UAAU;IACV,gBAAiC;E1CynPvC;E0CviQF;IzCgLI,sByCgQ8D;E1C0nPhE;E0C1iQF;IA6aQ,UAAU;IACV,gBAAiC;E1CgoPvC;E0C9iQF;IzCgLI,sByCgQ8D;E1CioPhE;E0CjjQF;IA6aQ,UAAU;IACV,WAAiC;E1CuoPvC;E0CrjQF;IzCgLI,iByCgQ8D;E1CwoPhE;AACF;;A0CvoPA;EzClQI,qByClLgB;EzCkLhB,sByClLgB;EAublB,oBAvbkB;A1CikQpB;;A0C7oPA;EAKI,uBAzbgB;A1CqkQpB;;A0CjpPA;EAOI,qCAA4C;A1C8oPhD;;A0CrpPA;EAUI,uBAAuB;A1C+oP3B;;A0CzpPA;EzClQI,cyC8QiC;EzC9QjC,eyC+QiC;EACjC,aAAa;A1CipPjB;;A0C/pPA;EAgBM,SAAS;EACT,qBAAqB;A1CmpP3B;;A0CpqPA;EAmBM,qBAAqB;A1CqpP3B;;A0CxqPA;EAqBM,gBAAgB;A1CupPtB;;A0C5qPA;EAuBI,aAAa;A1CypPjB;;A0ChrPA;EAyBI,eAAe;A1C2pPnB;;A0CprPA;EA2BI,mBAAmB;A1C6pPvB;;ACpgQE;EyC4UF;IA+BM,aAAa;E1C8pPjB;AACF;;AC9/PE;EyCgUF;IAmCM,aAAa;E1CgqPjB;AACF;;A0C9pPE;EACE,oBAAY;EzCzSZ,wCyC0S2D;EzC1S3D,yCyC2S2D;A1CiqP/D;;A0CpqPE;EAKI,8BAA8B;EAC9B,+BAA+B;A1CmqPrC;;A0CzqPE;EASM,iBAAY;A1CoqPpB;;ACniQE;EyCsXA;IAYQ,iBAAY;E1CsqPpB;AACF;;ACriQE;EyCkXA;IAeQ,iBAAY;E1CyqPpB;AACF;;ACviQE;EyC8WA;IAkBQ,iBAAY;E1C4qPpB;AACF;;ACziQE;EyC0WA;IAqBQ,iBAAY;E1C+qPpB;AACF;;AC3iQE;EyCsWA;IAwBQ,iBAAY;E1CkrPpB;AACF;;AC5iQI;EyCiWF;IA2BQ,iBAAY;E1CqrPpB;AACF;;ACxiQI;EyCuVF;IA8BQ,iBAAY;E1CwrPpB;AACF;;ACziQI;EyCkVF;IAiCQ,iBAAY;E1C2rPpB;AACF;;ACriQI;EyCwUF;IAoCQ,iBAAY;E1C8rPpB;AACF;;A0CnuPE;EASM,oBAAY;A1C8tPpB;;AC7lQE;EyCsXA;IAYQ,oBAAY;E1CguPpB;AACF;;AC/lQE;EyCkXA;IAeQ,oBAAY;E1CmuPpB;AACF;;ACjmQE;EyC8WA;IAkBQ,oBAAY;E1CsuPpB;AACF;;ACnmQE;EyC0WA;IAqBQ,oBAAY;E1CyuPpB;AACF;;ACrmQE;EyCsWA;IAwBQ,oBAAY;E1C4uPpB;AACF;;ACtmQI;EyCiWF;IA2BQ,oBAAY;E1C+uPpB;AACF;;AClmQI;EyCuVF;IA8BQ,oBAAY;E1CkvPpB;AACF;;ACnmQI;EyCkVF;IAiCQ,oBAAY;E1CqvPpB;AACF;;AC/lQI;EyCwUF;IAoCQ,oBAAY;E1CwvPpB;AACF;;A0C7xPE;EASM,mBAAY;A1CwxPpB;;ACvpQE;EyCsXA;IAYQ,mBAAY;E1C0xPpB;AACF;;ACzpQE;EyCkXA;IAeQ,mBAAY;E1C6xPpB;AACF;;AC3pQE;EyC8WA;IAkBQ,mBAAY;E1CgyPpB;AACF;;AC7pQE;EyC0WA;IAqBQ,mBAAY;E1CmyPpB;AACF;;AC/pQE;EyCsWA;IAwBQ,mBAAY;E1CsyPpB;AACF;;AChqQI;EyCiWF;IA2BQ,mBAAY;E1CyyPpB;AACF;;AC5pQI;EyCuVF;IA8BQ,mBAAY;E1C4yPpB;AACF;;AC7pQI;EyCkVF;IAiCQ,mBAAY;E1C+yPpB;AACF;;ACzpQI;EyCwUF;IAoCQ,mBAAY;E1CkzPpB;AACF;;A0Cv1PE;EASM,oBAAY;A1Ck1PpB;;ACjtQE;EyCsXA;IAYQ,oBAAY;E1Co1PpB;AACF;;ACntQE;EyCkXA;IAeQ,oBAAY;E1Cu1PpB;AACF;;ACrtQE;EyC8WA;IAkBQ,oBAAY;E1C01PpB;AACF;;ACvtQE;EyC0WA;IAqBQ,oBAAY;E1C61PpB;AACF;;ACztQE;EyCsWA;IAwBQ,oBAAY;E1Cg2PpB;AACF;;AC1tQI;EyCiWF;IA2BQ,oBAAY;E1Cm2PpB;AACF;;ACttQI;EyCuVF;IA8BQ,oBAAY;E1Cs2PpB;AACF;;ACvtQI;EyCkVF;IAiCQ,oBAAY;E1Cy2PpB;AACF;;ACntQI;EyCwUF;IAoCQ,oBAAY;E1C42PpB;AACF;;A0Cj5PE;EASM,iBAAY;A1C44PpB;;AC3wQE;EyCsXA;IAYQ,iBAAY;E1C84PpB;AACF;;AC7wQE;EyCkXA;IAeQ,iBAAY;E1Ci5PpB;AACF;;AC/wQE;EyC8WA;IAkBQ,iBAAY;E1Co5PpB;AACF;;ACjxQE;EyC0WA;IAqBQ,iBAAY;E1Cu5PpB;AACF;;ACnxQE;EyCsWA;IAwBQ,iBAAY;E1C05PpB;AACF;;ACpxQI;EyCiWF;IA2BQ,iBAAY;E1C65PpB;AACF;;AChxQI;EyCuVF;IA8BQ,iBAAY;E1Cg6PpB;AACF;;ACjxQI;EyCkVF;IAiCQ,iBAAY;E1Cm6PpB;AACF;;AC7wQI;EyCwUF;IAoCQ,iBAAY;E1Cs6PpB;AACF;;A0C38PE;EASM,oBAAY;A1Cs8PpB;;ACr0QE;EyCsXA;IAYQ,oBAAY;E1Cw8PpB;AACF;;ACv0QE;EyCkXA;IAeQ,oBAAY;E1C28PpB;AACF;;ACz0QE;EyC8WA;IAkBQ,oBAAY;E1C88PpB;AACF;;AC30QE;EyC0WA;IAqBQ,oBAAY;E1Ci9PpB;AACF;;AC70QE;EyCsWA;IAwBQ,oBAAY;E1Co9PpB;AACF;;AC90QI;EyCiWF;IA2BQ,oBAAY;E1Cu9PpB;AACF;;AC10QI;EyCuVF;IA8BQ,oBAAY;E1C09PpB;AACF;;AC30QI;EyCkVF;IAiCQ,oBAAY;E1C69PpB;AACF;;ACv0QI;EyCwUF;IAoCQ,oBAAY;E1Cg+PpB;AACF;;A0CrgQE;EASM,mBAAY;A1CggQpB;;AC/3QE;EyCsXA;IAYQ,mBAAY;E1CkgQpB;AACF;;ACj4QE;EyCkXA;IAeQ,mBAAY;E1CqgQpB;AACF;;ACn4QE;EyC8WA;IAkBQ,mBAAY;E1CwgQpB;AACF;;ACr4QE;EyC0WA;IAqBQ,mBAAY;E1C2gQpB;AACF;;ACv4QE;EyCsWA;IAwBQ,mBAAY;E1C8gQpB;AACF;;ACx4QI;EyCiWF;IA2BQ,mBAAY;E1CihQpB;AACF;;ACp4QI;EyCuVF;IA8BQ,mBAAY;E1CohQpB;AACF;;ACr4QI;EyCkVF;IAiCQ,mBAAY;E1CuhQpB;AACF;;ACj4QI;EyCwUF;IAoCQ,mBAAY;E1C0hQpB;AACF;;A0C/jQE;EASM,oBAAY;A1C0jQpB;;ACz7QE;EyCsXA;IAYQ,oBAAY;E1C4jQpB;AACF;;AC37QE;EyCkXA;IAeQ,oBAAY;E1C+jQpB;AACF;;AC77QE;EyC8WA;IAkBQ,oBAAY;E1CkkQpB;AACF;;AC/7QE;EyC0WA;IAqBQ,oBAAY;E1CqkQpB;AACF;;ACj8QE;EyCsWA;IAwBQ,oBAAY;E1CwkQpB;AACF;;ACl8QI;EyCiWF;IA2BQ,oBAAY;E1C2kQpB;AACF;;AC97QI;EyCuVF;IA8BQ,oBAAY;E1C8kQpB;AACF;;AC/7QI;EyCkVF;IAiCQ,oBAAY;E1CilQpB;AACF;;AC37QI;EyCwUF;IAoCQ,oBAAY;E1ColQpB;AACF;;A0CznQE;EASM,iBAAY;A1ConQpB;;ACn/QE;EyCsXA;IAYQ,iBAAY;E1CsnQpB;AACF;;ACr/QE;EyCkXA;IAeQ,iBAAY;E1CynQpB;AACF;;ACv/QE;EyC8WA;IAkBQ,iBAAY;E1C4nQpB;AACF;;ACz/QE;EyC0WA;IAqBQ,iBAAY;E1C+nQpB;AACF;;AC3/QE;EyCsWA;IAwBQ,iBAAY;E1CkoQpB;AACF;;AC5/QI;EyCiWF;IA2BQ,iBAAY;E1CqoQpB;AACF;;ACx/QI;EyCuVF;IA8BQ,iBAAY;E1CwoQpB;AACF;;ACz/QI;EyCkVF;IAiCQ,iBAAY;E1C2oQpB;AACF;;ACr/QI;EyCwUF;IAoCQ,iBAAY;E1C8oQpB;AACF;;A2C3oRA;EACE,oBAAoB;EACpB,cAAc;EACd,aAAa;EACb,YAAY;EACZ,cAAc;EACd,+BAAuB;EAAvB,4BAAuB;EAAvB,uBAAuB;A3C8oRzB;;A2CppRA;EASI,qBAA+B;EAC/B,sBAAgC;EAChC,oBAA8B;A3C+oRlC;;A2C1pRA;EAaM,uBAAiC;A3CipRvC;;A2C9pRA;EAeM,sBAjBgB;A3CoqRtB;;A2ClqRA;EAiBI,oBAAoB;A3CqpRxB;;A2CtqRA;EAmBI,gBArBkB;A3C4qRtB;;A2C1qRA;EAqBI,sBAAsB;A3CypR1B;;A2C9qRA;EAuBM,gCAAgC;A3C2pRtC;;AC5kRE;E0CtGF;IA2BM,aAAa;E3C4pRjB;E2CvrRF;IA8BQ,UAAU;IACV,eAA8B;E3C4pRpC;E2C3rRF;IA8BQ,UAAU;IACV,gBAA8B;E3CgqRpC;E2C/rRF;IA8BQ,UAAU;IACV,UAA8B;E3CoqRpC;E2CnsRF;IA8BQ,UAAU;IACV,gBAA8B;E3CwqRpC;E2CvsRF;IA8BQ,UAAU;IACV,gBAA8B;E3C4qRpC;E2C3sRF;IA8BQ,UAAU;IACV,UAA8B;E3CgrRpC;E2C/sRF;IA8BQ,UAAU;IACV,gBAA8B;E3CorRpC;E2CntRF;IA8BQ,UAAU;IACV,gBAA8B;E3CwrRpC;E2CvtRF;IA8BQ,UAAU;IACV,UAA8B;E3C4rRpC;E2C3tRF;IA8BQ,UAAU;IACV,gBAA8B;E3CgsRpC;E2C/tRF;IA8BQ,UAAU;IACV,gBAA8B;E3CosRpC;E2CnuRF;IA8BQ,UAAU;IACV,WAA8B;E3CwsRpC;AACF;;A4C5uRA,kBAAA;ACIE;EACE,uBAAwB;A7C4uR5B;;A6C3uRE;EAGI,yBAA0C;A7C4uRhD;;A6C3uRE;EACE,kCAAmC;A7C8uRvC;;A6CrvRE;EACE,yBAAwB;A7CwvR5B;;A6CvvRE;EAGI,uBAA0C;A7CwvRhD;;A6CvvRE;EACE,oCAAmC;A7C0vRvC;;A6CjwRE;EACE,4BAAwB;A7CowR5B;;A6CnwRE;EAGI,yBAA0C;A7CowRhD;;A6CnwRE;EACE,uCAAmC;A7CswRvC;;A6C7wRE;EACE,yBAAwB;A7CgxR5B;;A6C/wRE;EAGI,yBAA0C;A7CgxRhD;;A6C/wRE;EACE,oCAAmC;A7CkxRvC;;A6CzxRE;EACE,yBAAwB;A7C4xR5B;;A6C3xRE;EAGI,yBAA0C;A7C4xRhD;;A6C3xRE;EACE,oCAAmC;A7C8xRvC;;A6CzxRI;EACE,yBAA8B;A7C4xRpC;;A6C3xRI;EAGI,yBAAgD;A7C4xRxD;;A6C3xRI;EACE,oCAAyC;A7C8xR/C;;A6C5xRI;EACE,yBAA6B;A7C+xRnC;;A6C9xRI;EAGI,yBAAgD;A7C+xRxD;;A6C9xRI;EACE,oCAAwC;A7CiyR9C;;A6C7zRE;EACE,yBAAwB;A7Cg0R5B;;A6C/zRE;EAGI,yBAA0C;A7Cg0RhD;;A6C/zRE;EACE,oCAAmC;A7Ck0RvC;;A6C7zRI;EACE,yBAA8B;A7Cg0RpC;;A6C/zRI;EAGI,yBAAgD;A7Cg0RxD;;A6C/zRI;EACE,oCAAyC;A7Ck0R/C;;A6Ch0RI;EACE,yBAA6B;A7Cm0RnC;;A6Cl0RI;EAGI,yBAAgD;A7Cm0RxD;;A6Cl0RI;EACE,oCAAwC;A7Cq0R9C;;A6Cj2RE;EACE,yBAAwB;A7Co2R5B;;A6Cn2RE;EAGI,yBAA0C;A7Co2RhD;;A6Cn2RE;EACE,oCAAmC;A7Cs2RvC;;A6Cj2RI;EACE,yBAA8B;A7Co2RpC;;A6Cn2RI;EAGI,yBAAgD;A7Co2RxD;;A6Cn2RI;EACE,oCAAyC;A7Cs2R/C;;A6Cp2RI;EACE,yBAA6B;A7Cu2RnC;;A6Ct2RI;EAGI,yBAAgD;A7Cu2RxD;;A6Ct2RI;EACE,oCAAwC;A7Cy2R9C;;A6Cr4RE;EACE,yBAAwB;A7Cw4R5B;;A6Cv4RE;EAGI,yBAA0C;A7Cw4RhD;;A6Cv4RE;EACE,oCAAmC;A7C04RvC;;A6Cr4RI;EACE,yBAA8B;A7Cw4RpC;;A6Cv4RI;EAGI,yBAAgD;A7Cw4RxD;;A6Cv4RI;EACE,oCAAyC;A7C04R/C;;A6Cx4RI;EACE,yBAA6B;A7C24RnC;;A6C14RI;EAGI,yBAAgD;A7C24RxD;;A6C14RI;EACE,oCAAwC;A7C64R9C;;A6Cz6RE;EACE,yBAAwB;A7C46R5B;;A6C36RE;EAGI,yBAA0C;A7C46RhD;;A6C36RE;EACE,oCAAmC;A7C86RvC;;A6Cz6RI;EACE,yBAA8B;A7C46RpC;;A6C36RI;EAGI,yBAAgD;A7C46RxD;;A6C36RI;EACE,oCAAyC;A7C86R/C;;A6C56RI;EACE,yBAA6B;A7C+6RnC;;A6C96RI;EAGI,yBAAgD;A7C+6RxD;;A6C96RI;EACE,oCAAwC;A7Ci7R9C;;A6C78RE;EACE,yBAAwB;A7Cg9R5B;;A6C/8RE;EAGI,yBAA0C;A7Cg9RhD;;A6C/8RE;EACE,oCAAmC;A7Ck9RvC;;A6C78RI;EACE,yBAA8B;A7Cg9RpC;;A6C/8RI;EAGI,yBAAgD;A7Cg9RxD;;A6C/8RI;EACE,oCAAyC;A7Ck9R/C;;A6Ch9RI;EACE,yBAA6B;A7Cm9RnC;;A6Cl9RI;EAGI,yBAAgD;A7Cm9RxD;;A6Cl9RI;EACE,oCAAwC;A7Cq9R9C;;A6Cl9RE;EACE,yBAAwB;A7Cq9R5B;;A6Cp9RE;EACE,oCAAmC;A7Cu9RvC;;A6C19RE;EACE,yBAAwB;A7C69R5B;;A6C59RE;EACE,oCAAmC;A7C+9RvC;;A6Cl+RE;EACE,yBAAwB;A7Cq+R5B;;A6Cp+RE;EACE,oCAAmC;A7Cu+RvC;;A6C1+RE;EACE,yBAAwB;A7C6+R5B;;A6C5+RE;EACE,oCAAmC;A7C++RvC;;A6Cl/RE;EACE,yBAAwB;A7Cq/R5B;;A6Cp/RE;EACE,oCAAmC;A7Cu/RvC;;A6C1/RE;EACE,yBAAwB;A7C6/R5B;;A6C5/RE;EACE,oCAAmC;A7C+/RvC;;A6ClgSE;EACE,yBAAwB;A7CqgS5B;;A6CpgSE;EACE,oCAAmC;A7CugSvC;;A6C1gSE;EACE,4BAAwB;A7C6gS5B;;A6C5gSE;EACE,uCAAmC;A7C+gSvC;;A6ClhSE;EACE,yBAAwB;A7CqhS5B;;A6CphSE;EACE,oCAAmC;A7CuhSvC;;A8C3jSE;EACE,8BAAiC;A9C8jSrC;;A8C/jSE;EACE,sCAAiC;A9CkkSrC;;A8CnkSE;EACE,iCAAiC;A9CskSrC;;A8CvkSE;EACE,yCAAiC;A9C0kSrC;;A8CtkSE;EACE,4BAA4B;A9CykShC;;A8C1kSE;EACE,0BAA4B;A9C6kShC;;A8C9kSE;EACE,kCAA4B;A9CilShC;;A8C7kSE;EACE,sCAAkC;A9CglStC;;A8CjlSE;EACE,oCAAkC;A9ColStC;;A8CrlSE;EACE,kCAAkC;A9CwlStC;;A8CzlSE;EACE,yCAAkC;A9C4lStC;;A8C7lSE;EACE,wCAAkC;A9CgmStC;;A8CjmSE;EACE,wCAAkC;A9ComStC;;A8CrmSE;EACE,iCAAkC;A9CwmStC;;A8CzmSE;EACE,+BAAkC;A9C4mStC;;A8C7mSE;EACE,gCAAkC;A9CgnStC;;A8CjnSE;EACE,iCAAkC;A9ConStC;;A8ChnSE;EACE,oCAAgC;A9CmnSpC;;A8CpnSE;EACE,kCAAgC;A9CunSpC;;A8CxnSE;EACE,gCAAgC;A9C2nSpC;;A8C5nSE;EACE,uCAAgC;A9C+nSpC;;A8ChoSE;EACE,sCAAgC;A9CmoSpC;;A8CpoSE;EACE,sCAAgC;A9CuoSpC;;A8CxoSE;EACE,iCAAgC;A9C2oSpC;;A8C5oSE;EACE,+BAAgC;A9C+oSpC;;A8ChpSE;EACE,6BAAgC;A9CmpSpC;;A8CppSE;EACE,kCAAgC;A9CupSpC;;A8CnpSE;EACE,+BAA8B;A9CspSlC;;A8CvpSE;EACE,kCAA8B;A9C0pSlC;;A8C3pSE;EACE,gCAA8B;A9C8pSlC;;A8C/pSE;EACE,8BAA8B;A9CkqSlC;;A8CnqSE;EACE,gCAA8B;A9CsqSlC;;A8CvqSE;EACE,6BAA8B;A9C0qSlC;;A8C3qSE;EACE,2BAA8B;A9C8qSlC;;A8C/qSE;EACE,kCAA8B;A9CkrSlC;;A8CnrSE;EACE,gCAA8B;A9CsrSlC;;A8ClrSE;EACE,2BAA6B;A9CqrSjC;;A8CtrSE;EACE,iCAA6B;A9CyrSjC;;A8C1rSE;EACE,+BAA6B;A9C6rSjC;;A8C9rSE;EACE,6BAA6B;A9CisSjC;;A8ClsSE;EACE,+BAA6B;A9CqsSjC;;A8CtsSE;EACE,8BAA6B;A9CysSjC;;A8CpsSI;EACE,uBAAqC;A9CusS3C;;A8CxsSI;EACE,uBAAqC;A9C2sS3C;;A8C5sSI;EACE,uBAAqC;A9C+sS3C;;A8ChtSI;EACE,uBAAqC;A9CmtS3C;;A8CptSI;EACE,uBAAqC;A9CutS3C;;A8CxtSI;EACE,uBAAqC;A9C2tS3C;;A8C5tSI;EACE,yBAAqC;A9C+tS3C;;A8ChuSI;EACE,yBAAqC;A9CmuS3C;;A8CpuSI;EACE,yBAAqC;A9CuuS3C;;A8CxuSI;EACE,yBAAqC;A9C2uS3C;;A8C5uSI;EACE,yBAAqC;A9C+uS3C;;A8ChvSI;EACE,yBAAqC;A9CmvS3C;;AClxSE;EACE,WAAW;EACX,YAAY;EACZ,cAAc;ADqxSlB;;A+CtxSA;EACE,sBAAsB;A/CyxSxB;;A+CvxSA;EACE,uBAAuB;A/C0xSzB;;AgDjySA;EACE,2BAA2B;AhDoyS7B;;AgDlySA;EACE,2BAA2B;AhDqyS7B;;AgDnySA;EACE,0BAA0B;EAC1B,8BAA8B;AhDsyShC;;AiDhzSA;EACE,2BAA2B;AjDmzS7B;;AkD/ySA;EACE,6BAA6B;AlDkzS/B;;AmDxzSA;EACE,oBAAoB;AnD2zStB;;AmDzzSA;EACE,qBAAqB;AnD4zSvB;;AmDjzSI;EACE,oBAA+B;AnDozSrC;;AmDjzSM;EACE,wBAA8C;AnDozStD;;AmDrzSM;EACE,0BAA8C;AnDwzStD;;AmDzzSM;EACE,2BAA8C;AnD4zStD;;AmD7zSM;EACE,yBAA8C;AnDg0StD;;AmD7zSM;EACE,yBAAyC;EACzC,0BAA2C;AnDg0SnD;;AmD7zSM;EACE,wBAAuC;EACvC,2BAA6C;AnDg0SrD;;AmD/0SI;EACE,0BAA+B;AnDk1SrC;;AmD/0SM;EACE,8BAA8C;AnDk1StD;;AmDn1SM;EACE,gCAA8C;AnDs1StD;;AmDv1SM;EACE,iCAA8C;AnD01StD;;AmD31SM;EACE,+BAA8C;AnD81StD;;AmD31SM;EACE,+BAAyC;EACzC,gCAA2C;AnD81SnD;;AmD31SM;EACE,8BAAuC;EACvC,iCAA6C;AnD81SrD;;AmD72SI;EACE,yBAA+B;AnDg3SrC;;AmD72SM;EACE,6BAA8C;AnDg3StD;;AmDj3SM;EACE,+BAA8C;AnDo3StD;;AmDr3SM;EACE,gCAA8C;AnDw3StD;;AmDz3SM;EACE,8BAA8C;AnD43StD;;AmDz3SM;EACE,8BAAyC;EACzC,+BAA2C;AnD43SnD;;AmDz3SM;EACE,6BAAuC;EACvC,gCAA6C;AnD43SrD;;AmD34SI;EACE,0BAA+B;AnD84SrC;;AmD34SM;EACE,8BAA8C;AnD84StD;;AmD/4SM;EACE,gCAA8C;AnDk5StD;;AmDn5SM;EACE,iCAA8C;AnDs5StD;;AmDv5SM;EACE,+BAA8C;AnD05StD;;AmDv5SM;EACE,+BAAyC;EACzC,gCAA2C;AnD05SnD;;AmDv5SM;EACE,8BAAuC;EACvC,iCAA6C;AnD05SrD;;AmDz6SI;EACE,uBAA+B;AnD46SrC;;AmDz6SM;EACE,2BAA8C;AnD46StD;;AmD76SM;EACE,6BAA8C;AnDg7StD;;AmDj7SM;EACE,8BAA8C;AnDo7StD;;AmDr7SM;EACE,4BAA8C;AnDw7StD;;AmDr7SM;EACE,4BAAyC;EACzC,6BAA2C;AnDw7SnD;;AmDr7SM;EACE,2BAAuC;EACvC,8BAA6C;AnDw7SrD;;AmDv8SI;EACE,yBAA+B;AnD08SrC;;AmDv8SM;EACE,6BAA8C;AnD08StD;;AmD38SM;EACE,+BAA8C;AnD88StD;;AmD/8SM;EACE,gCAA8C;AnDk9StD;;AmDn9SM;EACE,8BAA8C;AnDs9StD;;AmDn9SM;EACE,8BAAyC;EACzC,+BAA2C;AnDs9SnD;;AmDn9SM;EACE,6BAAuC;EACvC,gCAA6C;AnDs9SrD;;AmDr+SI;EACE,uBAA+B;AnDw+SrC;;AmDr+SM;EACE,2BAA8C;AnDw+StD;;AmDz+SM;EACE,6BAA8C;AnD4+StD;;AmD7+SM;EACE,8BAA8C;AnDg/StD;;AmDj/SM;EACE,4BAA8C;AnDo/StD;;AmDj/SM;EACE,4BAAyC;EACzC,6BAA2C;AnDo/SnD;;AmDj/SM;EACE,2BAAuC;EACvC,8BAA6C;AnDo/SrD;;AmDngTI;EACE,uBAA+B;AnDsgTrC;;AmDngTM;EACE,2BAA8C;AnDsgTtD;;AmDvgTM;EACE,6BAA8C;AnD0gTtD;;AmD3gTM;EACE,8BAA8C;AnD8gTtD;;AmD/gTM;EACE,4BAA8C;AnDkhTtD;;AmD/gTM;EACE,4BAAyC;EACzC,6BAA2C;AnDkhTnD;;AmD/gTM;EACE,2BAAuC;EACvC,8BAA6C;AnDkhTrD;;AmDjiTI;EACE,qBAA+B;AnDoiTrC;;AmDjiTM;EACE,yBAA8C;AnDoiTtD;;AmDriTM;EACE,2BAA8C;AnDwiTtD;;AmDziTM;EACE,4BAA8C;AnD4iTtD;;AmD7iTM;EACE,0BAA8C;AnDgjTtD;;AmD7iTM;EACE,0BAAyC;EACzC,2BAA2C;AnDgjTnD;;AmD7iTM;EACE,yBAAuC;EACvC,4BAA6C;AnDgjTrD;;AmD/jTI;EACE,2BAA+B;AnDkkTrC;;AmD/jTM;EACE,+BAA8C;AnDkkTtD;;AmDnkTM;EACE,iCAA8C;AnDskTtD;;AmDvkTM;EACE,kCAA8C;AnD0kTtD;;AmD3kTM;EACE,gCAA8C;AnD8kTtD;;AmD3kTM;EACE,gCAAyC;EACzC,iCAA2C;AnD8kTnD;;AmD3kTM;EACE,+BAAuC;EACvC,kCAA6C;AnD8kTrD;;AmD7lTI;EACE,0BAA+B;AnDgmTrC;;AmD7lTM;EACE,8BAA8C;AnDgmTtD;;AmDjmTM;EACE,gCAA8C;AnDomTtD;;AmDrmTM;EACE,iCAA8C;AnDwmTtD;;AmDzmTM;EACE,+BAA8C;AnD4mTtD;;AmDzmTM;EACE,+BAAyC;EACzC,gCAA2C;AnD4mTnD;;AmDzmTM;EACE,8BAAuC;EACvC,iCAA6C;AnD4mTrD;;AmD3nTI;EACE,2BAA+B;AnD8nTrC;;AmD3nTM;EACE,+BAA8C;AnD8nTtD;;AmD/nTM;EACE,iCAA8C;AnDkoTtD;;AmDnoTM;EACE,kCAA8C;AnDsoTtD;;AmDvoTM;EACE,gCAA8C;AnD0oTtD;;AmDvoTM;EACE,gCAAyC;EACzC,iCAA2C;AnD0oTnD;;AmDvoTM;EACE,+BAAuC;EACvC,kCAA6C;AnD0oTrD;;AmDzpTI;EACE,wBAA+B;AnD4pTrC;;AmDzpTM;EACE,4BAA8C;AnD4pTtD;;AmD7pTM;EACE,8BAA8C;AnDgqTtD;;AmDjqTM;EACE,+BAA8C;AnDoqTtD;;AmDrqTM;EACE,6BAA8C;AnDwqTtD;;AmDrqTM;EACE,6BAAyC;EACzC,8BAA2C;AnDwqTnD;;AmDrqTM;EACE,4BAAuC;EACvC,+BAA6C;AnDwqTrD;;AmDvrTI;EACE,0BAA+B;AnD0rTrC;;AmDvrTM;EACE,8BAA8C;AnD0rTtD;;AmD3rTM;EACE,gCAA8C;AnD8rTtD;;AmD/rTM;EACE,iCAA8C;AnDksTtD;;AmDnsTM;EACE,+BAA8C;AnDssTtD;;AmDnsTM;EACE,+BAAyC;EACzC,gCAA2C;AnDssTnD;;AmDnsTM;EACE,8BAAuC;EACvC,iCAA6C;AnDssTrD;;AmDrtTI;EACE,wBAA+B;AnDwtTrC;;AmDrtTM;EACE,4BAA8C;AnDwtTtD;;AmDztTM;EACE,8BAA8C;AnD4tTtD;;AmD7tTM;EACE,+BAA8C;AnDguTtD;;AmDjuTM;EACE,6BAA8C;AnDouTtD;;AmDjuTM;EACE,6BAAyC;EACzC,8BAA2C;AnDouTnD;;AmDjuTM;EACE,4BAAuC;EACvC,+BAA6C;AnDouTrD;;AmDnvTI;EACE,wBAA+B;AnDsvTrC;;AmDnvTM;EACE,4BAA8C;AnDsvTtD;;AmDvvTM;EACE,8BAA8C;AnD0vTtD;;AmD3vTM;EACE,+BAA8C;AnD8vTtD;;AmD/vTM;EACE,6BAA8C;AnDkwTtD;;AmD/vTM;EACE,6BAAyC;EACzC,8BAA2C;AnDkwTnD;;AmD/vTM;EACE,4BAAuC;EACvC,+BAA6C;AnDkwTrD;;AoD3xTI;EACE,0BAA2B;ApD8xTjC;;AoD/xTI;EACE,4BAA2B;ApDkyTjC;;AoDnyTI;EACE,0BAA2B;ApDsyTjC;;AoDvyTI;EACE,4BAA2B;ApD0yTjC;;AoD3yTI;EACE,6BAA2B;ApD8yTjC;;AoD/yTI;EACE,0BAA2B;ApDkzTjC;;AoDnzTI;EACE,6BAA2B;ApDszTjC;;ACttTE;EmDjGE;IACE,0BAA2B;EpD2zT/B;EoD5zTE;IACE,4BAA2B;EpD8zT/B;EoD/zTE;IACE,0BAA2B;EpDi0T/B;EoDl0TE;IACE,4BAA2B;EpDo0T/B;EoDr0TE;IACE,6BAA2B;EpDu0T/B;EoDx0TE;IACE,0BAA2B;EpD00T/B;EoD30TE;IACE,6BAA2B;EpD60T/B;AACF;;AC1uTE;EmDrGE;IACE,0BAA2B;EpDm1T/B;EoDp1TE;IACE,4BAA2B;EpDs1T/B;EoDv1TE;IACE,0BAA2B;EpDy1T/B;EoD11TE;IACE,4BAA2B;EpD41T/B;EoD71TE;IACE,6BAA2B;EpD+1T/B;EoDh2TE;IACE,0BAA2B;EpDk2T/B;EoDn2TE;IACE,6BAA2B;EpDq2T/B;AACF;;AC1vTE;EmD7GE;IACE,0BAA2B;EpD22T/B;EoD52TE;IACE,4BAA2B;EpD82T/B;EoD/2TE;IACE,0BAA2B;EpDi3T/B;EoDl3TE;IACE,4BAA2B;EpDo3T/B;EoDr3TE;IACE,6BAA2B;EpDu3T/B;EoDx3TE;IACE,0BAA2B;EpD03T/B;EoD33TE;IACE,6BAA2B;EpD63T/B;AACF;;AC9wTE;EmDjHE;IACE,0BAA2B;EpDm4T/B;EoDp4TE;IACE,4BAA2B;EpDs4T/B;EoDv4TE;IACE,0BAA2B;EpDy4T/B;EoD14TE;IACE,4BAA2B;EpD44T/B;EoD74TE;IACE,6BAA2B;EpD+4T/B;EoDh5TE;IACE,0BAA2B;EpDk5T/B;EoDn5TE;IACE,6BAA2B;EpDq5T/B;AACF;;ACvxTI;EmDhIA;IACE,0BAA2B;EpD25T/B;EoD55TE;IACE,4BAA2B;EpD85T/B;EoD/5TE;IACE,0BAA2B;EpDi6T/B;EoDl6TE;IACE,4BAA2B;EpDo6T/B;EoDr6TE;IACE,6BAA2B;EpDu6T/B;EoDx6TE;IACE,0BAA2B;EpD06T/B;EoD36TE;IACE,6BAA2B;EpD66T/B;AACF;;AChyTI;EmD/IA;IACE,0BAA2B;EpDm7T/B;EoDp7TE;IACE,4BAA2B;EpDs7T/B;EoDv7TE;IACE,0BAA2B;EpDy7T/B;EoD17TE;IACE,4BAA2B;EpD47T/B;EoD77TE;IACE,6BAA2B;EpD+7T/B;EoDh8TE;IACE,0BAA2B;EpDk8T/B;EoDn8TE;IACE,6BAA2B;EpDq8T/B;AACF;;AoD76TE;EACE,6BAAqC;ApDg7TzC;;AoDj7TE;EACE,8BAAqC;ApDo7TzC;;AoDr7TE;EACE,2BAAqC;ApDw7TzC;;AoDz7TE;EACE,4BAAqC;ApD47TzC;;ACt3TE;EmDlEE;IACE,6BAAqC;EpD47TzC;AACF;;ACx3TE;EmDnEE;IACE,6BAAqC;EpD+7TzC;AACF;;AC13TE;EmDpEE;IACE,6BAAqC;EpDk8TzC;AACF;;AC53TE;EmDrEE;IACE,6BAAqC;EpDq8TzC;AACF;;AC93TE;EmDtEE;IACE,6BAAqC;EpDw8TzC;AACF;;AC/3TI;EmDxEA;IACE,6BAAqC;EpD28TzC;AACF;;AC33TI;EmD/EA;IACE,6BAAqC;EpD88TzC;AACF;;AC53TI;EmDjFA;IACE,6BAAqC;EpDi9TzC;AACF;;ACx3TI;EmDxFA;IACE,6BAAqC;EpDo9TzC;AACF;;AC56TE;EmDlEE;IACE,8BAAqC;EpDk/TzC;AACF;;AC96TE;EmDnEE;IACE,8BAAqC;EpDq/TzC;AACF;;ACh7TE;EmDpEE;IACE,8BAAqC;EpDw/TzC;AACF;;ACl7TE;EmDrEE;IACE,8BAAqC;EpD2/TzC;AACF;;ACp7TE;EmDtEE;IACE,8BAAqC;EpD8/TzC;AACF;;ACr7TI;EmDxEA;IACE,8BAAqC;EpDigUzC;AACF;;ACj7TI;EmD/EA;IACE,8BAAqC;EpDogUzC;AACF;;ACl7TI;EmDjFA;IACE,8BAAqC;EpDugUzC;AACF;;AC96TI;EmDxFA;IACE,8BAAqC;EpD0gUzC;AACF;;ACl+TE;EmDlEE;IACE,2BAAqC;EpDwiUzC;AACF;;ACp+TE;EmDnEE;IACE,2BAAqC;EpD2iUzC;AACF;;ACt+TE;EmDpEE;IACE,2BAAqC;EpD8iUzC;AACF;;ACx+TE;EmDrEE;IACE,2BAAqC;EpDijUzC;AACF;;AC1+TE;EmDtEE;IACE,2BAAqC;EpDojUzC;AACF;;AC3+TI;EmDxEA;IACE,2BAAqC;EpDujUzC;AACF;;ACv+TI;EmD/EA;IACE,2BAAqC;EpD0jUzC;AACF;;ACx+TI;EmDjFA;IACE,2BAAqC;EpD6jUzC;AACF;;ACp+TI;EmDxFA;IACE,2BAAqC;EpDgkUzC;AACF;;ACxhUE;EmDlEE;IACE,4BAAqC;EpD8lUzC;AACF;;AC1hUE;EmDnEE;IACE,4BAAqC;EpDimUzC;AACF;;AC5hUE;EmDpEE;IACE,4BAAqC;EpDomUzC;AACF;;AC9hUE;EmDrEE;IACE,4BAAqC;EpDumUzC;AACF;;AChiUE;EmDtEE;IACE,4BAAqC;EpD0mUzC;AACF;;ACjiUI;EmDxEA;IACE,4BAAqC;EpD6mUzC;AACF;;AC7hUI;EmD/EA;IACE,4BAAqC;EpDgnUzC;AACF;;AC9hUI;EmDjFA;IACE,4BAAqC;EpDmnUzC;AACF;;AC1hUI;EmDxFA;IACE,4BAAqC;EpDsnUzC;AACF;;AoDrnUA;EACE,qCAAqC;ApDwnUvC;;AoDtnUA;EACE,oCAAoC;ApDynUtC;;AoDvnUA;EACE,oCAAoC;ApD0nUtC;;AoDxnUA;EACE,6BAA6B;ApD2nU/B;;AoDznUA;EACE,qCAAqC;ApD4nUvC;;AoD1nUA;EACE,2BAAqC;ApD6nUvC;;AoD5nUA;EACE,2BAAsC;ApD+nUxC;;AoD9nUA;EACE,2BAAsC;ApDioUxC;;AoDhoUA;EACE,2BAAwC;ApDmoU1C;;AoDloUA;EACE,2BAAoC;ApDqoUtC;;AoDnoUA;EACE,+LAAuC;ApDsoUzC;;AoDpoUA;EACE,+LAAyC;ApDuoU3C;;AoDroUA;EACE,+LAA0C;ApDwoU5C;;AoDtoUA;EACE,iCAAyC;ApDyoU3C;;AoDvoUA;EACE,iCAAoC;ApD0oUtC;;AqD3uUE;EACE,yBAA+B;ArD8uUnC;;AC9oUE;EoD9FE;IACE,yBAA+B;ErDgvUnC;AACF;;AChpUE;EoD/FE;IACE,yBAA+B;ErDmvUnC;AACF;;AClpUE;EoDhGE;IACE,yBAA+B;ErDsvUnC;AACF;;ACppUE;EoDjGE;IACE,yBAA+B;ErDyvUnC;AACF;;ACtpUE;EoDlGE;IACE,yBAA+B;ErD4vUnC;AACF;;ACvpUI;EoDpGA;IACE,yBAA+B;ErD+vUnC;AACF;;ACnpUI;EoD3GA;IACE,yBAA+B;ErDkwUnC;AACF;;ACppUI;EoD7GA;IACE,yBAA+B;ErDqwUnC;AACF;;AChpUI;EoDpHA;IACE,yBAA+B;ErDwwUnC;AACF;;AqDryUE;EACE,wBAA+B;ArDwyUnC;;ACxsUE;EoD9FE;IACE,wBAA+B;ErD0yUnC;AACF;;AC1sUE;EoD/FE;IACE,wBAA+B;ErD6yUnC;AACF;;AC5sUE;EoDhGE;IACE,wBAA+B;ErDgzUnC;AACF;;AC9sUE;EoDjGE;IACE,wBAA+B;ErDmzUnC;AACF;;AChtUE;EoDlGE;IACE,wBAA+B;ErDszUnC;AACF;;ACjtUI;EoDpGA;IACE,wBAA+B;ErDyzUnC;AACF;;AC7sUI;EoD3GA;IACE,wBAA+B;ErD4zUnC;AACF;;AC9sUI;EoD7GA;IACE,wBAA+B;ErD+zUnC;AACF;;AC1sUI;EoDpHA;IACE,wBAA+B;ErDk0UnC;AACF;;AqD/1UE;EACE,0BAA+B;ArDk2UnC;;AClwUE;EoD9FE;IACE,0BAA+B;ErDo2UnC;AACF;;ACpwUE;EoD/FE;IACE,0BAA+B;ErDu2UnC;AACF;;ACtwUE;EoDhGE;IACE,0BAA+B;ErD02UnC;AACF;;ACxwUE;EoDjGE;IACE,0BAA+B;ErD62UnC;AACF;;AC1wUE;EoDlGE;IACE,0BAA+B;ErDg3UnC;AACF;;AC3wUI;EoDpGA;IACE,0BAA+B;ErDm3UnC;AACF;;ACvwUI;EoD3GA;IACE,0BAA+B;ErDs3UnC;AACF;;ACxwUI;EoD7GA;IACE,0BAA+B;ErDy3UnC;AACF;;ACpwUI;EoDpHA;IACE,0BAA+B;ErD43UnC;AACF;;AqDz5UE;EACE,gCAA+B;ArD45UnC;;AC5zUE;EoD9FE;IACE,gCAA+B;ErD85UnC;AACF;;AC9zUE;EoD/FE;IACE,gCAA+B;ErDi6UnC;AACF;;ACh0UE;EoDhGE;IACE,gCAA+B;ErDo6UnC;AACF;;ACl0UE;EoDjGE;IACE,gCAA+B;ErDu6UnC;AACF;;ACp0UE;EoDlGE;IACE,gCAA+B;ErD06UnC;AACF;;ACr0UI;EoDpGA;IACE,gCAA+B;ErD66UnC;AACF;;ACj0UI;EoD3GA;IACE,gCAA+B;ErDg7UnC;AACF;;ACl0UI;EoD7GA;IACE,gCAA+B;ErDm7UnC;AACF;;AC9zUI;EoDpHA;IACE,gCAA+B;ErDs7UnC;AACF;;AqDn9UE;EACE,+BAA+B;ArDs9UnC;;ACt3UE;EoD9FE;IACE,+BAA+B;ErDw9UnC;AACF;;ACx3UE;EoD/FE;IACE,+BAA+B;ErD29UnC;AACF;;AC13UE;EoDhGE;IACE,+BAA+B;ErD89UnC;AACF;;AC53UE;EoDjGE;IACE,+BAA+B;ErDi+UnC;AACF;;AC93UE;EoDlGE;IACE,+BAA+B;ErDo+UnC;AACF;;AC/3UI;EoDpGA;IACE,+BAA+B;ErDu+UnC;AACF;;AC33UI;EoD3GA;IACE,+BAA+B;ErD0+UnC;AACF;;AC53UI;EoD7GA;IACE,+BAA+B;ErD6+UnC;AACF;;ACx3UI;EoDpHA;IACE,+BAA+B;ErDg/UnC;AACF;;AqD/+UA;EACE,wBAAwB;ArDk/U1B;;AqDh/UA;EACE,uBAAuB;EACvB,iCAAiC;EACjC,yBAAyB;EACzB,2BAA2B;EAC3B,qBAAqB;EACrB,6BAA6B;EAC7B,8BAA8B;EAC9B,wBAAwB;ArDm/U1B;;AC37UE;EoDrDA;IACE,wBAAwB;ErDo/U1B;AACF;;AC77UE;EoDrDA;IACE,wBAAwB;ErDs/U1B;AACF;;AC/7UE;EoDrDA;IACE,wBAAwB;ErDw/U1B;AACF;;ACj8UE;EoDrDA;IACE,wBAAwB;ErD0/U1B;AACF;;ACn8UE;EoDrDA;IACE,wBAAwB;ErD4/U1B;AACF;;ACp8UI;EoDtDF;IACE,wBAAwB;ErD8/U1B;AACF;;ACh8UI;EoD5DF;IACE,wBAAwB;ErDggV1B;AACF;;ACj8UI;EoD7DF;IACE,wBAAwB;ErDkgV1B;AACF;;AC77UI;EoDnEF;IACE,wBAAwB;ErDogV1B;AACF;;AqDngVA;EACE,6BAA6B;ArDsgV/B;;ACr/UE;EoDdA;IACE,6BAA6B;ErDugV/B;AACF;;ACv/UE;EoDdA;IACE,6BAA6B;ErDygV/B;AACF;;ACz/UE;EoDdA;IACE,6BAA6B;ErD2gV/B;AACF;;AC3/UE;EoDdA;IACE,6BAA6B;ErD6gV/B;AACF;;AC7/UE;EoDdA;IACE,6BAA6B;ErD+gV/B;AACF;;AC9/UI;EoDfF;IACE,6BAA6B;ErDihV/B;AACF;;AC1/UI;EoDrBF;IACE,6BAA6B;ErDmhV/B;AACF;;AC3/UI;EoDtBF;IACE,6BAA6B;ErDqhV/B;AACF;;ACv/UI;EoD5BF;IACE,6BAA6B;ErDuhV/B;AACF;;AsDjpVA,iBAAA;ACWA;EACE,oBAAoB;EACpB,aAAa;EACb,sBAAsB;EACtB,8BAA8B;AvD0oVhC;;AuD9oVA;EAMI,gBAAgB;AvD4oVpB;;AuDlpVA;EASM,mBAAmB;AvD6oVzB;;AuDtpVA;EAeM,uBxDXyB;EwDYzB,cxDzBuB;ACoqV7B;;AuD3pVA;;EAmBQ,cAAc;AvD6oVtB;;AuDhqVA;EAqBQ,cxD9BqB;AC6qV7B;;AuDpqVA;EAuBQ,4BxDhCqB;ACirV7B;;AuDxqVA;;EA0BU,cxDnCmB;ACsrV7B;;ACtkVE;EsDvGF;IA6BU,uBxDzBqB;EC8qV7B;AACF;;AuDnrVA;;EAgCQ,4BxDzCqB;ACisV7B;;AuDxrVA;;;EAqCU,yB7C4DuB;E6C3DvB,cxD/CmB;ACwsV7B;;AuD/rVA;EAyCU,cxDlDmB;EwDmDnB,YAAY;AvD0pVtB;;AuDpsVA;EA4CY,UAAU;AvD4pVtB;;AuDxsVA;EA+CY,uBAAwB;EACxB,UAAU;AvD6pVtB;;AuD7sVA;EAoDY,cxD7DiB;AC0tV7B;;AuDjtVA;EAsDc,uCxD/De;AC8tV7B;;AuDrtVA;EA0Dc,yBxDnEe;EwDoEf,qBxDpEe;EwDqEf,YxDxDiB;ACutV/B;;AuD3tVA;EAkEU,4EAAyG;AvD6pVnH;;ACpoVE;EsD3FF;IAqEc,4EAAyG;EvD+pVrH;AACF;;AuDruVA;EAeM,yBxDxBuB;EwDyBvB,YxDZyB;ACsuV/B;;AuD1uVA;;EAmBQ,cAAc;AvD4tVtB;;AuD/uVA;EAqBQ,YxDjBuB;AC+uV/B;;AuDnvVA;EAuBQ,+BxDnBuB;ACmvV/B;;AuDvvVA;;EA0BU,YxDtBqB;ACwvV/B;;ACrpVE;EsDvGF;IA6BU,yBxDtCmB;EC0wV3B;AACF;;AuDlwVA;;EAgCQ,+BxD5BuB;ACmwV/B;;AuDvwVA;;;EAqCU,uB7C4DuB;E6C3DvB,YxDlCqB;AC0wV/B;;AuD9wVA;EAyCU,YxDrCqB;EwDsCrB,YAAY;AvDyuVtB;;AuDnxVA;EA4CY,UAAU;AvD2uVtB;;AuDvxVA;EA+CY,yBAAwB;EACxB,UAAU;AvD4uVtB;;AuD5xVA;EAoDY,YxDhDmB;AC4xV/B;;AuDhyVA;EAsDc,uCxD/De;AC6yV7B;;AuDpyVA;EA0Dc,uBxDtDiB;EwDuDjB,mBxDvDiB;EwDwDjB,cxDrEe;ACmzV7B;;AuD1yVA;EAkEU,8EAAyG;AvD4uVnH;;ACntVE;EsD3FF;IAqEc,8EAAyG;EvD8uVrH;AACF;;AuDpzVA;EAeM,4BxDbwB;EwDcxB,yB7CqDe;AVovVrB;;AuDzzVA;;EAmBQ,cAAc;AvD2yVtB;;AuD9zVA;EAqBQ,yB7CgDa;AV6vVrB;;AuDl0VA;EAuBQ,yB7C8Ca;AViwVrB;;AuDt0VA;;EA0BU,yB7C2CW;AVswVrB;;ACpuVE;EsDvGF;IA6BU,4BxD3BoB;EC80V5B;AACF;;AuDj1VA;;EAgCQ,yB7CqCa;AVixVrB;;AuDt1VA;;;EAqCU,yB7C4DuB;E6C3DvB,yB7C+BW;AVwxVrB;;AuD71VA;EAyCU,yB7C4BW;E6C3BX,YAAY;AvDwzVtB;;AuDl2VA;EA4CY,UAAU;AvD0zVtB;;AuDt2VA;EA+CY,4BAAwB;EACxB,UAAU;AvD2zVtB;;AuD32VA;EAoDY,yB7CiBS;AV0yVrB;;AuD/2VA;EAsDc,uCxD/De;AC43V7B;;AuDn3VA;EA0Dc,oC7CWO;E6CVP,gC7CUO;E6CTP,iBxD1DgB;ACu3V9B;;AuDz3VA;EAkEU,iFAAyG;AvD2zVnH;;AClyVE;EsD3FF;IAqEc,iFAAyG;EvD6zVrH;AACF;;AuDn4VA;EAeM,yBxDpBwB;EwDqBxB,W7CuDU;AVi0VhB;;AuDx4VA;;EAmBQ,cAAc;AvD03VtB;;AuD74VA;EAqBQ,W7CkDQ;AV00VhB;;AuDj5VA;EAuBQ,+B7CgDQ;AV80VhB;;AuDr5VA;;EA0BU,W7C6CM;AVm1VhB;;ACnzVE;EsDvGF;IA6BU,yBxDlCoB;ECo6V5B;AACF;;AuDh6VA;;EAgCQ,+B7CuCQ;AV81VhB;;AuDr6VA;;;EAqCU,yB7C4DuB;E6C3DvB,W7CiCM;AVq2VhB;;AuD56VA;EAyCU,W7C8BM;E6C7BN,YAAY;AvDu4VtB;;AuDj7VA;EA4CY,UAAU;AvDy4VtB;;AuDr7VA;EA+CY,yBAAwB;EACxB,UAAU;AvD04VtB;;AuD17VA;EAoDY,W7CmBI;AVu3VhB;;AuD97VA;EAsDc,uCxD/De;AC28V7B;;AuDl8VA;EA0Dc,sB7CaE;E6CZF,kB7CYE;E6CXF,cxDjEgB;AC68V9B;;AuDx8VA;EAkEU,gFAAyG;AvD04VnH;;ACj3VE;EsD3FF;IAqEc,gFAAyG;EvD44VrH;AACF;;AuDl9VA;EAeM,yBxDN4B;EwDO5B,W7CuDU;AVg5VhB;;AuDv9VA;;EAmBQ,cAAc;AvDy8VtB;;AuD59VA;EAqBQ,W7CkDQ;AVy5VhB;;AuDh+VA;EAuBQ,+B7CgDQ;AV65VhB;;AuDp+VA;;EA0BU,W7C6CM;AVk6VhB;;ACl4VE;EsDvGF;IA6BU,yBxDpBwB;ECq+VhC;AACF;;AuD/+VA;;EAgCQ,+B7CuCQ;AV66VhB;;AuDp/VA;;;EAqCU,yB7C4DuB;E6C3DvB,W7CiCM;AVo7VhB;;AuD3/VA;EAyCU,W7C8BM;E6C7BN,YAAY;AvDs9VtB;;AuDhgWA;EA4CY,UAAU;AvDw9VtB;;AuDpgWA;EA+CY,yBAAwB;EACxB,UAAU;AvDy9VtB;;AuDzgWA;EAoDY,W7CmBI;AVs8VhB;;AuD7gWA;EAsDc,uCxD/De;AC0hW7B;;AuDjhWA;EA0Dc,sB7CaE;E6CZF,kB7CYE;E6CXF,cxDnDoB;AC8gWlC;;AuDvhWA;EAkEU,gFAAyG;AvDy9VnH;;ACh8VE;EsD3FF;IAqEc,gFAAyG;EvD29VrH;AACF;;AuDjiWA;EAeM,yBxDJ4B;EwDK5B,W7CuDU;AV+9VhB;;AuDtiWA;;EAmBQ,cAAc;AvDwhWtB;;AuD3iWA;EAqBQ,W7CkDQ;AVw+VhB;;AuD/iWA;EAuBQ,+B7CgDQ;AV4+VhB;;AuDnjWA;;EA0BU,W7C6CM;AVi/VhB;;ACj9VE;EsDvGF;IA6BU,yBxDlBwB;ECkjWhC;AACF;;AuD9jWA;;EAgCQ,+B7CuCQ;AV4/VhB;;AuDnkWA;;;EAqCU,yB7C4DuB;E6C3DvB,W7CiCM;AVmgWhB;;AuD1kWA;EAyCU,W7C8BM;E6C7BN,YAAY;AvDqiWtB;;AuD/kWA;EA4CY,UAAU;AvDuiWtB;;AuDnlWA;EA+CY,yBAAwB;EACxB,UAAU;AvDwiWtB;;AuDxlWA;EAoDY,W7CmBI;AVqhWhB;;AuD5lWA;EAsDc,uCxD/De;ACymW7B;;AuDhmWA;EA0Dc,sB7CaE;E6CZF,kB7CYE;E6CXF,cxDjDoB;AC2lWlC;;AuDtmWA;EAkEU,gFAAyG;AvDwiWnH;;AC/gWE;EsD3FF;IAqEc,gFAAyG;EvD0iWrH;AACF;;AuDhnWA;EAeM,yBxDL4B;EwDM5B,W7CuDU;AV8iWhB;;AuDrnWA;;EAmBQ,cAAc;AvDumWtB;;AuD1nWA;EAqBQ,W7CkDQ;AVujWhB;;AuD9nWA;EAuBQ,+B7CgDQ;AV2jWhB;;AuDloWA;;EA0BU,W7C6CM;AVgkWhB;;AChiWE;EsDvGF;IA6BU,yBxDnBwB;ECkoWhC;AACF;;AuD7oWA;;EAgCQ,+B7CuCQ;AV2kWhB;;AuDlpWA;;;EAqCU,yB7C4DuB;E6C3DvB,W7CiCM;AVklWhB;;AuDzpWA;EAyCU,W7C8BM;E6C7BN,YAAY;AvDonWtB;;AuD9pWA;EA4CY,UAAU;AvDsnWtB;;AuDlqWA;EA+CY,yBAAwB;EACxB,UAAU;AvDunWtB;;AuDvqWA;EAoDY,W7CmBI;AVomWhB;;AuD3qWA;EAsDc,uCxD/De;ACwrW7B;;AuD/qWA;EA0Dc,sB7CaE;E6CZF,kB7CYE;E6CXF,cxDlDoB;AC2qWlC;;AuDrrWA;EAkEU,gFAAyG;AvDunWnH;;AC9lWE;EsD3FF;IAqEc,gFAAyG;EvDynWrH;AACF;;AuD/rWA;EAeM,yBxDP4B;EwDQ5B,W7CuDU;AV6nWhB;;AuDpsWA;;EAmBQ,cAAc;AvDsrWtB;;AuDzsWA;EAqBQ,W7CkDQ;AVsoWhB;;AuD7sWA;EAuBQ,+B7CgDQ;AV0oWhB;;AuDjtWA;;EA0BU,W7C6CM;AV+oWhB;;AC/mWE;EsDvGF;IA6BU,yBxDrBwB;ECmtWhC;AACF;;AuD5tWA;;EAgCQ,+B7CuCQ;AV0pWhB;;AuDjuWA;;;EAqCU,yB7C4DuB;E6C3DvB,W7CiCM;AViqWhB;;AuDxuWA;EAyCU,W7C8BM;E6C7BN,YAAY;AvDmsWtB;;AuD7uWA;EA4CY,UAAU;AvDqsWtB;;AuDjvWA;EA+CY,yBAAwB;EACxB,UAAU;AvDssWtB;;AuDtvWA;EAoDY,W7CmBI;AVmrWhB;;AuD1vWA;EAsDc,uCxD/De;ACuwW7B;;AuD9vWA;EA0Dc,sB7CaE;E6CZF,kB7CYE;E6CXF,cxDpDoB;AC4vWlC;;AuDpwWA;EAkEU,gFAAyG;AvDssWnH;;AC7qWE;EsD3FF;IAqEc,gFAAyG;EvDwsWrH;AACF;;AuD9wWA;EAeM,yBxDR4B;EwDS5B,yB7CqDe;AV8sWrB;;AuDnxWA;;EAmBQ,cAAc;AvDqwWtB;;AuDxxWA;EAqBQ,yB7CgDa;AVutWrB;;AuD5xWA;EAuBQ,yB7C8Ca;AV2tWrB;;AuDhyWA;;EA0BU,yB7C2CW;AVguWrB;;AC9rWE;EsDvGF;IA6BU,yBxDtBwB;ECmyWhC;AACF;;AuD3yWA;;EAgCQ,yB7CqCa;AV2uWrB;;AuDhzWA;;;EAqCU,yB7C4DuB;E6C3DvB,yB7C+BW;AVkvWrB;;AuDvzWA;EAyCU,yB7C4BW;E6C3BX,YAAY;AvDkxWtB;;AuD5zWA;EA4CY,UAAU;AvDoxWtB;;AuDh0WA;EA+CY,yBAAwB;EACxB,UAAU;AvDqxWtB;;AuDr0WA;EAoDY,yB7CiBS;AVowWrB;;AuDz0WA;EAsDc,uCxD/De;ACs1W7B;;AuD70WA;EA0Dc,oC7CWO;E6CVP,gC7CUO;E6CTP,cxDrDoB;AC40WlC;;AuDn1WA;EAkEU,gFAAyG;AvDqxWnH;;AC5vWE;EsD3FF;IAqEc,gFAAyG;EvDuxWrH;AACF;;AuD71WA;EAeM,yBxDF2B;EwDG3B,W7CuDU;AV2xWhB;;AuDl2WA;;EAmBQ,cAAc;AvDo1WtB;;AuDv2WA;EAqBQ,W7CkDQ;AVoyWhB;;AuD32WA;EAuBQ,+B7CgDQ;AVwyWhB;;AuD/2WA;;EA0BU,W7C6CM;AV6yWhB;;AC7wWE;EsDvGF;IA6BU,yBxDhBuB;EC42W/B;AACF;;AuD13WA;;EAgCQ,+B7CuCQ;AVwzWhB;;AuD/3WA;;;EAqCU,yB7C4DuB;E6C3DvB,W7CiCM;AV+zWhB;;AuDt4WA;EAyCU,W7C8BM;E6C7BN,YAAY;AvDi2WtB;;AuD34WA;EA4CY,UAAU;AvDm2WtB;;AuD/4WA;EA+CY,yBAAwB;EACxB,UAAU;AvDo2WtB;;AuDp5WA;EAoDY,W7CmBI;AVi1WhB;;AuDx5WA;EAsDc,uCxD/De;ACq6W7B;;AuD55WA;EA0Dc,sB7CaE;E6CZF,kB7CYE;E6CXF,cxD/CmB;ACq5WjC;;AuDl6WA;EAkEU,gFAAyG;AvDo2WnH;;AC30WE;EsD3FF;IAqEc,gFAAyG;EvDs2WrH;AACF;;AuD56WA;EAyEM,eAhF0B;AvDu7WhC;;ACj1WE;EsD/FF;IA6EQ,oBAnF8B;EvD27WpC;AACF;;ACv1WE;EsD/FF;IAiFQ,mBAtF4B;EvDg8WlC;AACF;;AuD57WA;EAsFM,mBAAmB;EACnB,aAAa;AvD02WnB;;AuDj8WA;EAyFQ,YAAY;EACZ,cAAc;AvD42WtB;;AuDt8WA;EA4FI,gBAAgB;AvD82WpB;;AuD18WA;EA8FI,iBAAiB;AvDg3WrB;;AuD52WA;EAEE,gBAAgB;AvD82WlB;;AuDh3WA;EAII,SAAS;EACT,gBAAgB;EAChB,eAAe;EACf,kBAAkB;EAClB,QAAQ;EACR,qCAAqC;AvDg3WzC;;AuDz3WA;EAYI,YAAY;AvDi3WhB;;ACp4WE;EsDOF;IAeI,aAAa;EvDm3Wf;AACF;;AuDl3WA;EACE,kBAAkB;AvDq3WpB;;AC94WE;EsDwBF;IAKM,aAAa;EvDs3WjB;EuD33WF;IAOQ,sBAAsB;EvDu3W5B;AACF;;ACn5WE;EsDoBF;IASI,aAAa;IACb,uBAAuB;EvD23WzB;EuDr4WF;ItDsDI,oBsD1CwC;EvD43W1C;AACF;;AuDz3WA;;EAEE,YAAY;EACZ,cAAc;AvD43WhB;;AuD13WA;EACE,YAAY;EACZ,cAAc;EACd,oBApJ6B;AvDihX/B;;ACz6WE;EsDyCF;IAKI,kBArJgC;EvDqhXlC;AACF;;AwDlhXA;EACE,oBAN2B;AxD2hX7B;;ACv6WE;EuD/GF;IAII,kBAR+B;ExD+hXjC;EwD3hXF;IAOM,oBAV8B;ExDiiXlC;EwD9hXF;IASM,mBAX4B;ExDmiXhC;AACF;;AyDniXA;EACE,yB1DO4B;E0DN5B,yBAJ+B;AzD0iXjC","file":"bulma.css"}
\ No newline at end of file
diff --git a/mc_openapi/assets/static/bulma.min.css b/mc_openapi/assets/static/bulma.min.css
new file mode 100644
index 0000000000000000000000000000000000000000..86ad2ff1408bdec4069ed2ea355bb5e32e356d96
--- /dev/null
+++ b/mc_openapi/assets/static/bulma.min.css
@@ -0,0 +1 @@
+/*! bulma.io v0.9.4 | MIT License | github.com/jgthms/bulma */.button,.file-cta,.file-name,.input,.pagination-ellipsis,.pagination-link,.pagination-next,.pagination-previous,.select select,.textarea{-moz-appearance:none;-webkit-appearance:none;align-items:center;border:1px solid transparent;border-radius:4px;box-shadow:none;display:inline-flex;font-size:1rem;height:2.5em;justify-content:flex-start;line-height:1.5;padding-bottom:calc(.5em - 1px);padding-left:calc(.75em - 1px);padding-right:calc(.75em - 1px);padding-top:calc(.5em - 1px);position:relative;vertical-align:top}.button:active,.button:focus,.file-cta:active,.file-cta:focus,.file-name:active,.file-name:focus,.input:active,.input:focus,.is-active.button,.is-active.file-cta,.is-active.file-name,.is-active.input,.is-active.pagination-ellipsis,.is-active.pagination-link,.is-active.pagination-next,.is-active.pagination-previous,.is-active.textarea,.is-focused.button,.is-focused.file-cta,.is-focused.file-name,.is-focused.input,.is-focused.pagination-ellipsis,.is-focused.pagination-link,.is-focused.pagination-next,.is-focused.pagination-previous,.is-focused.textarea,.pagination-ellipsis:active,.pagination-ellipsis:focus,.pagination-link:active,.pagination-link:focus,.pagination-next:active,.pagination-next:focus,.pagination-previous:active,.pagination-previous:focus,.select select.is-active,.select select.is-focused,.select select:active,.select select:focus,.textarea:active,.textarea:focus{outline:0}.button[disabled],.file-cta[disabled],.file-name[disabled],.input[disabled],.pagination-ellipsis[disabled],.pagination-link[disabled],.pagination-next[disabled],.pagination-previous[disabled],.select fieldset[disabled] select,.select select[disabled],.textarea[disabled],fieldset[disabled] .button,fieldset[disabled] .file-cta,fieldset[disabled] .file-name,fieldset[disabled] .input,fieldset[disabled] .pagination-ellipsis,fieldset[disabled] .pagination-link,fieldset[disabled] .pagination-next,fieldset[disabled] .pagination-previous,fieldset[disabled] .select select,fieldset[disabled] .textarea{cursor:not-allowed}.breadcrumb,.button,.file,.is-unselectable,.pagination-ellipsis,.pagination-link,.pagination-next,.pagination-previous,.tabs{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.navbar-link:not(.is-arrowless)::after,.select:not(.is-multiple):not(.is-loading)::after{border:3px solid transparent;border-radius:2px;border-right:0;border-top:0;content:" ";display:block;height:.625em;margin-top:-.4375em;pointer-events:none;position:absolute;top:50%;transform:rotate(-45deg);transform-origin:center;width:.625em}.block:not(:last-child),.box:not(:last-child),.breadcrumb:not(:last-child),.content:not(:last-child),.level:not(:last-child),.message:not(:last-child),.notification:not(:last-child),.pagination:not(:last-child),.progress:not(:last-child),.subtitle:not(:last-child),.table-container:not(:last-child),.table:not(:last-child),.tabs:not(:last-child),.title:not(:last-child){margin-bottom:1.5rem}.delete,.modal-close{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-moz-appearance:none;-webkit-appearance:none;background-color:rgba(10,10,10,.2);border:none;border-radius:9999px;cursor:pointer;pointer-events:auto;display:inline-block;flex-grow:0;flex-shrink:0;font-size:0;height:20px;max-height:20px;max-width:20px;min-height:20px;min-width:20px;outline:0;position:relative;vertical-align:top;width:20px}.delete::after,.delete::before,.modal-close::after,.modal-close::before{background-color:#fff;content:"";display:block;left:50%;position:absolute;top:50%;transform:translateX(-50%) translateY(-50%) rotate(45deg);transform-origin:center center}.delete::before,.modal-close::before{height:2px;width:50%}.delete::after,.modal-close::after{height:50%;width:2px}.delete:focus,.delete:hover,.modal-close:focus,.modal-close:hover{background-color:rgba(10,10,10,.3)}.delete:active,.modal-close:active{background-color:rgba(10,10,10,.4)}.is-small.delete,.is-small.modal-close{height:16px;max-height:16px;max-width:16px;min-height:16px;min-width:16px;width:16px}.is-medium.delete,.is-medium.modal-close{height:24px;max-height:24px;max-width:24px;min-height:24px;min-width:24px;width:24px}.is-large.delete,.is-large.modal-close{height:32px;max-height:32px;max-width:32px;min-height:32px;min-width:32px;width:32px}.button.is-loading::after,.control.is-loading::after,.loader,.select.is-loading::after{-webkit-animation:spinAround .5s infinite linear;animation:spinAround .5s infinite linear;border:2px solid #dbdbdb;border-radius:9999px;border-right-color:transparent;border-top-color:transparent;content:"";display:block;height:1em;position:relative;width:1em}.hero-video,.image.is-16by9 .has-ratio,.image.is-16by9 img,.image.is-1by1 .has-ratio,.image.is-1by1 img,.image.is-1by2 .has-ratio,.image.is-1by2 img,.image.is-1by3 .has-ratio,.image.is-1by3 img,.image.is-2by1 .has-ratio,.image.is-2by1 img,.image.is-2by3 .has-ratio,.image.is-2by3 img,.image.is-3by1 .has-ratio,.image.is-3by1 img,.image.is-3by2 .has-ratio,.image.is-3by2 img,.image.is-3by4 .has-ratio,.image.is-3by4 img,.image.is-3by5 .has-ratio,.image.is-3by5 img,.image.is-4by3 .has-ratio,.image.is-4by3 img,.image.is-4by5 .has-ratio,.image.is-4by5 img,.image.is-5by3 .has-ratio,.image.is-5by3 img,.image.is-5by4 .has-ratio,.image.is-5by4 img,.image.is-9by16 .has-ratio,.image.is-9by16 img,.image.is-square .has-ratio,.image.is-square img,.is-overlay,.modal,.modal-background{bottom:0;left:0;position:absolute;right:0;top:0}.navbar-burger{-moz-appearance:none;-webkit-appearance:none;appearance:none;background:0 0;border:none;color:currentColor;font-family:inherit;font-size:1em;margin:0;padding:0}/*! minireset.css v0.0.6 | MIT License | github.com/jgthms/minireset.css */blockquote,body,dd,dl,dt,fieldset,figure,h1,h2,h3,h4,h5,h6,hr,html,iframe,legend,li,ol,p,pre,textarea,ul{margin:0;padding:0}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:400}ul{list-style:none}button,input,select,textarea{margin:0}html{box-sizing:border-box}*,::after,::before{box-sizing:inherit}img,video{height:auto;max-width:100%}iframe{border:0}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}td:not([align]),th:not([align]){text-align:inherit}html{background-color:#fff;font-size:16px;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;min-width:300px;overflow-x:hidden;overflow-y:scroll;text-rendering:optimizeLegibility;-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%;text-size-adjust:100%}article,aside,figure,footer,header,hgroup,section{display:block}body,button,input,optgroup,select,textarea{font-family:BlinkMacSystemFont,-apple-system,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Fira Sans","Droid Sans","Helvetica Neue",Helvetica,Arial,sans-serif}code,pre{-moz-osx-font-smoothing:auto;-webkit-font-smoothing:auto;font-family:monospace}body{color:#4a4a4a;font-size:1em;font-weight:400;line-height:1.5}a{color:#485fc7;cursor:pointer;text-decoration:none}a strong{color:currentColor}a:hover{color:#363636}code{background-color:#f5f5f5;color:#da1039;font-size:.875em;font-weight:400;padding:.25em .5em .25em}hr{background-color:#f5f5f5;border:none;display:block;height:2px;margin:1.5rem 0}img{height:auto;max-width:100%}input[type=checkbox],input[type=radio]{vertical-align:baseline}small{font-size:.875em}span{font-style:inherit;font-weight:inherit}strong{color:#363636;font-weight:700}fieldset{border:none}pre{-webkit-overflow-scrolling:touch;background-color:#f5f5f5;color:#4a4a4a;font-size:.875em;overflow-x:auto;padding:1.25rem 1.5rem;white-space:pre;word-wrap:normal}pre code{background-color:transparent;color:currentColor;font-size:1em;padding:0}table td,table th{vertical-align:top}table td:not([align]),table th:not([align]){text-align:inherit}table th{color:#363636}@-webkit-keyframes spinAround{from{transform:rotate(0)}to{transform:rotate(359deg)}}@keyframes spinAround{from{transform:rotate(0)}to{transform:rotate(359deg)}}.box{background-color:#fff;border-radius:6px;box-shadow:0 .5em 1em -.125em rgba(10,10,10,.1),0 0 0 1px rgba(10,10,10,.02);color:#4a4a4a;display:block;padding:1.25rem}a.box:focus,a.box:hover{box-shadow:0 .5em 1em -.125em rgba(10,10,10,.1),0 0 0 1px #485fc7}a.box:active{box-shadow:inset 0 1px 2px rgba(10,10,10,.2),0 0 0 1px #485fc7}.button{background-color:#fff;border-color:#dbdbdb;border-width:1px;color:#363636;cursor:pointer;justify-content:center;padding-bottom:calc(.5em - 1px);padding-left:1em;padding-right:1em;padding-top:calc(.5em - 1px);text-align:center;white-space:nowrap}.button strong{color:inherit}.button .icon,.button .icon.is-large,.button .icon.is-medium,.button .icon.is-small{height:1.5em;width:1.5em}.button .icon:first-child:not(:last-child){margin-left:calc(-.5em - 1px);margin-right:.25em}.button .icon:last-child:not(:first-child){margin-left:.25em;margin-right:calc(-.5em - 1px)}.button .icon:first-child:last-child{margin-left:calc(-.5em - 1px);margin-right:calc(-.5em - 1px)}.button.is-hovered,.button:hover{border-color:#b5b5b5;color:#363636}.button.is-focused,.button:focus{border-color:#485fc7;color:#363636}.button.is-focused:not(:active),.button:focus:not(:active){box-shadow:0 0 0 .125em rgba(72,95,199,.25)}.button.is-active,.button:active{border-color:#4a4a4a;color:#363636}.button.is-text{background-color:transparent;border-color:transparent;color:#4a4a4a;text-decoration:underline}.button.is-text.is-focused,.button.is-text.is-hovered,.button.is-text:focus,.button.is-text:hover{background-color:#f5f5f5;color:#363636}.button.is-text.is-active,.button.is-text:active{background-color:#e8e8e8;color:#363636}.button.is-text[disabled],fieldset[disabled] .button.is-text{background-color:transparent;border-color:transparent;box-shadow:none}.button.is-ghost{background:0 0;border-color:transparent;color:#485fc7;text-decoration:none}.button.is-ghost.is-hovered,.button.is-ghost:hover{color:#485fc7;text-decoration:underline}.button.is-white{background-color:#fff;border-color:transparent;color:#0a0a0a}.button.is-white.is-hovered,.button.is-white:hover{background-color:#f9f9f9;border-color:transparent;color:#0a0a0a}.button.is-white.is-focused,.button.is-white:focus{border-color:transparent;color:#0a0a0a}.button.is-white.is-focused:not(:active),.button.is-white:focus:not(:active){box-shadow:0 0 0 .125em rgba(255,255,255,.25)}.button.is-white.is-active,.button.is-white:active{background-color:#f2f2f2;border-color:transparent;color:#0a0a0a}.button.is-white[disabled],fieldset[disabled] .button.is-white{background-color:#fff;border-color:#fff;box-shadow:none}.button.is-white.is-inverted{background-color:#0a0a0a;color:#fff}.button.is-white.is-inverted.is-hovered,.button.is-white.is-inverted:hover{background-color:#000}.button.is-white.is-inverted[disabled],fieldset[disabled] .button.is-white.is-inverted{background-color:#0a0a0a;border-color:transparent;box-shadow:none;color:#fff}.button.is-white.is-loading::after{border-color:transparent transparent #0a0a0a #0a0a0a!important}.button.is-white.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-white.is-outlined.is-focused,.button.is-white.is-outlined.is-hovered,.button.is-white.is-outlined:focus,.button.is-white.is-outlined:hover{background-color:#fff;border-color:#fff;color:#0a0a0a}.button.is-white.is-outlined.is-loading::after{border-color:transparent transparent #fff #fff!important}.button.is-white.is-outlined.is-loading.is-focused::after,.button.is-white.is-outlined.is-loading.is-hovered::after,.button.is-white.is-outlined.is-loading:focus::after,.button.is-white.is-outlined.is-loading:hover::after{border-color:transparent transparent #0a0a0a #0a0a0a!important}.button.is-white.is-outlined[disabled],fieldset[disabled] .button.is-white.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-white.is-inverted.is-outlined{background-color:transparent;border-color:#0a0a0a;color:#0a0a0a}.button.is-white.is-inverted.is-outlined.is-focused,.button.is-white.is-inverted.is-outlined.is-hovered,.button.is-white.is-inverted.is-outlined:focus,.button.is-white.is-inverted.is-outlined:hover{background-color:#0a0a0a;color:#fff}.button.is-white.is-inverted.is-outlined.is-loading.is-focused::after,.button.is-white.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-white.is-inverted.is-outlined.is-loading:focus::after,.button.is-white.is-inverted.is-outlined.is-loading:hover::after{border-color:transparent transparent #fff #fff!important}.button.is-white.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-white.is-inverted.is-outlined{background-color:transparent;border-color:#0a0a0a;box-shadow:none;color:#0a0a0a}.button.is-black{background-color:#0a0a0a;border-color:transparent;color:#fff}.button.is-black.is-hovered,.button.is-black:hover{background-color:#040404;border-color:transparent;color:#fff}.button.is-black.is-focused,.button.is-black:focus{border-color:transparent;color:#fff}.button.is-black.is-focused:not(:active),.button.is-black:focus:not(:active){box-shadow:0 0 0 .125em rgba(10,10,10,.25)}.button.is-black.is-active,.button.is-black:active{background-color:#000;border-color:transparent;color:#fff}.button.is-black[disabled],fieldset[disabled] .button.is-black{background-color:#0a0a0a;border-color:#0a0a0a;box-shadow:none}.button.is-black.is-inverted{background-color:#fff;color:#0a0a0a}.button.is-black.is-inverted.is-hovered,.button.is-black.is-inverted:hover{background-color:#f2f2f2}.button.is-black.is-inverted[disabled],fieldset[disabled] .button.is-black.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#0a0a0a}.button.is-black.is-loading::after{border-color:transparent transparent #fff #fff!important}.button.is-black.is-outlined{background-color:transparent;border-color:#0a0a0a;color:#0a0a0a}.button.is-black.is-outlined.is-focused,.button.is-black.is-outlined.is-hovered,.button.is-black.is-outlined:focus,.button.is-black.is-outlined:hover{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}.button.is-black.is-outlined.is-loading::after{border-color:transparent transparent #0a0a0a #0a0a0a!important}.button.is-black.is-outlined.is-loading.is-focused::after,.button.is-black.is-outlined.is-loading.is-hovered::after,.button.is-black.is-outlined.is-loading:focus::after,.button.is-black.is-outlined.is-loading:hover::after{border-color:transparent transparent #fff #fff!important}.button.is-black.is-outlined[disabled],fieldset[disabled] .button.is-black.is-outlined{background-color:transparent;border-color:#0a0a0a;box-shadow:none;color:#0a0a0a}.button.is-black.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-black.is-inverted.is-outlined.is-focused,.button.is-black.is-inverted.is-outlined.is-hovered,.button.is-black.is-inverted.is-outlined:focus,.button.is-black.is-inverted.is-outlined:hover{background-color:#fff;color:#0a0a0a}.button.is-black.is-inverted.is-outlined.is-loading.is-focused::after,.button.is-black.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-black.is-inverted.is-outlined.is-loading:focus::after,.button.is-black.is-inverted.is-outlined.is-loading:hover::after{border-color:transparent transparent #0a0a0a #0a0a0a!important}.button.is-black.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-black.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-light{background-color:#f5f5f5;border-color:transparent;color:rgba(0,0,0,.7)}.button.is-light.is-hovered,.button.is-light:hover{background-color:#eee;border-color:transparent;color:rgba(0,0,0,.7)}.button.is-light.is-focused,.button.is-light:focus{border-color:transparent;color:rgba(0,0,0,.7)}.button.is-light.is-focused:not(:active),.button.is-light:focus:not(:active){box-shadow:0 0 0 .125em rgba(245,245,245,.25)}.button.is-light.is-active,.button.is-light:active{background-color:#e8e8e8;border-color:transparent;color:rgba(0,0,0,.7)}.button.is-light[disabled],fieldset[disabled] .button.is-light{background-color:#f5f5f5;border-color:#f5f5f5;box-shadow:none}.button.is-light.is-inverted{background-color:rgba(0,0,0,.7);color:#f5f5f5}.button.is-light.is-inverted.is-hovered,.button.is-light.is-inverted:hover{background-color:rgba(0,0,0,.7)}.button.is-light.is-inverted[disabled],fieldset[disabled] .button.is-light.is-inverted{background-color:rgba(0,0,0,.7);border-color:transparent;box-shadow:none;color:#f5f5f5}.button.is-light.is-loading::after{border-color:transparent transparent rgba(0,0,0,.7) rgba(0,0,0,.7)!important}.button.is-light.is-outlined{background-color:transparent;border-color:#f5f5f5;color:#f5f5f5}.button.is-light.is-outlined.is-focused,.button.is-light.is-outlined.is-hovered,.button.is-light.is-outlined:focus,.button.is-light.is-outlined:hover{background-color:#f5f5f5;border-color:#f5f5f5;color:rgba(0,0,0,.7)}.button.is-light.is-outlined.is-loading::after{border-color:transparent transparent #f5f5f5 #f5f5f5!important}.button.is-light.is-outlined.is-loading.is-focused::after,.button.is-light.is-outlined.is-loading.is-hovered::after,.button.is-light.is-outlined.is-loading:focus::after,.button.is-light.is-outlined.is-loading:hover::after{border-color:transparent transparent rgba(0,0,0,.7) rgba(0,0,0,.7)!important}.button.is-light.is-outlined[disabled],fieldset[disabled] .button.is-light.is-outlined{background-color:transparent;border-color:#f5f5f5;box-shadow:none;color:#f5f5f5}.button.is-light.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,.7);color:rgba(0,0,0,.7)}.button.is-light.is-inverted.is-outlined.is-focused,.button.is-light.is-inverted.is-outlined.is-hovered,.button.is-light.is-inverted.is-outlined:focus,.button.is-light.is-inverted.is-outlined:hover{background-color:rgba(0,0,0,.7);color:#f5f5f5}.button.is-light.is-inverted.is-outlined.is-loading.is-focused::after,.button.is-light.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-light.is-inverted.is-outlined.is-loading:focus::after,.button.is-light.is-inverted.is-outlined.is-loading:hover::after{border-color:transparent transparent #f5f5f5 #f5f5f5!important}.button.is-light.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-light.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,.7);box-shadow:none;color:rgba(0,0,0,.7)}.button.is-dark{background-color:#363636;border-color:transparent;color:#fff}.button.is-dark.is-hovered,.button.is-dark:hover{background-color:#2f2f2f;border-color:transparent;color:#fff}.button.is-dark.is-focused,.button.is-dark:focus{border-color:transparent;color:#fff}.button.is-dark.is-focused:not(:active),.button.is-dark:focus:not(:active){box-shadow:0 0 0 .125em rgba(54,54,54,.25)}.button.is-dark.is-active,.button.is-dark:active{background-color:#292929;border-color:transparent;color:#fff}.button.is-dark[disabled],fieldset[disabled] .button.is-dark{background-color:#363636;border-color:#363636;box-shadow:none}.button.is-dark.is-inverted{background-color:#fff;color:#363636}.button.is-dark.is-inverted.is-hovered,.button.is-dark.is-inverted:hover{background-color:#f2f2f2}.button.is-dark.is-inverted[disabled],fieldset[disabled] .button.is-dark.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#363636}.button.is-dark.is-loading::after{border-color:transparent transparent #fff #fff!important}.button.is-dark.is-outlined{background-color:transparent;border-color:#363636;color:#363636}.button.is-dark.is-outlined.is-focused,.button.is-dark.is-outlined.is-hovered,.button.is-dark.is-outlined:focus,.button.is-dark.is-outlined:hover{background-color:#363636;border-color:#363636;color:#fff}.button.is-dark.is-outlined.is-loading::after{border-color:transparent transparent #363636 #363636!important}.button.is-dark.is-outlined.is-loading.is-focused::after,.button.is-dark.is-outlined.is-loading.is-hovered::after,.button.is-dark.is-outlined.is-loading:focus::after,.button.is-dark.is-outlined.is-loading:hover::after{border-color:transparent transparent #fff #fff!important}.button.is-dark.is-outlined[disabled],fieldset[disabled] .button.is-dark.is-outlined{background-color:transparent;border-color:#363636;box-shadow:none;color:#363636}.button.is-dark.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-dark.is-inverted.is-outlined.is-focused,.button.is-dark.is-inverted.is-outlined.is-hovered,.button.is-dark.is-inverted.is-outlined:focus,.button.is-dark.is-inverted.is-outlined:hover{background-color:#fff;color:#363636}.button.is-dark.is-inverted.is-outlined.is-loading.is-focused::after,.button.is-dark.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-dark.is-inverted.is-outlined.is-loading:focus::after,.button.is-dark.is-inverted.is-outlined.is-loading:hover::after{border-color:transparent transparent #363636 #363636!important}.button.is-dark.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-dark.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-primary{background-color:#00d1b2;border-color:transparent;color:#fff}.button.is-primary.is-hovered,.button.is-primary:hover{background-color:#00c4a7;border-color:transparent;color:#fff}.button.is-primary.is-focused,.button.is-primary:focus{border-color:transparent;color:#fff}.button.is-primary.is-focused:not(:active),.button.is-primary:focus:not(:active){box-shadow:0 0 0 .125em rgba(0,209,178,.25)}.button.is-primary.is-active,.button.is-primary:active{background-color:#00b89c;border-color:transparent;color:#fff}.button.is-primary[disabled],fieldset[disabled] .button.is-primary{background-color:#00d1b2;border-color:#00d1b2;box-shadow:none}.button.is-primary.is-inverted{background-color:#fff;color:#00d1b2}.button.is-primary.is-inverted.is-hovered,.button.is-primary.is-inverted:hover{background-color:#f2f2f2}.button.is-primary.is-inverted[disabled],fieldset[disabled] .button.is-primary.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#00d1b2}.button.is-primary.is-loading::after{border-color:transparent transparent #fff #fff!important}.button.is-primary.is-outlined{background-color:transparent;border-color:#00d1b2;color:#00d1b2}.button.is-primary.is-outlined.is-focused,.button.is-primary.is-outlined.is-hovered,.button.is-primary.is-outlined:focus,.button.is-primary.is-outlined:hover{background-color:#00d1b2;border-color:#00d1b2;color:#fff}.button.is-primary.is-outlined.is-loading::after{border-color:transparent transparent #00d1b2 #00d1b2!important}.button.is-primary.is-outlined.is-loading.is-focused::after,.button.is-primary.is-outlined.is-loading.is-hovered::after,.button.is-primary.is-outlined.is-loading:focus::after,.button.is-primary.is-outlined.is-loading:hover::after{border-color:transparent transparent #fff #fff!important}.button.is-primary.is-outlined[disabled],fieldset[disabled] .button.is-primary.is-outlined{background-color:transparent;border-color:#00d1b2;box-shadow:none;color:#00d1b2}.button.is-primary.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-primary.is-inverted.is-outlined.is-focused,.button.is-primary.is-inverted.is-outlined.is-hovered,.button.is-primary.is-inverted.is-outlined:focus,.button.is-primary.is-inverted.is-outlined:hover{background-color:#fff;color:#00d1b2}.button.is-primary.is-inverted.is-outlined.is-loading.is-focused::after,.button.is-primary.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-primary.is-inverted.is-outlined.is-loading:focus::after,.button.is-primary.is-inverted.is-outlined.is-loading:hover::after{border-color:transparent transparent #00d1b2 #00d1b2!important}.button.is-primary.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-primary.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-primary.is-light{background-color:#ebfffc;color:#00947e}.button.is-primary.is-light.is-hovered,.button.is-primary.is-light:hover{background-color:#defffa;border-color:transparent;color:#00947e}.button.is-primary.is-light.is-active,.button.is-primary.is-light:active{background-color:#d1fff8;border-color:transparent;color:#00947e}.button.is-link{background-color:#485fc7;border-color:transparent;color:#fff}.button.is-link.is-hovered,.button.is-link:hover{background-color:#3e56c4;border-color:transparent;color:#fff}.button.is-link.is-focused,.button.is-link:focus{border-color:transparent;color:#fff}.button.is-link.is-focused:not(:active),.button.is-link:focus:not(:active){box-shadow:0 0 0 .125em rgba(72,95,199,.25)}.button.is-link.is-active,.button.is-link:active{background-color:#3a51bb;border-color:transparent;color:#fff}.button.is-link[disabled],fieldset[disabled] .button.is-link{background-color:#485fc7;border-color:#485fc7;box-shadow:none}.button.is-link.is-inverted{background-color:#fff;color:#485fc7}.button.is-link.is-inverted.is-hovered,.button.is-link.is-inverted:hover{background-color:#f2f2f2}.button.is-link.is-inverted[disabled],fieldset[disabled] .button.is-link.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#485fc7}.button.is-link.is-loading::after{border-color:transparent transparent #fff #fff!important}.button.is-link.is-outlined{background-color:transparent;border-color:#485fc7;color:#485fc7}.button.is-link.is-outlined.is-focused,.button.is-link.is-outlined.is-hovered,.button.is-link.is-outlined:focus,.button.is-link.is-outlined:hover{background-color:#485fc7;border-color:#485fc7;color:#fff}.button.is-link.is-outlined.is-loading::after{border-color:transparent transparent #485fc7 #485fc7!important}.button.is-link.is-outlined.is-loading.is-focused::after,.button.is-link.is-outlined.is-loading.is-hovered::after,.button.is-link.is-outlined.is-loading:focus::after,.button.is-link.is-outlined.is-loading:hover::after{border-color:transparent transparent #fff #fff!important}.button.is-link.is-outlined[disabled],fieldset[disabled] .button.is-link.is-outlined{background-color:transparent;border-color:#485fc7;box-shadow:none;color:#485fc7}.button.is-link.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-link.is-inverted.is-outlined.is-focused,.button.is-link.is-inverted.is-outlined.is-hovered,.button.is-link.is-inverted.is-outlined:focus,.button.is-link.is-inverted.is-outlined:hover{background-color:#fff;color:#485fc7}.button.is-link.is-inverted.is-outlined.is-loading.is-focused::after,.button.is-link.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-link.is-inverted.is-outlined.is-loading:focus::after,.button.is-link.is-inverted.is-outlined.is-loading:hover::after{border-color:transparent transparent #485fc7 #485fc7!important}.button.is-link.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-link.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-link.is-light{background-color:#eff1fa;color:#3850b7}.button.is-link.is-light.is-hovered,.button.is-link.is-light:hover{background-color:#e6e9f7;border-color:transparent;color:#3850b7}.button.is-link.is-light.is-active,.button.is-link.is-light:active{background-color:#dce0f4;border-color:transparent;color:#3850b7}.button.is-info{background-color:#3e8ed0;border-color:transparent;color:#fff}.button.is-info.is-hovered,.button.is-info:hover{background-color:#3488ce;border-color:transparent;color:#fff}.button.is-info.is-focused,.button.is-info:focus{border-color:transparent;color:#fff}.button.is-info.is-focused:not(:active),.button.is-info:focus:not(:active){box-shadow:0 0 0 .125em rgba(62,142,208,.25)}.button.is-info.is-active,.button.is-info:active{background-color:#3082c5;border-color:transparent;color:#fff}.button.is-info[disabled],fieldset[disabled] .button.is-info{background-color:#3e8ed0;border-color:#3e8ed0;box-shadow:none}.button.is-info.is-inverted{background-color:#fff;color:#3e8ed0}.button.is-info.is-inverted.is-hovered,.button.is-info.is-inverted:hover{background-color:#f2f2f2}.button.is-info.is-inverted[disabled],fieldset[disabled] .button.is-info.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#3e8ed0}.button.is-info.is-loading::after{border-color:transparent transparent #fff #fff!important}.button.is-info.is-outlined{background-color:transparent;border-color:#3e8ed0;color:#3e8ed0}.button.is-info.is-outlined.is-focused,.button.is-info.is-outlined.is-hovered,.button.is-info.is-outlined:focus,.button.is-info.is-outlined:hover{background-color:#3e8ed0;border-color:#3e8ed0;color:#fff}.button.is-info.is-outlined.is-loading::after{border-color:transparent transparent #3e8ed0 #3e8ed0!important}.button.is-info.is-outlined.is-loading.is-focused::after,.button.is-info.is-outlined.is-loading.is-hovered::after,.button.is-info.is-outlined.is-loading:focus::after,.button.is-info.is-outlined.is-loading:hover::after{border-color:transparent transparent #fff #fff!important}.button.is-info.is-outlined[disabled],fieldset[disabled] .button.is-info.is-outlined{background-color:transparent;border-color:#3e8ed0;box-shadow:none;color:#3e8ed0}.button.is-info.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-info.is-inverted.is-outlined.is-focused,.button.is-info.is-inverted.is-outlined.is-hovered,.button.is-info.is-inverted.is-outlined:focus,.button.is-info.is-inverted.is-outlined:hover{background-color:#fff;color:#3e8ed0}.button.is-info.is-inverted.is-outlined.is-loading.is-focused::after,.button.is-info.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-info.is-inverted.is-outlined.is-loading:focus::after,.button.is-info.is-inverted.is-outlined.is-loading:hover::after{border-color:transparent transparent #3e8ed0 #3e8ed0!important}.button.is-info.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-info.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-info.is-light{background-color:#eff5fb;color:#296fa8}.button.is-info.is-light.is-hovered,.button.is-info.is-light:hover{background-color:#e4eff9;border-color:transparent;color:#296fa8}.button.is-info.is-light.is-active,.button.is-info.is-light:active{background-color:#dae9f6;border-color:transparent;color:#296fa8}.button.is-success{background-color:#48c78e;border-color:transparent;color:#fff}.button.is-success.is-hovered,.button.is-success:hover{background-color:#3ec487;border-color:transparent;color:#fff}.button.is-success.is-focused,.button.is-success:focus{border-color:transparent;color:#fff}.button.is-success.is-focused:not(:active),.button.is-success:focus:not(:active){box-shadow:0 0 0 .125em rgba(72,199,142,.25)}.button.is-success.is-active,.button.is-success:active{background-color:#3abb81;border-color:transparent;color:#fff}.button.is-success[disabled],fieldset[disabled] .button.is-success{background-color:#48c78e;border-color:#48c78e;box-shadow:none}.button.is-success.is-inverted{background-color:#fff;color:#48c78e}.button.is-success.is-inverted.is-hovered,.button.is-success.is-inverted:hover{background-color:#f2f2f2}.button.is-success.is-inverted[disabled],fieldset[disabled] .button.is-success.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#48c78e}.button.is-success.is-loading::after{border-color:transparent transparent #fff #fff!important}.button.is-success.is-outlined{background-color:transparent;border-color:#48c78e;color:#48c78e}.button.is-success.is-outlined.is-focused,.button.is-success.is-outlined.is-hovered,.button.is-success.is-outlined:focus,.button.is-success.is-outlined:hover{background-color:#48c78e;border-color:#48c78e;color:#fff}.button.is-success.is-outlined.is-loading::after{border-color:transparent transparent #48c78e #48c78e!important}.button.is-success.is-outlined.is-loading.is-focused::after,.button.is-success.is-outlined.is-loading.is-hovered::after,.button.is-success.is-outlined.is-loading:focus::after,.button.is-success.is-outlined.is-loading:hover::after{border-color:transparent transparent #fff #fff!important}.button.is-success.is-outlined[disabled],fieldset[disabled] .button.is-success.is-outlined{background-color:transparent;border-color:#48c78e;box-shadow:none;color:#48c78e}.button.is-success.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-success.is-inverted.is-outlined.is-focused,.button.is-success.is-inverted.is-outlined.is-hovered,.button.is-success.is-inverted.is-outlined:focus,.button.is-success.is-inverted.is-outlined:hover{background-color:#fff;color:#48c78e}.button.is-success.is-inverted.is-outlined.is-loading.is-focused::after,.button.is-success.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-success.is-inverted.is-outlined.is-loading:focus::after,.button.is-success.is-inverted.is-outlined.is-loading:hover::after{border-color:transparent transparent #48c78e #48c78e!important}.button.is-success.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-success.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-success.is-light{background-color:#effaf5;color:#257953}.button.is-success.is-light.is-hovered,.button.is-success.is-light:hover{background-color:#e6f7ef;border-color:transparent;color:#257953}.button.is-success.is-light.is-active,.button.is-success.is-light:active{background-color:#dcf4e9;border-color:transparent;color:#257953}.button.is-warning{background-color:#ffe08a;border-color:transparent;color:rgba(0,0,0,.7)}.button.is-warning.is-hovered,.button.is-warning:hover{background-color:#ffdc7d;border-color:transparent;color:rgba(0,0,0,.7)}.button.is-warning.is-focused,.button.is-warning:focus{border-color:transparent;color:rgba(0,0,0,.7)}.button.is-warning.is-focused:not(:active),.button.is-warning:focus:not(:active){box-shadow:0 0 0 .125em rgba(255,224,138,.25)}.button.is-warning.is-active,.button.is-warning:active{background-color:#ffd970;border-color:transparent;color:rgba(0,0,0,.7)}.button.is-warning[disabled],fieldset[disabled] .button.is-warning{background-color:#ffe08a;border-color:#ffe08a;box-shadow:none}.button.is-warning.is-inverted{background-color:rgba(0,0,0,.7);color:#ffe08a}.button.is-warning.is-inverted.is-hovered,.button.is-warning.is-inverted:hover{background-color:rgba(0,0,0,.7)}.button.is-warning.is-inverted[disabled],fieldset[disabled] .button.is-warning.is-inverted{background-color:rgba(0,0,0,.7);border-color:transparent;box-shadow:none;color:#ffe08a}.button.is-warning.is-loading::after{border-color:transparent transparent rgba(0,0,0,.7) rgba(0,0,0,.7)!important}.button.is-warning.is-outlined{background-color:transparent;border-color:#ffe08a;color:#ffe08a}.button.is-warning.is-outlined.is-focused,.button.is-warning.is-outlined.is-hovered,.button.is-warning.is-outlined:focus,.button.is-warning.is-outlined:hover{background-color:#ffe08a;border-color:#ffe08a;color:rgba(0,0,0,.7)}.button.is-warning.is-outlined.is-loading::after{border-color:transparent transparent #ffe08a #ffe08a!important}.button.is-warning.is-outlined.is-loading.is-focused::after,.button.is-warning.is-outlined.is-loading.is-hovered::after,.button.is-warning.is-outlined.is-loading:focus::after,.button.is-warning.is-outlined.is-loading:hover::after{border-color:transparent transparent rgba(0,0,0,.7) rgba(0,0,0,.7)!important}.button.is-warning.is-outlined[disabled],fieldset[disabled] .button.is-warning.is-outlined{background-color:transparent;border-color:#ffe08a;box-shadow:none;color:#ffe08a}.button.is-warning.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,.7);color:rgba(0,0,0,.7)}.button.is-warning.is-inverted.is-outlined.is-focused,.button.is-warning.is-inverted.is-outlined.is-hovered,.button.is-warning.is-inverted.is-outlined:focus,.button.is-warning.is-inverted.is-outlined:hover{background-color:rgba(0,0,0,.7);color:#ffe08a}.button.is-warning.is-inverted.is-outlined.is-loading.is-focused::after,.button.is-warning.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-warning.is-inverted.is-outlined.is-loading:focus::after,.button.is-warning.is-inverted.is-outlined.is-loading:hover::after{border-color:transparent transparent #ffe08a #ffe08a!important}.button.is-warning.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-warning.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,.7);box-shadow:none;color:rgba(0,0,0,.7)}.button.is-warning.is-light{background-color:#fffaeb;color:#946c00}.button.is-warning.is-light.is-hovered,.button.is-warning.is-light:hover{background-color:#fff6de;border-color:transparent;color:#946c00}.button.is-warning.is-light.is-active,.button.is-warning.is-light:active{background-color:#fff3d1;border-color:transparent;color:#946c00}.button.is-danger{background-color:#f14668;border-color:transparent;color:#fff}.button.is-danger.is-hovered,.button.is-danger:hover{background-color:#f03a5f;border-color:transparent;color:#fff}.button.is-danger.is-focused,.button.is-danger:focus{border-color:transparent;color:#fff}.button.is-danger.is-focused:not(:active),.button.is-danger:focus:not(:active){box-shadow:0 0 0 .125em rgba(241,70,104,.25)}.button.is-danger.is-active,.button.is-danger:active{background-color:#ef2e55;border-color:transparent;color:#fff}.button.is-danger[disabled],fieldset[disabled] .button.is-danger{background-color:#f14668;border-color:#f14668;box-shadow:none}.button.is-danger.is-inverted{background-color:#fff;color:#f14668}.button.is-danger.is-inverted.is-hovered,.button.is-danger.is-inverted:hover{background-color:#f2f2f2}.button.is-danger.is-inverted[disabled],fieldset[disabled] .button.is-danger.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#f14668}.button.is-danger.is-loading::after{border-color:transparent transparent #fff #fff!important}.button.is-danger.is-outlined{background-color:transparent;border-color:#f14668;color:#f14668}.button.is-danger.is-outlined.is-focused,.button.is-danger.is-outlined.is-hovered,.button.is-danger.is-outlined:focus,.button.is-danger.is-outlined:hover{background-color:#f14668;border-color:#f14668;color:#fff}.button.is-danger.is-outlined.is-loading::after{border-color:transparent transparent #f14668 #f14668!important}.button.is-danger.is-outlined.is-loading.is-focused::after,.button.is-danger.is-outlined.is-loading.is-hovered::after,.button.is-danger.is-outlined.is-loading:focus::after,.button.is-danger.is-outlined.is-loading:hover::after{border-color:transparent transparent #fff #fff!important}.button.is-danger.is-outlined[disabled],fieldset[disabled] .button.is-danger.is-outlined{background-color:transparent;border-color:#f14668;box-shadow:none;color:#f14668}.button.is-danger.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-danger.is-inverted.is-outlined.is-focused,.button.is-danger.is-inverted.is-outlined.is-hovered,.button.is-danger.is-inverted.is-outlined:focus,.button.is-danger.is-inverted.is-outlined:hover{background-color:#fff;color:#f14668}.button.is-danger.is-inverted.is-outlined.is-loading.is-focused::after,.button.is-danger.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-danger.is-inverted.is-outlined.is-loading:focus::after,.button.is-danger.is-inverted.is-outlined.is-loading:hover::after{border-color:transparent transparent #f14668 #f14668!important}.button.is-danger.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-danger.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-danger.is-light{background-color:#feecf0;color:#cc0f35}.button.is-danger.is-light.is-hovered,.button.is-danger.is-light:hover{background-color:#fde0e6;border-color:transparent;color:#cc0f35}.button.is-danger.is-light.is-active,.button.is-danger.is-light:active{background-color:#fcd4dc;border-color:transparent;color:#cc0f35}.button.is-small{font-size:.75rem}.button.is-small:not(.is-rounded){border-radius:2px}.button.is-normal{font-size:1rem}.button.is-medium{font-size:1.25rem}.button.is-large{font-size:1.5rem}.button[disabled],fieldset[disabled] .button{background-color:#fff;border-color:#dbdbdb;box-shadow:none;opacity:.5}.button.is-fullwidth{display:flex;width:100%}.button.is-loading{color:transparent!important;pointer-events:none}.button.is-loading::after{position:absolute;left:calc(50% - (1em * .5));top:calc(50% - (1em * .5));position:absolute!important}.button.is-static{background-color:#f5f5f5;border-color:#dbdbdb;color:#7a7a7a;box-shadow:none;pointer-events:none}.button.is-rounded{border-radius:9999px;padding-left:calc(1em + .25em);padding-right:calc(1em + .25em)}.buttons{align-items:center;display:flex;flex-wrap:wrap;justify-content:flex-start}.buttons .button{margin-bottom:.5rem}.buttons .button:not(:last-child):not(.is-fullwidth){margin-right:.5rem}.buttons:last-child{margin-bottom:-.5rem}.buttons:not(:last-child){margin-bottom:1rem}.buttons.are-small .button:not(.is-normal):not(.is-medium):not(.is-large){font-size:.75rem}.buttons.are-small .button:not(.is-normal):not(.is-medium):not(.is-large):not(.is-rounded){border-radius:2px}.buttons.are-medium .button:not(.is-small):not(.is-normal):not(.is-large){font-size:1.25rem}.buttons.are-large .button:not(.is-small):not(.is-normal):not(.is-medium){font-size:1.5rem}.buttons.has-addons .button:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.buttons.has-addons .button:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0;margin-right:-1px}.buttons.has-addons .button:last-child{margin-right:0}.buttons.has-addons .button.is-hovered,.buttons.has-addons .button:hover{z-index:2}.buttons.has-addons .button.is-active,.buttons.has-addons .button.is-focused,.buttons.has-addons .button.is-selected,.buttons.has-addons .button:active,.buttons.has-addons .button:focus{z-index:3}.buttons.has-addons .button.is-active:hover,.buttons.has-addons .button.is-focused:hover,.buttons.has-addons .button.is-selected:hover,.buttons.has-addons .button:active:hover,.buttons.has-addons .button:focus:hover{z-index:4}.buttons.has-addons .button.is-expanded{flex-grow:1;flex-shrink:1}.buttons.is-centered{justify-content:center}.buttons.is-centered:not(.has-addons) .button:not(.is-fullwidth){margin-left:.25rem;margin-right:.25rem}.buttons.is-right{justify-content:flex-end}.buttons.is-right:not(.has-addons) .button:not(.is-fullwidth){margin-left:.25rem;margin-right:.25rem}@media screen and (max-width:768px){.button.is-responsive.is-small{font-size:.5625rem}.button.is-responsive,.button.is-responsive.is-normal{font-size:.65625rem}.button.is-responsive.is-medium{font-size:.75rem}.button.is-responsive.is-large{font-size:1rem}}@media screen and (min-width:769px) and (max-width:1023px){.button.is-responsive.is-small{font-size:.65625rem}.button.is-responsive,.button.is-responsive.is-normal{font-size:.75rem}.button.is-responsive.is-medium{font-size:1rem}.button.is-responsive.is-large{font-size:1.25rem}}.container{flex-grow:1;margin:0 auto;position:relative;width:auto}.container.is-fluid{max-width:none!important;padding-left:32px;padding-right:32px;width:100%}@media screen and (min-width:1024px){.container{max-width:960px}}@media screen and (max-width:1215px){.container.is-widescreen:not(.is-max-desktop){max-width:1152px}}@media screen and (max-width:1407px){.container.is-fullhd:not(.is-max-desktop):not(.is-max-widescreen){max-width:1344px}}@media screen and (min-width:1216px){.container:not(.is-max-desktop){max-width:1152px}}@media screen and (min-width:1408px){.container:not(.is-max-desktop):not(.is-max-widescreen){max-width:1344px}}.content li+li{margin-top:.25em}.content blockquote:not(:last-child),.content dl:not(:last-child),.content ol:not(:last-child),.content p:not(:last-child),.content pre:not(:last-child),.content table:not(:last-child),.content ul:not(:last-child){margin-bottom:1em}.content h1,.content h2,.content h3,.content h4,.content h5,.content h6{color:#363636;font-weight:600;line-height:1.125}.content h1{font-size:2em;margin-bottom:.5em}.content h1:not(:first-child){margin-top:1em}.content h2{font-size:1.75em;margin-bottom:.5714em}.content h2:not(:first-child){margin-top:1.1428em}.content h3{font-size:1.5em;margin-bottom:.6666em}.content h3:not(:first-child){margin-top:1.3333em}.content h4{font-size:1.25em;margin-bottom:.8em}.content h5{font-size:1.125em;margin-bottom:.8888em}.content h6{font-size:1em;margin-bottom:1em}.content blockquote{background-color:#f5f5f5;border-left:5px solid #dbdbdb;padding:1.25em 1.5em}.content ol{list-style-position:outside;margin-left:2em;margin-top:1em}.content ol:not([type]){list-style-type:decimal}.content ol:not([type]).is-lower-alpha{list-style-type:lower-alpha}.content ol:not([type]).is-lower-roman{list-style-type:lower-roman}.content ol:not([type]).is-upper-alpha{list-style-type:upper-alpha}.content ol:not([type]).is-upper-roman{list-style-type:upper-roman}.content ul{list-style:disc outside;margin-left:2em;margin-top:1em}.content ul ul{list-style-type:circle;margin-top:.5em}.content ul ul ul{list-style-type:square}.content dd{margin-left:2em}.content figure{margin-left:2em;margin-right:2em;text-align:center}.content figure:not(:first-child){margin-top:2em}.content figure:not(:last-child){margin-bottom:2em}.content figure img{display:inline-block}.content figure figcaption{font-style:italic}.content pre{-webkit-overflow-scrolling:touch;overflow-x:auto;padding:1.25em 1.5em;white-space:pre;word-wrap:normal}.content sub,.content sup{font-size:75%}.content table{width:100%}.content table td,.content table th{border:1px solid #dbdbdb;border-width:0 0 1px;padding:.5em .75em;vertical-align:top}.content table th{color:#363636}.content table th:not([align]){text-align:inherit}.content table thead td,.content table thead th{border-width:0 0 2px;color:#363636}.content table tfoot td,.content table tfoot th{border-width:2px 0 0;color:#363636}.content table tbody tr:last-child td,.content table tbody tr:last-child th{border-bottom-width:0}.content .tabs li+li{margin-top:0}.content.is-small{font-size:.75rem}.content.is-normal{font-size:1rem}.content.is-medium{font-size:1.25rem}.content.is-large{font-size:1.5rem}.icon{align-items:center;display:inline-flex;justify-content:center;height:1.5rem;width:1.5rem}.icon.is-small{height:1rem;width:1rem}.icon.is-medium{height:2rem;width:2rem}.icon.is-large{height:3rem;width:3rem}.icon-text{align-items:flex-start;color:inherit;display:inline-flex;flex-wrap:wrap;line-height:1.5rem;vertical-align:top}.icon-text .icon{flex-grow:0;flex-shrink:0}.icon-text .icon:not(:last-child){margin-right:.25em}.icon-text .icon:not(:first-child){margin-left:.25em}div.icon-text{display:flex}.image{display:block;position:relative}.image img{display:block;height:auto;width:100%}.image img.is-rounded{border-radius:9999px}.image.is-fullwidth{width:100%}.image.is-16by9 .has-ratio,.image.is-16by9 img,.image.is-1by1 .has-ratio,.image.is-1by1 img,.image.is-1by2 .has-ratio,.image.is-1by2 img,.image.is-1by3 .has-ratio,.image.is-1by3 img,.image.is-2by1 .has-ratio,.image.is-2by1 img,.image.is-2by3 .has-ratio,.image.is-2by3 img,.image.is-3by1 .has-ratio,.image.is-3by1 img,.image.is-3by2 .has-ratio,.image.is-3by2 img,.image.is-3by4 .has-ratio,.image.is-3by4 img,.image.is-3by5 .has-ratio,.image.is-3by5 img,.image.is-4by3 .has-ratio,.image.is-4by3 img,.image.is-4by5 .has-ratio,.image.is-4by5 img,.image.is-5by3 .has-ratio,.image.is-5by3 img,.image.is-5by4 .has-ratio,.image.is-5by4 img,.image.is-9by16 .has-ratio,.image.is-9by16 img,.image.is-square .has-ratio,.image.is-square img{height:100%;width:100%}.image.is-1by1,.image.is-square{padding-top:100%}.image.is-5by4{padding-top:80%}.image.is-4by3{padding-top:75%}.image.is-3by2{padding-top:66.6666%}.image.is-5by3{padding-top:60%}.image.is-16by9{padding-top:56.25%}.image.is-2by1{padding-top:50%}.image.is-3by1{padding-top:33.3333%}.image.is-4by5{padding-top:125%}.image.is-3by4{padding-top:133.3333%}.image.is-2by3{padding-top:150%}.image.is-3by5{padding-top:166.6666%}.image.is-9by16{padding-top:177.7777%}.image.is-1by2{padding-top:200%}.image.is-1by3{padding-top:300%}.image.is-16x16{height:16px;width:16px}.image.is-24x24{height:24px;width:24px}.image.is-32x32{height:32px;width:32px}.image.is-48x48{height:48px;width:48px}.image.is-64x64{height:64px;width:64px}.image.is-96x96{height:96px;width:96px}.image.is-128x128{height:128px;width:128px}.notification{background-color:#f5f5f5;border-radius:4px;position:relative;padding:1.25rem 2.5rem 1.25rem 1.5rem}.notification a:not(.button):not(.dropdown-item){color:currentColor;text-decoration:underline}.notification strong{color:currentColor}.notification code,.notification pre{background:#fff}.notification pre code{background:0 0}.notification>.delete{right:.5rem;position:absolute;top:.5rem}.notification .content,.notification .subtitle,.notification .title{color:currentColor}.notification.is-white{background-color:#fff;color:#0a0a0a}.notification.is-black{background-color:#0a0a0a;color:#fff}.notification.is-light{background-color:#f5f5f5;color:rgba(0,0,0,.7)}.notification.is-dark{background-color:#363636;color:#fff}.notification.is-primary{background-color:#00d1b2;color:#fff}.notification.is-primary.is-light{background-color:#ebfffc;color:#00947e}.notification.is-link{background-color:#485fc7;color:#fff}.notification.is-link.is-light{background-color:#eff1fa;color:#3850b7}.notification.is-info{background-color:#3e8ed0;color:#fff}.notification.is-info.is-light{background-color:#eff5fb;color:#296fa8}.notification.is-success{background-color:#48c78e;color:#fff}.notification.is-success.is-light{background-color:#effaf5;color:#257953}.notification.is-warning{background-color:#ffe08a;color:rgba(0,0,0,.7)}.notification.is-warning.is-light{background-color:#fffaeb;color:#946c00}.notification.is-danger{background-color:#f14668;color:#fff}.notification.is-danger.is-light{background-color:#feecf0;color:#cc0f35}.progress{-moz-appearance:none;-webkit-appearance:none;border:none;border-radius:9999px;display:block;height:1rem;overflow:hidden;padding:0;width:100%}.progress::-webkit-progress-bar{background-color:#ededed}.progress::-webkit-progress-value{background-color:#4a4a4a}.progress::-moz-progress-bar{background-color:#4a4a4a}.progress::-ms-fill{background-color:#4a4a4a;border:none}.progress.is-white::-webkit-progress-value{background-color:#fff}.progress.is-white::-moz-progress-bar{background-color:#fff}.progress.is-white::-ms-fill{background-color:#fff}.progress.is-white:indeterminate{background-image:linear-gradient(to right,#fff 30%,#ededed 30%)}.progress.is-black::-webkit-progress-value{background-color:#0a0a0a}.progress.is-black::-moz-progress-bar{background-color:#0a0a0a}.progress.is-black::-ms-fill{background-color:#0a0a0a}.progress.is-black:indeterminate{background-image:linear-gradient(to right,#0a0a0a 30%,#ededed 30%)}.progress.is-light::-webkit-progress-value{background-color:#f5f5f5}.progress.is-light::-moz-progress-bar{background-color:#f5f5f5}.progress.is-light::-ms-fill{background-color:#f5f5f5}.progress.is-light:indeterminate{background-image:linear-gradient(to right,#f5f5f5 30%,#ededed 30%)}.progress.is-dark::-webkit-progress-value{background-color:#363636}.progress.is-dark::-moz-progress-bar{background-color:#363636}.progress.is-dark::-ms-fill{background-color:#363636}.progress.is-dark:indeterminate{background-image:linear-gradient(to right,#363636 30%,#ededed 30%)}.progress.is-primary::-webkit-progress-value{background-color:#00d1b2}.progress.is-primary::-moz-progress-bar{background-color:#00d1b2}.progress.is-primary::-ms-fill{background-color:#00d1b2}.progress.is-primary:indeterminate{background-image:linear-gradient(to right,#00d1b2 30%,#ededed 30%)}.progress.is-link::-webkit-progress-value{background-color:#485fc7}.progress.is-link::-moz-progress-bar{background-color:#485fc7}.progress.is-link::-ms-fill{background-color:#485fc7}.progress.is-link:indeterminate{background-image:linear-gradient(to right,#485fc7 30%,#ededed 30%)}.progress.is-info::-webkit-progress-value{background-color:#3e8ed0}.progress.is-info::-moz-progress-bar{background-color:#3e8ed0}.progress.is-info::-ms-fill{background-color:#3e8ed0}.progress.is-info:indeterminate{background-image:linear-gradient(to right,#3e8ed0 30%,#ededed 30%)}.progress.is-success::-webkit-progress-value{background-color:#48c78e}.progress.is-success::-moz-progress-bar{background-color:#48c78e}.progress.is-success::-ms-fill{background-color:#48c78e}.progress.is-success:indeterminate{background-image:linear-gradient(to right,#48c78e 30%,#ededed 30%)}.progress.is-warning::-webkit-progress-value{background-color:#ffe08a}.progress.is-warning::-moz-progress-bar{background-color:#ffe08a}.progress.is-warning::-ms-fill{background-color:#ffe08a}.progress.is-warning:indeterminate{background-image:linear-gradient(to right,#ffe08a 30%,#ededed 30%)}.progress.is-danger::-webkit-progress-value{background-color:#f14668}.progress.is-danger::-moz-progress-bar{background-color:#f14668}.progress.is-danger::-ms-fill{background-color:#f14668}.progress.is-danger:indeterminate{background-image:linear-gradient(to right,#f14668 30%,#ededed 30%)}.progress:indeterminate{-webkit-animation-duration:1.5s;animation-duration:1.5s;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;-webkit-animation-name:moveIndeterminate;animation-name:moveIndeterminate;-webkit-animation-timing-function:linear;animation-timing-function:linear;background-color:#ededed;background-image:linear-gradient(to right,#4a4a4a 30%,#ededed 30%);background-position:top left;background-repeat:no-repeat;background-size:150% 150%}.progress:indeterminate::-webkit-progress-bar{background-color:transparent}.progress:indeterminate::-moz-progress-bar{background-color:transparent}.progress:indeterminate::-ms-fill{animation-name:none}.progress.is-small{height:.75rem}.progress.is-medium{height:1.25rem}.progress.is-large{height:1.5rem}@-webkit-keyframes moveIndeterminate{from{background-position:200% 0}to{background-position:-200% 0}}@keyframes moveIndeterminate{from{background-position:200% 0}to{background-position:-200% 0}}.table{background-color:#fff;color:#363636}.table td,.table th{border:1px solid #dbdbdb;border-width:0 0 1px;padding:.5em .75em;vertical-align:top}.table td.is-white,.table th.is-white{background-color:#fff;border-color:#fff;color:#0a0a0a}.table td.is-black,.table th.is-black{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}.table td.is-light,.table th.is-light{background-color:#f5f5f5;border-color:#f5f5f5;color:rgba(0,0,0,.7)}.table td.is-dark,.table th.is-dark{background-color:#363636;border-color:#363636;color:#fff}.table td.is-primary,.table th.is-primary{background-color:#00d1b2;border-color:#00d1b2;color:#fff}.table td.is-link,.table th.is-link{background-color:#485fc7;border-color:#485fc7;color:#fff}.table td.is-info,.table th.is-info{background-color:#3e8ed0;border-color:#3e8ed0;color:#fff}.table td.is-success,.table th.is-success{background-color:#48c78e;border-color:#48c78e;color:#fff}.table td.is-warning,.table th.is-warning{background-color:#ffe08a;border-color:#ffe08a;color:rgba(0,0,0,.7)}.table td.is-danger,.table th.is-danger{background-color:#f14668;border-color:#f14668;color:#fff}.table td.is-narrow,.table th.is-narrow{white-space:nowrap;width:1%}.table td.is-selected,.table th.is-selected{background-color:#00d1b2;color:#fff}.table td.is-selected a,.table td.is-selected strong,.table th.is-selected a,.table th.is-selected strong{color:currentColor}.table td.is-vcentered,.table th.is-vcentered{vertical-align:middle}.table th{color:#363636}.table th:not([align]){text-align:left}.table tr.is-selected{background-color:#00d1b2;color:#fff}.table tr.is-selected a,.table tr.is-selected strong{color:currentColor}.table tr.is-selected td,.table tr.is-selected th{border-color:#fff;color:currentColor}.table thead{background-color:transparent}.table thead td,.table thead th{border-width:0 0 2px;color:#363636}.table tfoot{background-color:transparent}.table tfoot td,.table tfoot th{border-width:2px 0 0;color:#363636}.table tbody{background-color:transparent}.table tbody tr:last-child td,.table tbody tr:last-child th{border-bottom-width:0}.table.is-bordered td,.table.is-bordered th{border-width:1px}.table.is-bordered tr:last-child td,.table.is-bordered tr:last-child th{border-bottom-width:1px}.table.is-fullwidth{width:100%}.table.is-hoverable tbody tr:not(.is-selected):hover{background-color:#fafafa}.table.is-hoverable.is-striped tbody tr:not(.is-selected):hover{background-color:#fafafa}.table.is-hoverable.is-striped tbody tr:not(.is-selected):hover:nth-child(2n){background-color:#f5f5f5}.table.is-narrow td,.table.is-narrow th{padding:.25em .5em}.table.is-striped tbody tr:not(.is-selected):nth-child(2n){background-color:#fafafa}.table-container{-webkit-overflow-scrolling:touch;overflow:auto;overflow-y:hidden;max-width:100%}.tags{align-items:center;display:flex;flex-wrap:wrap;justify-content:flex-start}.tags .tag{margin-bottom:.5rem}.tags .tag:not(:last-child){margin-right:.5rem}.tags:last-child{margin-bottom:-.5rem}.tags:not(:last-child){margin-bottom:1rem}.tags.are-medium .tag:not(.is-normal):not(.is-large){font-size:1rem}.tags.are-large .tag:not(.is-normal):not(.is-medium){font-size:1.25rem}.tags.is-centered{justify-content:center}.tags.is-centered .tag{margin-right:.25rem;margin-left:.25rem}.tags.is-right{justify-content:flex-end}.tags.is-right .tag:not(:first-child){margin-left:.5rem}.tags.is-right .tag:not(:last-child){margin-right:0}.tags.has-addons .tag{margin-right:0}.tags.has-addons .tag:not(:first-child){margin-left:0;border-top-left-radius:0;border-bottom-left-radius:0}.tags.has-addons .tag:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.tag:not(body){align-items:center;background-color:#f5f5f5;border-radius:4px;color:#4a4a4a;display:inline-flex;font-size:.75rem;height:2em;justify-content:center;line-height:1.5;padding-left:.75em;padding-right:.75em;white-space:nowrap}.tag:not(body) .delete{margin-left:.25rem;margin-right:-.375rem}.tag:not(body).is-white{background-color:#fff;color:#0a0a0a}.tag:not(body).is-black{background-color:#0a0a0a;color:#fff}.tag:not(body).is-light{background-color:#f5f5f5;color:rgba(0,0,0,.7)}.tag:not(body).is-dark{background-color:#363636;color:#fff}.tag:not(body).is-primary{background-color:#00d1b2;color:#fff}.tag:not(body).is-primary.is-light{background-color:#ebfffc;color:#00947e}.tag:not(body).is-link{background-color:#485fc7;color:#fff}.tag:not(body).is-link.is-light{background-color:#eff1fa;color:#3850b7}.tag:not(body).is-info{background-color:#3e8ed0;color:#fff}.tag:not(body).is-info.is-light{background-color:#eff5fb;color:#296fa8}.tag:not(body).is-success{background-color:#48c78e;color:#fff}.tag:not(body).is-success.is-light{background-color:#effaf5;color:#257953}.tag:not(body).is-warning{background-color:#ffe08a;color:rgba(0,0,0,.7)}.tag:not(body).is-warning.is-light{background-color:#fffaeb;color:#946c00}.tag:not(body).is-danger{background-color:#f14668;color:#fff}.tag:not(body).is-danger.is-light{background-color:#feecf0;color:#cc0f35}.tag:not(body).is-normal{font-size:.75rem}.tag:not(body).is-medium{font-size:1rem}.tag:not(body).is-large{font-size:1.25rem}.tag:not(body) .icon:first-child:not(:last-child){margin-left:-.375em;margin-right:.1875em}.tag:not(body) .icon:last-child:not(:first-child){margin-left:.1875em;margin-right:-.375em}.tag:not(body) .icon:first-child:last-child{margin-left:-.375em;margin-right:-.375em}.tag:not(body).is-delete{margin-left:1px;padding:0;position:relative;width:2em}.tag:not(body).is-delete::after,.tag:not(body).is-delete::before{background-color:currentColor;content:"";display:block;left:50%;position:absolute;top:50%;transform:translateX(-50%) translateY(-50%) rotate(45deg);transform-origin:center center}.tag:not(body).is-delete::before{height:1px;width:50%}.tag:not(body).is-delete::after{height:50%;width:1px}.tag:not(body).is-delete:focus,.tag:not(body).is-delete:hover{background-color:#e8e8e8}.tag:not(body).is-delete:active{background-color:#dbdbdb}.tag:not(body).is-rounded{border-radius:9999px}a.tag:hover{text-decoration:underline}.subtitle,.title{word-break:break-word}.subtitle em,.subtitle span,.title em,.title span{font-weight:inherit}.subtitle sub,.title sub{font-size:.75em}.subtitle sup,.title sup{font-size:.75em}.subtitle .tag,.title .tag{vertical-align:middle}.title{color:#363636;font-size:2rem;font-weight:600;line-height:1.125}.title strong{color:inherit;font-weight:inherit}.title:not(.is-spaced)+.subtitle{margin-top:-1.25rem}.title.is-1{font-size:3rem}.title.is-2{font-size:2.5rem}.title.is-3{font-size:2rem}.title.is-4{font-size:1.5rem}.title.is-5{font-size:1.25rem}.title.is-6{font-size:1rem}.title.is-7{font-size:.75rem}.subtitle{color:#4a4a4a;font-size:1.25rem;font-weight:400;line-height:1.25}.subtitle strong{color:#363636;font-weight:600}.subtitle:not(.is-spaced)+.title{margin-top:-1.25rem}.subtitle.is-1{font-size:3rem}.subtitle.is-2{font-size:2.5rem}.subtitle.is-3{font-size:2rem}.subtitle.is-4{font-size:1.5rem}.subtitle.is-5{font-size:1.25rem}.subtitle.is-6{font-size:1rem}.subtitle.is-7{font-size:.75rem}.heading{display:block;font-size:11px;letter-spacing:1px;margin-bottom:5px;text-transform:uppercase}.number{align-items:center;background-color:#f5f5f5;border-radius:9999px;display:inline-flex;font-size:1.25rem;height:2em;justify-content:center;margin-right:1.5rem;min-width:2.5em;padding:.25rem .5rem;text-align:center;vertical-align:top}.input,.select select,.textarea{background-color:#fff;border-color:#dbdbdb;border-radius:4px;color:#363636}.input::-moz-placeholder,.select select::-moz-placeholder,.textarea::-moz-placeholder{color:rgba(54,54,54,.3)}.input::-webkit-input-placeholder,.select select::-webkit-input-placeholder,.textarea::-webkit-input-placeholder{color:rgba(54,54,54,.3)}.input:-moz-placeholder,.select select:-moz-placeholder,.textarea:-moz-placeholder{color:rgba(54,54,54,.3)}.input:-ms-input-placeholder,.select select:-ms-input-placeholder,.textarea:-ms-input-placeholder{color:rgba(54,54,54,.3)}.input:hover,.is-hovered.input,.is-hovered.textarea,.select select.is-hovered,.select select:hover,.textarea:hover{border-color:#b5b5b5}.input:active,.input:focus,.is-active.input,.is-active.textarea,.is-focused.input,.is-focused.textarea,.select select.is-active,.select select.is-focused,.select select:active,.select select:focus,.textarea:active,.textarea:focus{border-color:#485fc7;box-shadow:0 0 0 .125em rgba(72,95,199,.25)}.input[disabled],.select fieldset[disabled] select,.select select[disabled],.textarea[disabled],fieldset[disabled] .input,fieldset[disabled] .select select,fieldset[disabled] .textarea{background-color:#f5f5f5;border-color:#f5f5f5;box-shadow:none;color:#7a7a7a}.input[disabled]::-moz-placeholder,.select fieldset[disabled] select::-moz-placeholder,.select select[disabled]::-moz-placeholder,.textarea[disabled]::-moz-placeholder,fieldset[disabled] .input::-moz-placeholder,fieldset[disabled] .select select::-moz-placeholder,fieldset[disabled] .textarea::-moz-placeholder{color:rgba(122,122,122,.3)}.input[disabled]::-webkit-input-placeholder,.select fieldset[disabled] select::-webkit-input-placeholder,.select select[disabled]::-webkit-input-placeholder,.textarea[disabled]::-webkit-input-placeholder,fieldset[disabled] .input::-webkit-input-placeholder,fieldset[disabled] .select select::-webkit-input-placeholder,fieldset[disabled] .textarea::-webkit-input-placeholder{color:rgba(122,122,122,.3)}.input[disabled]:-moz-placeholder,.select fieldset[disabled] select:-moz-placeholder,.select select[disabled]:-moz-placeholder,.textarea[disabled]:-moz-placeholder,fieldset[disabled] .input:-moz-placeholder,fieldset[disabled] .select select:-moz-placeholder,fieldset[disabled] .textarea:-moz-placeholder{color:rgba(122,122,122,.3)}.input[disabled]:-ms-input-placeholder,.select fieldset[disabled] select:-ms-input-placeholder,.select select[disabled]:-ms-input-placeholder,.textarea[disabled]:-ms-input-placeholder,fieldset[disabled] .input:-ms-input-placeholder,fieldset[disabled] .select select:-ms-input-placeholder,fieldset[disabled] .textarea:-ms-input-placeholder{color:rgba(122,122,122,.3)}.input,.textarea{box-shadow:inset 0 .0625em .125em rgba(10,10,10,.05);max-width:100%;width:100%}.input[readonly],.textarea[readonly]{box-shadow:none}.is-white.input,.is-white.textarea{border-color:#fff}.is-white.input:active,.is-white.input:focus,.is-white.is-active.input,.is-white.is-active.textarea,.is-white.is-focused.input,.is-white.is-focused.textarea,.is-white.textarea:active,.is-white.textarea:focus{box-shadow:0 0 0 .125em rgba(255,255,255,.25)}.is-black.input,.is-black.textarea{border-color:#0a0a0a}.is-black.input:active,.is-black.input:focus,.is-black.is-active.input,.is-black.is-active.textarea,.is-black.is-focused.input,.is-black.is-focused.textarea,.is-black.textarea:active,.is-black.textarea:focus{box-shadow:0 0 0 .125em rgba(10,10,10,.25)}.is-light.input,.is-light.textarea{border-color:#f5f5f5}.is-light.input:active,.is-light.input:focus,.is-light.is-active.input,.is-light.is-active.textarea,.is-light.is-focused.input,.is-light.is-focused.textarea,.is-light.textarea:active,.is-light.textarea:focus{box-shadow:0 0 0 .125em rgba(245,245,245,.25)}.is-dark.input,.is-dark.textarea{border-color:#363636}.is-dark.input:active,.is-dark.input:focus,.is-dark.is-active.input,.is-dark.is-active.textarea,.is-dark.is-focused.input,.is-dark.is-focused.textarea,.is-dark.textarea:active,.is-dark.textarea:focus{box-shadow:0 0 0 .125em rgba(54,54,54,.25)}.is-primary.input,.is-primary.textarea{border-color:#00d1b2}.is-primary.input:active,.is-primary.input:focus,.is-primary.is-active.input,.is-primary.is-active.textarea,.is-primary.is-focused.input,.is-primary.is-focused.textarea,.is-primary.textarea:active,.is-primary.textarea:focus{box-shadow:0 0 0 .125em rgba(0,209,178,.25)}.is-link.input,.is-link.textarea{border-color:#485fc7}.is-link.input:active,.is-link.input:focus,.is-link.is-active.input,.is-link.is-active.textarea,.is-link.is-focused.input,.is-link.is-focused.textarea,.is-link.textarea:active,.is-link.textarea:focus{box-shadow:0 0 0 .125em rgba(72,95,199,.25)}.is-info.input,.is-info.textarea{border-color:#3e8ed0}.is-info.input:active,.is-info.input:focus,.is-info.is-active.input,.is-info.is-active.textarea,.is-info.is-focused.input,.is-info.is-focused.textarea,.is-info.textarea:active,.is-info.textarea:focus{box-shadow:0 0 0 .125em rgba(62,142,208,.25)}.is-success.input,.is-success.textarea{border-color:#48c78e}.is-success.input:active,.is-success.input:focus,.is-success.is-active.input,.is-success.is-active.textarea,.is-success.is-focused.input,.is-success.is-focused.textarea,.is-success.textarea:active,.is-success.textarea:focus{box-shadow:0 0 0 .125em rgba(72,199,142,.25)}.is-warning.input,.is-warning.textarea{border-color:#ffe08a}.is-warning.input:active,.is-warning.input:focus,.is-warning.is-active.input,.is-warning.is-active.textarea,.is-warning.is-focused.input,.is-warning.is-focused.textarea,.is-warning.textarea:active,.is-warning.textarea:focus{box-shadow:0 0 0 .125em rgba(255,224,138,.25)}.is-danger.input,.is-danger.textarea{border-color:#f14668}.is-danger.input:active,.is-danger.input:focus,.is-danger.is-active.input,.is-danger.is-active.textarea,.is-danger.is-focused.input,.is-danger.is-focused.textarea,.is-danger.textarea:active,.is-danger.textarea:focus{box-shadow:0 0 0 .125em rgba(241,70,104,.25)}.is-small.input,.is-small.textarea{border-radius:2px;font-size:.75rem}.is-medium.input,.is-medium.textarea{font-size:1.25rem}.is-large.input,.is-large.textarea{font-size:1.5rem}.is-fullwidth.input,.is-fullwidth.textarea{display:block;width:100%}.is-inline.input,.is-inline.textarea{display:inline;width:auto}.input.is-rounded{border-radius:9999px;padding-left:calc(calc(.75em - 1px) + .375em);padding-right:calc(calc(.75em - 1px) + .375em)}.input.is-static{background-color:transparent;border-color:transparent;box-shadow:none;padding-left:0;padding-right:0}.textarea{display:block;max-width:100%;min-width:100%;padding:calc(.75em - 1px);resize:vertical}.textarea:not([rows]){max-height:40em;min-height:8em}.textarea[rows]{height:initial}.textarea.has-fixed-size{resize:none}.checkbox,.radio{cursor:pointer;display:inline-block;line-height:1.25;position:relative}.checkbox input,.radio input{cursor:pointer}.checkbox:hover,.radio:hover{color:#363636}.checkbox input[disabled],.checkbox[disabled],.radio input[disabled],.radio[disabled],fieldset[disabled] .checkbox,fieldset[disabled] .radio{color:#7a7a7a;cursor:not-allowed}.radio+.radio{margin-left:.5em}.select{display:inline-block;max-width:100%;position:relative;vertical-align:top}.select:not(.is-multiple){height:2.5em}.select:not(.is-multiple):not(.is-loading)::after{border-color:#485fc7;right:1.125em;z-index:4}.select.is-rounded select{border-radius:9999px;padding-left:1em}.select select{cursor:pointer;display:block;font-size:1em;max-width:100%;outline:0}.select select::-ms-expand{display:none}.select select[disabled]:hover,fieldset[disabled] .select select:hover{border-color:#f5f5f5}.select select:not([multiple]){padding-right:2.5em}.select select[multiple]{height:auto;padding:0}.select select[multiple] option{padding:.5em 1em}.select:not(.is-multiple):not(.is-loading):hover::after{border-color:#363636}.select.is-white:not(:hover)::after{border-color:#fff}.select.is-white select{border-color:#fff}.select.is-white select.is-hovered,.select.is-white select:hover{border-color:#f2f2f2}.select.is-white select.is-active,.select.is-white select.is-focused,.select.is-white select:active,.select.is-white select:focus{box-shadow:0 0 0 .125em rgba(255,255,255,.25)}.select.is-black:not(:hover)::after{border-color:#0a0a0a}.select.is-black select{border-color:#0a0a0a}.select.is-black select.is-hovered,.select.is-black select:hover{border-color:#000}.select.is-black select.is-active,.select.is-black select.is-focused,.select.is-black select:active,.select.is-black select:focus{box-shadow:0 0 0 .125em rgba(10,10,10,.25)}.select.is-light:not(:hover)::after{border-color:#f5f5f5}.select.is-light select{border-color:#f5f5f5}.select.is-light select.is-hovered,.select.is-light select:hover{border-color:#e8e8e8}.select.is-light select.is-active,.select.is-light select.is-focused,.select.is-light select:active,.select.is-light select:focus{box-shadow:0 0 0 .125em rgba(245,245,245,.25)}.select.is-dark:not(:hover)::after{border-color:#363636}.select.is-dark select{border-color:#363636}.select.is-dark select.is-hovered,.select.is-dark select:hover{border-color:#292929}.select.is-dark select.is-active,.select.is-dark select.is-focused,.select.is-dark select:active,.select.is-dark select:focus{box-shadow:0 0 0 .125em rgba(54,54,54,.25)}.select.is-primary:not(:hover)::after{border-color:#00d1b2}.select.is-primary select{border-color:#00d1b2}.select.is-primary select.is-hovered,.select.is-primary select:hover{border-color:#00b89c}.select.is-primary select.is-active,.select.is-primary select.is-focused,.select.is-primary select:active,.select.is-primary select:focus{box-shadow:0 0 0 .125em rgba(0,209,178,.25)}.select.is-link:not(:hover)::after{border-color:#485fc7}.select.is-link select{border-color:#485fc7}.select.is-link select.is-hovered,.select.is-link select:hover{border-color:#3a51bb}.select.is-link select.is-active,.select.is-link select.is-focused,.select.is-link select:active,.select.is-link select:focus{box-shadow:0 0 0 .125em rgba(72,95,199,.25)}.select.is-info:not(:hover)::after{border-color:#3e8ed0}.select.is-info select{border-color:#3e8ed0}.select.is-info select.is-hovered,.select.is-info select:hover{border-color:#3082c5}.select.is-info select.is-active,.select.is-info select.is-focused,.select.is-info select:active,.select.is-info select:focus{box-shadow:0 0 0 .125em rgba(62,142,208,.25)}.select.is-success:not(:hover)::after{border-color:#48c78e}.select.is-success select{border-color:#48c78e}.select.is-success select.is-hovered,.select.is-success select:hover{border-color:#3abb81}.select.is-success select.is-active,.select.is-success select.is-focused,.select.is-success select:active,.select.is-success select:focus{box-shadow:0 0 0 .125em rgba(72,199,142,.25)}.select.is-warning:not(:hover)::after{border-color:#ffe08a}.select.is-warning select{border-color:#ffe08a}.select.is-warning select.is-hovered,.select.is-warning select:hover{border-color:#ffd970}.select.is-warning select.is-active,.select.is-warning select.is-focused,.select.is-warning select:active,.select.is-warning select:focus{box-shadow:0 0 0 .125em rgba(255,224,138,.25)}.select.is-danger:not(:hover)::after{border-color:#f14668}.select.is-danger select{border-color:#f14668}.select.is-danger select.is-hovered,.select.is-danger select:hover{border-color:#ef2e55}.select.is-danger select.is-active,.select.is-danger select.is-focused,.select.is-danger select:active,.select.is-danger select:focus{box-shadow:0 0 0 .125em rgba(241,70,104,.25)}.select.is-small{border-radius:2px;font-size:.75rem}.select.is-medium{font-size:1.25rem}.select.is-large{font-size:1.5rem}.select.is-disabled::after{border-color:#7a7a7a!important;opacity:.5}.select.is-fullwidth{width:100%}.select.is-fullwidth select{width:100%}.select.is-loading::after{margin-top:0;position:absolute;right:.625em;top:.625em;transform:none}.select.is-loading.is-small:after{font-size:.75rem}.select.is-loading.is-medium:after{font-size:1.25rem}.select.is-loading.is-large:after{font-size:1.5rem}.file{align-items:stretch;display:flex;justify-content:flex-start;position:relative}.file.is-white .file-cta{background-color:#fff;border-color:transparent;color:#0a0a0a}.file.is-white.is-hovered .file-cta,.file.is-white:hover .file-cta{background-color:#f9f9f9;border-color:transparent;color:#0a0a0a}.file.is-white.is-focused .file-cta,.file.is-white:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(255,255,255,.25);color:#0a0a0a}.file.is-white.is-active .file-cta,.file.is-white:active .file-cta{background-color:#f2f2f2;border-color:transparent;color:#0a0a0a}.file.is-black .file-cta{background-color:#0a0a0a;border-color:transparent;color:#fff}.file.is-black.is-hovered .file-cta,.file.is-black:hover .file-cta{background-color:#040404;border-color:transparent;color:#fff}.file.is-black.is-focused .file-cta,.file.is-black:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(10,10,10,.25);color:#fff}.file.is-black.is-active .file-cta,.file.is-black:active .file-cta{background-color:#000;border-color:transparent;color:#fff}.file.is-light .file-cta{background-color:#f5f5f5;border-color:transparent;color:rgba(0,0,0,.7)}.file.is-light.is-hovered .file-cta,.file.is-light:hover .file-cta{background-color:#eee;border-color:transparent;color:rgba(0,0,0,.7)}.file.is-light.is-focused .file-cta,.file.is-light:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(245,245,245,.25);color:rgba(0,0,0,.7)}.file.is-light.is-active .file-cta,.file.is-light:active .file-cta{background-color:#e8e8e8;border-color:transparent;color:rgba(0,0,0,.7)}.file.is-dark .file-cta{background-color:#363636;border-color:transparent;color:#fff}.file.is-dark.is-hovered .file-cta,.file.is-dark:hover .file-cta{background-color:#2f2f2f;border-color:transparent;color:#fff}.file.is-dark.is-focused .file-cta,.file.is-dark:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(54,54,54,.25);color:#fff}.file.is-dark.is-active .file-cta,.file.is-dark:active .file-cta{background-color:#292929;border-color:transparent;color:#fff}.file.is-primary .file-cta{background-color:#00d1b2;border-color:transparent;color:#fff}.file.is-primary.is-hovered .file-cta,.file.is-primary:hover .file-cta{background-color:#00c4a7;border-color:transparent;color:#fff}.file.is-primary.is-focused .file-cta,.file.is-primary:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(0,209,178,.25);color:#fff}.file.is-primary.is-active .file-cta,.file.is-primary:active .file-cta{background-color:#00b89c;border-color:transparent;color:#fff}.file.is-link .file-cta{background-color:#485fc7;border-color:transparent;color:#fff}.file.is-link.is-hovered .file-cta,.file.is-link:hover .file-cta{background-color:#3e56c4;border-color:transparent;color:#fff}.file.is-link.is-focused .file-cta,.file.is-link:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(72,95,199,.25);color:#fff}.file.is-link.is-active .file-cta,.file.is-link:active .file-cta{background-color:#3a51bb;border-color:transparent;color:#fff}.file.is-info .file-cta{background-color:#3e8ed0;border-color:transparent;color:#fff}.file.is-info.is-hovered .file-cta,.file.is-info:hover .file-cta{background-color:#3488ce;border-color:transparent;color:#fff}.file.is-info.is-focused .file-cta,.file.is-info:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(62,142,208,.25);color:#fff}.file.is-info.is-active .file-cta,.file.is-info:active .file-cta{background-color:#3082c5;border-color:transparent;color:#fff}.file.is-success .file-cta{background-color:#48c78e;border-color:transparent;color:#fff}.file.is-success.is-hovered .file-cta,.file.is-success:hover .file-cta{background-color:#3ec487;border-color:transparent;color:#fff}.file.is-success.is-focused .file-cta,.file.is-success:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(72,199,142,.25);color:#fff}.file.is-success.is-active .file-cta,.file.is-success:active .file-cta{background-color:#3abb81;border-color:transparent;color:#fff}.file.is-warning .file-cta{background-color:#ffe08a;border-color:transparent;color:rgba(0,0,0,.7)}.file.is-warning.is-hovered .file-cta,.file.is-warning:hover .file-cta{background-color:#ffdc7d;border-color:transparent;color:rgba(0,0,0,.7)}.file.is-warning.is-focused .file-cta,.file.is-warning:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(255,224,138,.25);color:rgba(0,0,0,.7)}.file.is-warning.is-active .file-cta,.file.is-warning:active .file-cta{background-color:#ffd970;border-color:transparent;color:rgba(0,0,0,.7)}.file.is-danger .file-cta{background-color:#f14668;border-color:transparent;color:#fff}.file.is-danger.is-hovered .file-cta,.file.is-danger:hover .file-cta{background-color:#f03a5f;border-color:transparent;color:#fff}.file.is-danger.is-focused .file-cta,.file.is-danger:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(241,70,104,.25);color:#fff}.file.is-danger.is-active .file-cta,.file.is-danger:active .file-cta{background-color:#ef2e55;border-color:transparent;color:#fff}.file.is-small{font-size:.75rem}.file.is-normal{font-size:1rem}.file.is-medium{font-size:1.25rem}.file.is-medium .file-icon .fa{font-size:21px}.file.is-large{font-size:1.5rem}.file.is-large .file-icon .fa{font-size:28px}.file.has-name .file-cta{border-bottom-right-radius:0;border-top-right-radius:0}.file.has-name .file-name{border-bottom-left-radius:0;border-top-left-radius:0}.file.has-name.is-empty .file-cta{border-radius:4px}.file.has-name.is-empty .file-name{display:none}.file.is-boxed .file-label{flex-direction:column}.file.is-boxed .file-cta{flex-direction:column;height:auto;padding:1em 3em}.file.is-boxed .file-name{border-width:0 1px 1px}.file.is-boxed .file-icon{height:1.5em;width:1.5em}.file.is-boxed .file-icon .fa{font-size:21px}.file.is-boxed.is-small .file-icon .fa{font-size:14px}.file.is-boxed.is-medium .file-icon .fa{font-size:28px}.file.is-boxed.is-large .file-icon .fa{font-size:35px}.file.is-boxed.has-name .file-cta{border-radius:4px 4px 0 0}.file.is-boxed.has-name .file-name{border-radius:0 0 4px 4px;border-width:0 1px 1px}.file.is-centered{justify-content:center}.file.is-fullwidth .file-label{width:100%}.file.is-fullwidth .file-name{flex-grow:1;max-width:none}.file.is-right{justify-content:flex-end}.file.is-right .file-cta{border-radius:0 4px 4px 0}.file.is-right .file-name{border-radius:4px 0 0 4px;border-width:1px 0 1px 1px;order:-1}.file-label{align-items:stretch;display:flex;cursor:pointer;justify-content:flex-start;overflow:hidden;position:relative}.file-label:hover .file-cta{background-color:#eee;color:#363636}.file-label:hover .file-name{border-color:#d5d5d5}.file-label:active .file-cta{background-color:#e8e8e8;color:#363636}.file-label:active .file-name{border-color:#cfcfcf}.file-input{height:100%;left:0;opacity:0;outline:0;position:absolute;top:0;width:100%}.file-cta,.file-name{border-color:#dbdbdb;border-radius:4px;font-size:1em;padding-left:1em;padding-right:1em;white-space:nowrap}.file-cta{background-color:#f5f5f5;color:#4a4a4a}.file-name{border-color:#dbdbdb;border-style:solid;border-width:1px 1px 1px 0;display:block;max-width:16em;overflow:hidden;text-align:inherit;text-overflow:ellipsis}.file-icon{align-items:center;display:flex;height:1em;justify-content:center;margin-right:.5em;width:1em}.file-icon .fa{font-size:14px}.label{color:#363636;display:block;font-size:1rem;font-weight:700}.label:not(:last-child){margin-bottom:.5em}.label.is-small{font-size:.75rem}.label.is-medium{font-size:1.25rem}.label.is-large{font-size:1.5rem}.help{display:block;font-size:.75rem;margin-top:.25rem}.help.is-white{color:#fff}.help.is-black{color:#0a0a0a}.help.is-light{color:#f5f5f5}.help.is-dark{color:#363636}.help.is-primary{color:#00d1b2}.help.is-link{color:#485fc7}.help.is-info{color:#3e8ed0}.help.is-success{color:#48c78e}.help.is-warning{color:#ffe08a}.help.is-danger{color:#f14668}.field:not(:last-child){margin-bottom:.75rem}.field.has-addons{display:flex;justify-content:flex-start}.field.has-addons .control:not(:last-child){margin-right:-1px}.field.has-addons .control:not(:first-child):not(:last-child) .button,.field.has-addons .control:not(:first-child):not(:last-child) .input,.field.has-addons .control:not(:first-child):not(:last-child) .select select{border-radius:0}.field.has-addons .control:first-child:not(:only-child) .button,.field.has-addons .control:first-child:not(:only-child) .input,.field.has-addons .control:first-child:not(:only-child) .select select{border-bottom-right-radius:0;border-top-right-radius:0}.field.has-addons .control:last-child:not(:only-child) .button,.field.has-addons .control:last-child:not(:only-child) .input,.field.has-addons .control:last-child:not(:only-child) .select select{border-bottom-left-radius:0;border-top-left-radius:0}.field.has-addons .control .button:not([disabled]).is-hovered,.field.has-addons .control .button:not([disabled]):hover,.field.has-addons .control .input:not([disabled]).is-hovered,.field.has-addons .control .input:not([disabled]):hover,.field.has-addons .control .select select:not([disabled]).is-hovered,.field.has-addons .control .select select:not([disabled]):hover{z-index:2}.field.has-addons .control .button:not([disabled]).is-active,.field.has-addons .control .button:not([disabled]).is-focused,.field.has-addons .control .button:not([disabled]):active,.field.has-addons .control .button:not([disabled]):focus,.field.has-addons .control .input:not([disabled]).is-active,.field.has-addons .control .input:not([disabled]).is-focused,.field.has-addons .control .input:not([disabled]):active,.field.has-addons .control .input:not([disabled]):focus,.field.has-addons .control .select select:not([disabled]).is-active,.field.has-addons .control .select select:not([disabled]).is-focused,.field.has-addons .control .select select:not([disabled]):active,.field.has-addons .control .select select:not([disabled]):focus{z-index:3}.field.has-addons .control .button:not([disabled]).is-active:hover,.field.has-addons .control .button:not([disabled]).is-focused:hover,.field.has-addons .control .button:not([disabled]):active:hover,.field.has-addons .control .button:not([disabled]):focus:hover,.field.has-addons .control .input:not([disabled]).is-active:hover,.field.has-addons .control .input:not([disabled]).is-focused:hover,.field.has-addons .control .input:not([disabled]):active:hover,.field.has-addons .control .input:not([disabled]):focus:hover,.field.has-addons .control .select select:not([disabled]).is-active:hover,.field.has-addons .control .select select:not([disabled]).is-focused:hover,.field.has-addons .control .select select:not([disabled]):active:hover,.field.has-addons .control .select select:not([disabled]):focus:hover{z-index:4}.field.has-addons .control.is-expanded{flex-grow:1;flex-shrink:1}.field.has-addons.has-addons-centered{justify-content:center}.field.has-addons.has-addons-right{justify-content:flex-end}.field.has-addons.has-addons-fullwidth .control{flex-grow:1;flex-shrink:0}.field.is-grouped{display:flex;justify-content:flex-start}.field.is-grouped>.control{flex-shrink:0}.field.is-grouped>.control:not(:last-child){margin-bottom:0;margin-right:.75rem}.field.is-grouped>.control.is-expanded{flex-grow:1;flex-shrink:1}.field.is-grouped.is-grouped-centered{justify-content:center}.field.is-grouped.is-grouped-right{justify-content:flex-end}.field.is-grouped.is-grouped-multiline{flex-wrap:wrap}.field.is-grouped.is-grouped-multiline>.control:last-child,.field.is-grouped.is-grouped-multiline>.control:not(:last-child){margin-bottom:.75rem}.field.is-grouped.is-grouped-multiline:last-child{margin-bottom:-.75rem}.field.is-grouped.is-grouped-multiline:not(:last-child){margin-bottom:0}@media screen and (min-width:769px),print{.field.is-horizontal{display:flex}}.field-label .label{font-size:inherit}@media screen and (max-width:768px){.field-label{margin-bottom:.5rem}}@media screen and (min-width:769px),print{.field-label{flex-basis:0;flex-grow:1;flex-shrink:0;margin-right:1.5rem;text-align:right}.field-label.is-small{font-size:.75rem;padding-top:.375em}.field-label.is-normal{padding-top:.375em}.field-label.is-medium{font-size:1.25rem;padding-top:.375em}.field-label.is-large{font-size:1.5rem;padding-top:.375em}}.field-body .field .field{margin-bottom:0}@media screen and (min-width:769px),print{.field-body{display:flex;flex-basis:0;flex-grow:5;flex-shrink:1}.field-body .field{margin-bottom:0}.field-body>.field{flex-shrink:1}.field-body>.field:not(.is-narrow){flex-grow:1}.field-body>.field:not(:last-child){margin-right:.75rem}}.control{box-sizing:border-box;clear:both;font-size:1rem;position:relative;text-align:inherit}.control.has-icons-left .input:focus~.icon,.control.has-icons-left .select:focus~.icon,.control.has-icons-right .input:focus~.icon,.control.has-icons-right .select:focus~.icon{color:#4a4a4a}.control.has-icons-left .input.is-small~.icon,.control.has-icons-left .select.is-small~.icon,.control.has-icons-right .input.is-small~.icon,.control.has-icons-right .select.is-small~.icon{font-size:.75rem}.control.has-icons-left .input.is-medium~.icon,.control.has-icons-left .select.is-medium~.icon,.control.has-icons-right .input.is-medium~.icon,.control.has-icons-right .select.is-medium~.icon{font-size:1.25rem}.control.has-icons-left .input.is-large~.icon,.control.has-icons-left .select.is-large~.icon,.control.has-icons-right .input.is-large~.icon,.control.has-icons-right .select.is-large~.icon{font-size:1.5rem}.control.has-icons-left .icon,.control.has-icons-right .icon{color:#dbdbdb;height:2.5em;pointer-events:none;position:absolute;top:0;width:2.5em;z-index:4}.control.has-icons-left .input,.control.has-icons-left .select select{padding-left:2.5em}.control.has-icons-left .icon.is-left{left:0}.control.has-icons-right .input,.control.has-icons-right .select select{padding-right:2.5em}.control.has-icons-right .icon.is-right{right:0}.control.is-loading::after{position:absolute!important;right:.625em;top:.625em;z-index:4}.control.is-loading.is-small:after{font-size:.75rem}.control.is-loading.is-medium:after{font-size:1.25rem}.control.is-loading.is-large:after{font-size:1.5rem}.breadcrumb{font-size:1rem;white-space:nowrap}.breadcrumb a{align-items:center;color:#485fc7;display:flex;justify-content:center;padding:0 .75em}.breadcrumb a:hover{color:#363636}.breadcrumb li{align-items:center;display:flex}.breadcrumb li:first-child a{padding-left:0}.breadcrumb li.is-active a{color:#363636;cursor:default;pointer-events:none}.breadcrumb li+li::before{color:#b5b5b5;content:"\0002f"}.breadcrumb ol,.breadcrumb ul{align-items:flex-start;display:flex;flex-wrap:wrap;justify-content:flex-start}.breadcrumb .icon:first-child{margin-right:.5em}.breadcrumb .icon:last-child{margin-left:.5em}.breadcrumb.is-centered ol,.breadcrumb.is-centered ul{justify-content:center}.breadcrumb.is-right ol,.breadcrumb.is-right ul{justify-content:flex-end}.breadcrumb.is-small{font-size:.75rem}.breadcrumb.is-medium{font-size:1.25rem}.breadcrumb.is-large{font-size:1.5rem}.breadcrumb.has-arrow-separator li+li::before{content:"\02192"}.breadcrumb.has-bullet-separator li+li::before{content:"\02022"}.breadcrumb.has-dot-separator li+li::before{content:"\000b7"}.breadcrumb.has-succeeds-separator li+li::before{content:"\0227B"}.card{background-color:#fff;border-radius:.25rem;box-shadow:0 .5em 1em -.125em rgba(10,10,10,.1),0 0 0 1px rgba(10,10,10,.02);color:#4a4a4a;max-width:100%;position:relative}.card-content:first-child,.card-footer:first-child,.card-header:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card-content:last-child,.card-footer:last-child,.card-header:last-child{border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem}.card-header{background-color:transparent;align-items:stretch;box-shadow:0 .125em .25em rgba(10,10,10,.1);display:flex}.card-header-title{align-items:center;color:#363636;display:flex;flex-grow:1;font-weight:700;padding:.75rem 1rem}.card-header-title.is-centered{justify-content:center}.card-header-icon{-moz-appearance:none;-webkit-appearance:none;appearance:none;background:0 0;border:none;color:currentColor;font-family:inherit;font-size:1em;margin:0;padding:0;align-items:center;cursor:pointer;display:flex;justify-content:center;padding:.75rem 1rem}.card-image{display:block;position:relative}.card-image:first-child img{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card-image:last-child img{border-bottom-left-radius:.25rem;border-bottom-right-radius:.25rem}.card-content{background-color:transparent;padding:1.5rem}.card-footer{background-color:transparent;border-top:1px solid #ededed;align-items:stretch;display:flex}.card-footer-item{align-items:center;display:flex;flex-basis:0;flex-grow:1;flex-shrink:0;justify-content:center;padding:.75rem}.card-footer-item:not(:last-child){border-right:1px solid #ededed}.card .media:not(:last-child){margin-bottom:1.5rem}.dropdown{display:inline-flex;position:relative;vertical-align:top}.dropdown.is-active .dropdown-menu,.dropdown.is-hoverable:hover .dropdown-menu{display:block}.dropdown.is-right .dropdown-menu{left:auto;right:0}.dropdown.is-up .dropdown-menu{bottom:100%;padding-bottom:4px;padding-top:initial;top:auto}.dropdown-menu{display:none;left:0;min-width:12rem;padding-top:4px;position:absolute;top:100%;z-index:20}.dropdown-content{background-color:#fff;border-radius:4px;box-shadow:0 .5em 1em -.125em rgba(10,10,10,.1),0 0 0 1px rgba(10,10,10,.02);padding-bottom:.5rem;padding-top:.5rem}.dropdown-item{color:#4a4a4a;display:block;font-size:.875rem;line-height:1.5;padding:.375rem 1rem;position:relative}a.dropdown-item,button.dropdown-item{padding-right:3rem;text-align:inherit;white-space:nowrap;width:100%}a.dropdown-item:hover,button.dropdown-item:hover{background-color:#f5f5f5;color:#0a0a0a}a.dropdown-item.is-active,button.dropdown-item.is-active{background-color:#485fc7;color:#fff}.dropdown-divider{background-color:#ededed;border:none;display:block;height:1px;margin:.5rem 0}.level{align-items:center;justify-content:space-between}.level code{border-radius:4px}.level img{display:inline-block;vertical-align:top}.level.is-mobile{display:flex}.level.is-mobile .level-left,.level.is-mobile .level-right{display:flex}.level.is-mobile .level-left+.level-right{margin-top:0}.level.is-mobile .level-item:not(:last-child){margin-bottom:0;margin-right:.75rem}.level.is-mobile .level-item:not(.is-narrow){flex-grow:1}@media screen and (min-width:769px),print{.level{display:flex}.level>.level-item:not(.is-narrow){flex-grow:1}}.level-item{align-items:center;display:flex;flex-basis:auto;flex-grow:0;flex-shrink:0;justify-content:center}.level-item .subtitle,.level-item .title{margin-bottom:0}@media screen and (max-width:768px){.level-item:not(:last-child){margin-bottom:.75rem}}.level-left,.level-right{flex-basis:auto;flex-grow:0;flex-shrink:0}.level-left .level-item.is-flexible,.level-right .level-item.is-flexible{flex-grow:1}@media screen and (min-width:769px),print{.level-left .level-item:not(:last-child),.level-right .level-item:not(:last-child){margin-right:.75rem}}.level-left{align-items:center;justify-content:flex-start}@media screen and (max-width:768px){.level-left+.level-right{margin-top:1.5rem}}@media screen and (min-width:769px),print{.level-left{display:flex}}.level-right{align-items:center;justify-content:flex-end}@media screen and (min-width:769px),print{.level-right{display:flex}}.media{align-items:flex-start;display:flex;text-align:inherit}.media .content:not(:last-child){margin-bottom:.75rem}.media .media{border-top:1px solid rgba(219,219,219,.5);display:flex;padding-top:.75rem}.media .media .content:not(:last-child),.media .media .control:not(:last-child){margin-bottom:.5rem}.media .media .media{padding-top:.5rem}.media .media .media+.media{margin-top:.5rem}.media+.media{border-top:1px solid rgba(219,219,219,.5);margin-top:1rem;padding-top:1rem}.media.is-large+.media{margin-top:1.5rem;padding-top:1.5rem}.media-left,.media-right{flex-basis:auto;flex-grow:0;flex-shrink:0}.media-left{margin-right:1rem}.media-right{margin-left:1rem}.media-content{flex-basis:auto;flex-grow:1;flex-shrink:1;text-align:inherit}@media screen and (max-width:768px){.media-content{overflow-x:auto}}.menu{font-size:1rem}.menu.is-small{font-size:.75rem}.menu.is-medium{font-size:1.25rem}.menu.is-large{font-size:1.5rem}.menu-list{line-height:1.25}.menu-list a{border-radius:2px;color:#4a4a4a;display:block;padding:.5em .75em}.menu-list a:hover{background-color:#f5f5f5;color:#363636}.menu-list a.is-active{background-color:#485fc7;color:#fff}.menu-list li ul{border-left:1px solid #dbdbdb;margin:.75em;padding-left:.75em}.menu-label{color:#7a7a7a;font-size:.75em;letter-spacing:.1em;text-transform:uppercase}.menu-label:not(:first-child){margin-top:1em}.menu-label:not(:last-child){margin-bottom:1em}.message{background-color:#f5f5f5;border-radius:4px;font-size:1rem}.message strong{color:currentColor}.message a:not(.button):not(.tag):not(.dropdown-item){color:currentColor;text-decoration:underline}.message.is-small{font-size:.75rem}.message.is-medium{font-size:1.25rem}.message.is-large{font-size:1.5rem}.message.is-white{background-color:#fff}.message.is-white .message-header{background-color:#fff;color:#0a0a0a}.message.is-white .message-body{border-color:#fff}.message.is-black{background-color:#fafafa}.message.is-black .message-header{background-color:#0a0a0a;color:#fff}.message.is-black .message-body{border-color:#0a0a0a}.message.is-light{background-color:#fafafa}.message.is-light .message-header{background-color:#f5f5f5;color:rgba(0,0,0,.7)}.message.is-light .message-body{border-color:#f5f5f5}.message.is-dark{background-color:#fafafa}.message.is-dark .message-header{background-color:#363636;color:#fff}.message.is-dark .message-body{border-color:#363636}.message.is-primary{background-color:#ebfffc}.message.is-primary .message-header{background-color:#00d1b2;color:#fff}.message.is-primary .message-body{border-color:#00d1b2;color:#00947e}.message.is-link{background-color:#eff1fa}.message.is-link .message-header{background-color:#485fc7;color:#fff}.message.is-link .message-body{border-color:#485fc7;color:#3850b7}.message.is-info{background-color:#eff5fb}.message.is-info .message-header{background-color:#3e8ed0;color:#fff}.message.is-info .message-body{border-color:#3e8ed0;color:#296fa8}.message.is-success{background-color:#effaf5}.message.is-success .message-header{background-color:#48c78e;color:#fff}.message.is-success .message-body{border-color:#48c78e;color:#257953}.message.is-warning{background-color:#fffaeb}.message.is-warning .message-header{background-color:#ffe08a;color:rgba(0,0,0,.7)}.message.is-warning .message-body{border-color:#ffe08a;color:#946c00}.message.is-danger{background-color:#feecf0}.message.is-danger .message-header{background-color:#f14668;color:#fff}.message.is-danger .message-body{border-color:#f14668;color:#cc0f35}.message-header{align-items:center;background-color:#4a4a4a;border-radius:4px 4px 0 0;color:#fff;display:flex;font-weight:700;justify-content:space-between;line-height:1.25;padding:.75em 1em;position:relative}.message-header .delete{flex-grow:0;flex-shrink:0;margin-left:.75em}.message-header+.message-body{border-width:0;border-top-left-radius:0;border-top-right-radius:0}.message-body{border-color:#dbdbdb;border-radius:4px;border-style:solid;border-width:0 0 0 4px;color:#4a4a4a;padding:1.25em 1.5em}.message-body code,.message-body pre{background-color:#fff}.message-body pre code{background-color:transparent}.modal{align-items:center;display:none;flex-direction:column;justify-content:center;overflow:hidden;position:fixed;z-index:40}.modal.is-active{display:flex}.modal-background{background-color:rgba(10,10,10,.86)}.modal-card,.modal-content{margin:0 20px;max-height:calc(100vh - 160px);overflow:auto;position:relative;width:100%}@media screen and (min-width:769px){.modal-card,.modal-content{margin:0 auto;max-height:calc(100vh - 40px);width:640px}}.modal-close{background:0 0;height:40px;position:fixed;right:20px;top:20px;width:40px}.modal-card{display:flex;flex-direction:column;max-height:calc(100vh - 40px);overflow:hidden;-ms-overflow-y:visible}.modal-card-foot,.modal-card-head{align-items:center;background-color:#f5f5f5;display:flex;flex-shrink:0;justify-content:flex-start;padding:20px;position:relative}.modal-card-head{border-bottom:1px solid #dbdbdb;border-top-left-radius:6px;border-top-right-radius:6px}.modal-card-title{color:#363636;flex-grow:1;flex-shrink:0;font-size:1.5rem;line-height:1}.modal-card-foot{border-bottom-left-radius:6px;border-bottom-right-radius:6px;border-top:1px solid #dbdbdb}.modal-card-foot .button:not(:last-child){margin-right:.5em}.modal-card-body{-webkit-overflow-scrolling:touch;background-color:#fff;flex-grow:1;flex-shrink:1;overflow:auto;padding:20px}.navbar{background-color:#fff;min-height:3.25rem;position:relative;z-index:30}.navbar.is-white{background-color:#fff;color:#0a0a0a}.navbar.is-white .navbar-brand .navbar-link,.navbar.is-white .navbar-brand>.navbar-item{color:#0a0a0a}.navbar.is-white .navbar-brand .navbar-link.is-active,.navbar.is-white .navbar-brand .navbar-link:focus,.navbar.is-white .navbar-brand .navbar-link:hover,.navbar.is-white .navbar-brand>a.navbar-item.is-active,.navbar.is-white .navbar-brand>a.navbar-item:focus,.navbar.is-white .navbar-brand>a.navbar-item:hover{background-color:#f2f2f2;color:#0a0a0a}.navbar.is-white .navbar-brand .navbar-link::after{border-color:#0a0a0a}.navbar.is-white .navbar-burger{color:#0a0a0a}@media screen and (min-width:1024px){.navbar.is-white .navbar-end .navbar-link,.navbar.is-white .navbar-end>.navbar-item,.navbar.is-white .navbar-start .navbar-link,.navbar.is-white .navbar-start>.navbar-item{color:#0a0a0a}.navbar.is-white .navbar-end .navbar-link.is-active,.navbar.is-white .navbar-end .navbar-link:focus,.navbar.is-white .navbar-end .navbar-link:hover,.navbar.is-white .navbar-end>a.navbar-item.is-active,.navbar.is-white .navbar-end>a.navbar-item:focus,.navbar.is-white .navbar-end>a.navbar-item:hover,.navbar.is-white .navbar-start .navbar-link.is-active,.navbar.is-white .navbar-start .navbar-link:focus,.navbar.is-white .navbar-start .navbar-link:hover,.navbar.is-white .navbar-start>a.navbar-item.is-active,.navbar.is-white .navbar-start>a.navbar-item:focus,.navbar.is-white .navbar-start>a.navbar-item:hover{background-color:#f2f2f2;color:#0a0a0a}.navbar.is-white .navbar-end .navbar-link::after,.navbar.is-white .navbar-start .navbar-link::after{border-color:#0a0a0a}.navbar.is-white .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-white .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-white .navbar-item.has-dropdown:hover .navbar-link{background-color:#f2f2f2;color:#0a0a0a}.navbar.is-white .navbar-dropdown a.navbar-item.is-active{background-color:#fff;color:#0a0a0a}}.navbar.is-black{background-color:#0a0a0a;color:#fff}.navbar.is-black .navbar-brand .navbar-link,.navbar.is-black .navbar-brand>.navbar-item{color:#fff}.navbar.is-black .navbar-brand .navbar-link.is-active,.navbar.is-black .navbar-brand .navbar-link:focus,.navbar.is-black .navbar-brand .navbar-link:hover,.navbar.is-black .navbar-brand>a.navbar-item.is-active,.navbar.is-black .navbar-brand>a.navbar-item:focus,.navbar.is-black .navbar-brand>a.navbar-item:hover{background-color:#000;color:#fff}.navbar.is-black .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-black .navbar-burger{color:#fff}@media screen and (min-width:1024px){.navbar.is-black .navbar-end .navbar-link,.navbar.is-black .navbar-end>.navbar-item,.navbar.is-black .navbar-start .navbar-link,.navbar.is-black .navbar-start>.navbar-item{color:#fff}.navbar.is-black .navbar-end .navbar-link.is-active,.navbar.is-black .navbar-end .navbar-link:focus,.navbar.is-black .navbar-end .navbar-link:hover,.navbar.is-black .navbar-end>a.navbar-item.is-active,.navbar.is-black .navbar-end>a.navbar-item:focus,.navbar.is-black .navbar-end>a.navbar-item:hover,.navbar.is-black .navbar-start .navbar-link.is-active,.navbar.is-black .navbar-start .navbar-link:focus,.navbar.is-black .navbar-start .navbar-link:hover,.navbar.is-black .navbar-start>a.navbar-item.is-active,.navbar.is-black .navbar-start>a.navbar-item:focus,.navbar.is-black .navbar-start>a.navbar-item:hover{background-color:#000;color:#fff}.navbar.is-black .navbar-end .navbar-link::after,.navbar.is-black .navbar-start .navbar-link::after{border-color:#fff}.navbar.is-black .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-black .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-black .navbar-item.has-dropdown:hover .navbar-link{background-color:#000;color:#fff}.navbar.is-black .navbar-dropdown a.navbar-item.is-active{background-color:#0a0a0a;color:#fff}}.navbar.is-light{background-color:#f5f5f5;color:rgba(0,0,0,.7)}.navbar.is-light .navbar-brand .navbar-link,.navbar.is-light .navbar-brand>.navbar-item{color:rgba(0,0,0,.7)}.navbar.is-light .navbar-brand .navbar-link.is-active,.navbar.is-light .navbar-brand .navbar-link:focus,.navbar.is-light .navbar-brand .navbar-link:hover,.navbar.is-light .navbar-brand>a.navbar-item.is-active,.navbar.is-light .navbar-brand>a.navbar-item:focus,.navbar.is-light .navbar-brand>a.navbar-item:hover{background-color:#e8e8e8;color:rgba(0,0,0,.7)}.navbar.is-light .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,.7)}.navbar.is-light .navbar-burger{color:rgba(0,0,0,.7)}@media screen and (min-width:1024px){.navbar.is-light .navbar-end .navbar-link,.navbar.is-light .navbar-end>.navbar-item,.navbar.is-light .navbar-start .navbar-link,.navbar.is-light .navbar-start>.navbar-item{color:rgba(0,0,0,.7)}.navbar.is-light .navbar-end .navbar-link.is-active,.navbar.is-light .navbar-end .navbar-link:focus,.navbar.is-light .navbar-end .navbar-link:hover,.navbar.is-light .navbar-end>a.navbar-item.is-active,.navbar.is-light .navbar-end>a.navbar-item:focus,.navbar.is-light .navbar-end>a.navbar-item:hover,.navbar.is-light .navbar-start .navbar-link.is-active,.navbar.is-light .navbar-start .navbar-link:focus,.navbar.is-light .navbar-start .navbar-link:hover,.navbar.is-light .navbar-start>a.navbar-item.is-active,.navbar.is-light .navbar-start>a.navbar-item:focus,.navbar.is-light .navbar-start>a.navbar-item:hover{background-color:#e8e8e8;color:rgba(0,0,0,.7)}.navbar.is-light .navbar-end .navbar-link::after,.navbar.is-light .navbar-start .navbar-link::after{border-color:rgba(0,0,0,.7)}.navbar.is-light .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-light .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-light .navbar-item.has-dropdown:hover .navbar-link{background-color:#e8e8e8;color:rgba(0,0,0,.7)}.navbar.is-light .navbar-dropdown a.navbar-item.is-active{background-color:#f5f5f5;color:rgba(0,0,0,.7)}}.navbar.is-dark{background-color:#363636;color:#fff}.navbar.is-dark .navbar-brand .navbar-link,.navbar.is-dark .navbar-brand>.navbar-item{color:#fff}.navbar.is-dark .navbar-brand .navbar-link.is-active,.navbar.is-dark .navbar-brand .navbar-link:focus,.navbar.is-dark .navbar-brand .navbar-link:hover,.navbar.is-dark .navbar-brand>a.navbar-item.is-active,.navbar.is-dark .navbar-brand>a.navbar-item:focus,.navbar.is-dark .navbar-brand>a.navbar-item:hover{background-color:#292929;color:#fff}.navbar.is-dark .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-dark .navbar-burger{color:#fff}@media screen and (min-width:1024px){.navbar.is-dark .navbar-end .navbar-link,.navbar.is-dark .navbar-end>.navbar-item,.navbar.is-dark .navbar-start .navbar-link,.navbar.is-dark .navbar-start>.navbar-item{color:#fff}.navbar.is-dark .navbar-end .navbar-link.is-active,.navbar.is-dark .navbar-end .navbar-link:focus,.navbar.is-dark .navbar-end .navbar-link:hover,.navbar.is-dark .navbar-end>a.navbar-item.is-active,.navbar.is-dark .navbar-end>a.navbar-item:focus,.navbar.is-dark .navbar-end>a.navbar-item:hover,.navbar.is-dark .navbar-start .navbar-link.is-active,.navbar.is-dark .navbar-start .navbar-link:focus,.navbar.is-dark .navbar-start .navbar-link:hover,.navbar.is-dark .navbar-start>a.navbar-item.is-active,.navbar.is-dark .navbar-start>a.navbar-item:focus,.navbar.is-dark .navbar-start>a.navbar-item:hover{background-color:#292929;color:#fff}.navbar.is-dark .navbar-end .navbar-link::after,.navbar.is-dark .navbar-start .navbar-link::after{border-color:#fff}.navbar.is-dark .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-dark .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-dark .navbar-item.has-dropdown:hover .navbar-link{background-color:#292929;color:#fff}.navbar.is-dark .navbar-dropdown a.navbar-item.is-active{background-color:#363636;color:#fff}}.navbar.is-primary{background-color:#00d1b2;color:#fff}.navbar.is-primary .navbar-brand .navbar-link,.navbar.is-primary .navbar-brand>.navbar-item{color:#fff}.navbar.is-primary .navbar-brand .navbar-link.is-active,.navbar.is-primary .navbar-brand .navbar-link:focus,.navbar.is-primary .navbar-brand .navbar-link:hover,.navbar.is-primary .navbar-brand>a.navbar-item.is-active,.navbar.is-primary .navbar-brand>a.navbar-item:focus,.navbar.is-primary .navbar-brand>a.navbar-item:hover{background-color:#00b89c;color:#fff}.navbar.is-primary .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-primary .navbar-burger{color:#fff}@media screen and (min-width:1024px){.navbar.is-primary .navbar-end .navbar-link,.navbar.is-primary .navbar-end>.navbar-item,.navbar.is-primary .navbar-start .navbar-link,.navbar.is-primary .navbar-start>.navbar-item{color:#fff}.navbar.is-primary .navbar-end .navbar-link.is-active,.navbar.is-primary .navbar-end .navbar-link:focus,.navbar.is-primary .navbar-end .navbar-link:hover,.navbar.is-primary .navbar-end>a.navbar-item.is-active,.navbar.is-primary .navbar-end>a.navbar-item:focus,.navbar.is-primary .navbar-end>a.navbar-item:hover,.navbar.is-primary .navbar-start .navbar-link.is-active,.navbar.is-primary .navbar-start .navbar-link:focus,.navbar.is-primary .navbar-start .navbar-link:hover,.navbar.is-primary .navbar-start>a.navbar-item.is-active,.navbar.is-primary .navbar-start>a.navbar-item:focus,.navbar.is-primary .navbar-start>a.navbar-item:hover{background-color:#00b89c;color:#fff}.navbar.is-primary .navbar-end .navbar-link::after,.navbar.is-primary .navbar-start .navbar-link::after{border-color:#fff}.navbar.is-primary .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-primary .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-primary .navbar-item.has-dropdown:hover .navbar-link{background-color:#00b89c;color:#fff}.navbar.is-primary .navbar-dropdown a.navbar-item.is-active{background-color:#00d1b2;color:#fff}}.navbar.is-link{background-color:#485fc7;color:#fff}.navbar.is-link .navbar-brand .navbar-link,.navbar.is-link .navbar-brand>.navbar-item{color:#fff}.navbar.is-link .navbar-brand .navbar-link.is-active,.navbar.is-link .navbar-brand .navbar-link:focus,.navbar.is-link .navbar-brand .navbar-link:hover,.navbar.is-link .navbar-brand>a.navbar-item.is-active,.navbar.is-link .navbar-brand>a.navbar-item:focus,.navbar.is-link .navbar-brand>a.navbar-item:hover{background-color:#3a51bb;color:#fff}.navbar.is-link .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-link .navbar-burger{color:#fff}@media screen and (min-width:1024px){.navbar.is-link .navbar-end .navbar-link,.navbar.is-link .navbar-end>.navbar-item,.navbar.is-link .navbar-start .navbar-link,.navbar.is-link .navbar-start>.navbar-item{color:#fff}.navbar.is-link .navbar-end .navbar-link.is-active,.navbar.is-link .navbar-end .navbar-link:focus,.navbar.is-link .navbar-end .navbar-link:hover,.navbar.is-link .navbar-end>a.navbar-item.is-active,.navbar.is-link .navbar-end>a.navbar-item:focus,.navbar.is-link .navbar-end>a.navbar-item:hover,.navbar.is-link .navbar-start .navbar-link.is-active,.navbar.is-link .navbar-start .navbar-link:focus,.navbar.is-link .navbar-start .navbar-link:hover,.navbar.is-link .navbar-start>a.navbar-item.is-active,.navbar.is-link .navbar-start>a.navbar-item:focus,.navbar.is-link .navbar-start>a.navbar-item:hover{background-color:#3a51bb;color:#fff}.navbar.is-link .navbar-end .navbar-link::after,.navbar.is-link .navbar-start .navbar-link::after{border-color:#fff}.navbar.is-link .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-link .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-link .navbar-item.has-dropdown:hover .navbar-link{background-color:#3a51bb;color:#fff}.navbar.is-link .navbar-dropdown a.navbar-item.is-active{background-color:#485fc7;color:#fff}}.navbar.is-info{background-color:#3e8ed0;color:#fff}.navbar.is-info .navbar-brand .navbar-link,.navbar.is-info .navbar-brand>.navbar-item{color:#fff}.navbar.is-info .navbar-brand .navbar-link.is-active,.navbar.is-info .navbar-brand .navbar-link:focus,.navbar.is-info .navbar-brand .navbar-link:hover,.navbar.is-info .navbar-brand>a.navbar-item.is-active,.navbar.is-info .navbar-brand>a.navbar-item:focus,.navbar.is-info .navbar-brand>a.navbar-item:hover{background-color:#3082c5;color:#fff}.navbar.is-info .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-info .navbar-burger{color:#fff}@media screen and (min-width:1024px){.navbar.is-info .navbar-end .navbar-link,.navbar.is-info .navbar-end>.navbar-item,.navbar.is-info .navbar-start .navbar-link,.navbar.is-info .navbar-start>.navbar-item{color:#fff}.navbar.is-info .navbar-end .navbar-link.is-active,.navbar.is-info .navbar-end .navbar-link:focus,.navbar.is-info .navbar-end .navbar-link:hover,.navbar.is-info .navbar-end>a.navbar-item.is-active,.navbar.is-info .navbar-end>a.navbar-item:focus,.navbar.is-info .navbar-end>a.navbar-item:hover,.navbar.is-info .navbar-start .navbar-link.is-active,.navbar.is-info .navbar-start .navbar-link:focus,.navbar.is-info .navbar-start .navbar-link:hover,.navbar.is-info .navbar-start>a.navbar-item.is-active,.navbar.is-info .navbar-start>a.navbar-item:focus,.navbar.is-info .navbar-start>a.navbar-item:hover{background-color:#3082c5;color:#fff}.navbar.is-info .navbar-end .navbar-link::after,.navbar.is-info .navbar-start .navbar-link::after{border-color:#fff}.navbar.is-info .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-info .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-info .navbar-item.has-dropdown:hover .navbar-link{background-color:#3082c5;color:#fff}.navbar.is-info .navbar-dropdown a.navbar-item.is-active{background-color:#3e8ed0;color:#fff}}.navbar.is-success{background-color:#48c78e;color:#fff}.navbar.is-success .navbar-brand .navbar-link,.navbar.is-success .navbar-brand>.navbar-item{color:#fff}.navbar.is-success .navbar-brand .navbar-link.is-active,.navbar.is-success .navbar-brand .navbar-link:focus,.navbar.is-success .navbar-brand .navbar-link:hover,.navbar.is-success .navbar-brand>a.navbar-item.is-active,.navbar.is-success .navbar-brand>a.navbar-item:focus,.navbar.is-success .navbar-brand>a.navbar-item:hover{background-color:#3abb81;color:#fff}.navbar.is-success .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-success .navbar-burger{color:#fff}@media screen and (min-width:1024px){.navbar.is-success .navbar-end .navbar-link,.navbar.is-success .navbar-end>.navbar-item,.navbar.is-success .navbar-start .navbar-link,.navbar.is-success .navbar-start>.navbar-item{color:#fff}.navbar.is-success .navbar-end .navbar-link.is-active,.navbar.is-success .navbar-end .navbar-link:focus,.navbar.is-success .navbar-end .navbar-link:hover,.navbar.is-success .navbar-end>a.navbar-item.is-active,.navbar.is-success .navbar-end>a.navbar-item:focus,.navbar.is-success .navbar-end>a.navbar-item:hover,.navbar.is-success .navbar-start .navbar-link.is-active,.navbar.is-success .navbar-start .navbar-link:focus,.navbar.is-success .navbar-start .navbar-link:hover,.navbar.is-success .navbar-start>a.navbar-item.is-active,.navbar.is-success .navbar-start>a.navbar-item:focus,.navbar.is-success .navbar-start>a.navbar-item:hover{background-color:#3abb81;color:#fff}.navbar.is-success .navbar-end .navbar-link::after,.navbar.is-success .navbar-start .navbar-link::after{border-color:#fff}.navbar.is-success .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-success .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-success .navbar-item.has-dropdown:hover .navbar-link{background-color:#3abb81;color:#fff}.navbar.is-success .navbar-dropdown a.navbar-item.is-active{background-color:#48c78e;color:#fff}}.navbar.is-warning{background-color:#ffe08a;color:rgba(0,0,0,.7)}.navbar.is-warning .navbar-brand .navbar-link,.navbar.is-warning .navbar-brand>.navbar-item{color:rgba(0,0,0,.7)}.navbar.is-warning .navbar-brand .navbar-link.is-active,.navbar.is-warning .navbar-brand .navbar-link:focus,.navbar.is-warning .navbar-brand .navbar-link:hover,.navbar.is-warning .navbar-brand>a.navbar-item.is-active,.navbar.is-warning .navbar-brand>a.navbar-item:focus,.navbar.is-warning .navbar-brand>a.navbar-item:hover{background-color:#ffd970;color:rgba(0,0,0,.7)}.navbar.is-warning .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,.7)}.navbar.is-warning .navbar-burger{color:rgba(0,0,0,.7)}@media screen and (min-width:1024px){.navbar.is-warning .navbar-end .navbar-link,.navbar.is-warning .navbar-end>.navbar-item,.navbar.is-warning .navbar-start .navbar-link,.navbar.is-warning .navbar-start>.navbar-item{color:rgba(0,0,0,.7)}.navbar.is-warning .navbar-end .navbar-link.is-active,.navbar.is-warning .navbar-end .navbar-link:focus,.navbar.is-warning .navbar-end .navbar-link:hover,.navbar.is-warning .navbar-end>a.navbar-item.is-active,.navbar.is-warning .navbar-end>a.navbar-item:focus,.navbar.is-warning .navbar-end>a.navbar-item:hover,.navbar.is-warning .navbar-start .navbar-link.is-active,.navbar.is-warning .navbar-start .navbar-link:focus,.navbar.is-warning .navbar-start .navbar-link:hover,.navbar.is-warning .navbar-start>a.navbar-item.is-active,.navbar.is-warning .navbar-start>a.navbar-item:focus,.navbar.is-warning .navbar-start>a.navbar-item:hover{background-color:#ffd970;color:rgba(0,0,0,.7)}.navbar.is-warning .navbar-end .navbar-link::after,.navbar.is-warning .navbar-start .navbar-link::after{border-color:rgba(0,0,0,.7)}.navbar.is-warning .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-warning .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-warning .navbar-item.has-dropdown:hover .navbar-link{background-color:#ffd970;color:rgba(0,0,0,.7)}.navbar.is-warning .navbar-dropdown a.navbar-item.is-active{background-color:#ffe08a;color:rgba(0,0,0,.7)}}.navbar.is-danger{background-color:#f14668;color:#fff}.navbar.is-danger .navbar-brand .navbar-link,.navbar.is-danger .navbar-brand>.navbar-item{color:#fff}.navbar.is-danger .navbar-brand .navbar-link.is-active,.navbar.is-danger .navbar-brand .navbar-link:focus,.navbar.is-danger .navbar-brand .navbar-link:hover,.navbar.is-danger .navbar-brand>a.navbar-item.is-active,.navbar.is-danger .navbar-brand>a.navbar-item:focus,.navbar.is-danger .navbar-brand>a.navbar-item:hover{background-color:#ef2e55;color:#fff}.navbar.is-danger .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-danger .navbar-burger{color:#fff}@media screen and (min-width:1024px){.navbar.is-danger .navbar-end .navbar-link,.navbar.is-danger .navbar-end>.navbar-item,.navbar.is-danger .navbar-start .navbar-link,.navbar.is-danger .navbar-start>.navbar-item{color:#fff}.navbar.is-danger .navbar-end .navbar-link.is-active,.navbar.is-danger .navbar-end .navbar-link:focus,.navbar.is-danger .navbar-end .navbar-link:hover,.navbar.is-danger .navbar-end>a.navbar-item.is-active,.navbar.is-danger .navbar-end>a.navbar-item:focus,.navbar.is-danger .navbar-end>a.navbar-item:hover,.navbar.is-danger .navbar-start .navbar-link.is-active,.navbar.is-danger .navbar-start .navbar-link:focus,.navbar.is-danger .navbar-start .navbar-link:hover,.navbar.is-danger .navbar-start>a.navbar-item.is-active,.navbar.is-danger .navbar-start>a.navbar-item:focus,.navbar.is-danger .navbar-start>a.navbar-item:hover{background-color:#ef2e55;color:#fff}.navbar.is-danger .navbar-end .navbar-link::after,.navbar.is-danger .navbar-start .navbar-link::after{border-color:#fff}.navbar.is-danger .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-danger .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-danger .navbar-item.has-dropdown:hover .navbar-link{background-color:#ef2e55;color:#fff}.navbar.is-danger .navbar-dropdown a.navbar-item.is-active{background-color:#f14668;color:#fff}}.navbar>.container{align-items:stretch;display:flex;min-height:3.25rem;width:100%}.navbar.has-shadow{box-shadow:0 2px 0 0 #f5f5f5}.navbar.is-fixed-bottom,.navbar.is-fixed-top{left:0;position:fixed;right:0;z-index:30}.navbar.is-fixed-bottom{bottom:0}.navbar.is-fixed-bottom.has-shadow{box-shadow:0 -2px 0 0 #f5f5f5}.navbar.is-fixed-top{top:0}body.has-navbar-fixed-top,html.has-navbar-fixed-top{padding-top:3.25rem}body.has-navbar-fixed-bottom,html.has-navbar-fixed-bottom{padding-bottom:3.25rem}.navbar-brand,.navbar-tabs{align-items:stretch;display:flex;flex-shrink:0;min-height:3.25rem}.navbar-brand a.navbar-item:focus,.navbar-brand a.navbar-item:hover{background-color:transparent}.navbar-tabs{-webkit-overflow-scrolling:touch;max-width:100vw;overflow-x:auto;overflow-y:hidden}.navbar-burger{color:#4a4a4a;-moz-appearance:none;-webkit-appearance:none;appearance:none;background:0 0;border:none;cursor:pointer;display:block;height:3.25rem;position:relative;width:3.25rem;margin-left:auto}.navbar-burger span{background-color:currentColor;display:block;height:1px;left:calc(50% - 8px);position:absolute;transform-origin:center;transition-duration:86ms;transition-property:background-color,opacity,transform;transition-timing-function:ease-out;width:16px}.navbar-burger span:first-child{top:calc(50% - 6px)}.navbar-burger span:nth-child(2){top:calc(50% - 1px)}.navbar-burger span:nth-child(3){top:calc(50% + 4px)}.navbar-burger:hover{background-color:rgba(0,0,0,.05)}.navbar-burger.is-active span:first-child{transform:translateY(5px) rotate(45deg)}.navbar-burger.is-active span:nth-child(2){opacity:0}.navbar-burger.is-active span:nth-child(3){transform:translateY(-5px) rotate(-45deg)}.navbar-menu{display:none}.navbar-item,.navbar-link{color:#4a4a4a;display:block;line-height:1.5;padding:.5rem .75rem;position:relative}.navbar-item .icon:only-child,.navbar-link .icon:only-child{margin-left:-.25rem;margin-right:-.25rem}.navbar-link,a.navbar-item{cursor:pointer}.navbar-link.is-active,.navbar-link:focus,.navbar-link:focus-within,.navbar-link:hover,a.navbar-item.is-active,a.navbar-item:focus,a.navbar-item:focus-within,a.navbar-item:hover{background-color:#fafafa;color:#485fc7}.navbar-item{flex-grow:0;flex-shrink:0}.navbar-item img{max-height:1.75rem}.navbar-item.has-dropdown{padding:0}.navbar-item.is-expanded{flex-grow:1;flex-shrink:1}.navbar-item.is-tab{border-bottom:1px solid transparent;min-height:3.25rem;padding-bottom:calc(.5rem - 1px)}.navbar-item.is-tab:focus,.navbar-item.is-tab:hover{background-color:transparent;border-bottom-color:#485fc7}.navbar-item.is-tab.is-active{background-color:transparent;border-bottom-color:#485fc7;border-bottom-style:solid;border-bottom-width:3px;color:#485fc7;padding-bottom:calc(.5rem - 3px)}.navbar-content{flex-grow:1;flex-shrink:1}.navbar-link:not(.is-arrowless){padding-right:2.5em}.navbar-link:not(.is-arrowless)::after{border-color:#485fc7;margin-top:-.375em;right:1.125em}.navbar-dropdown{font-size:.875rem;padding-bottom:.5rem;padding-top:.5rem}.navbar-dropdown .navbar-item{padding-left:1.5rem;padding-right:1.5rem}.navbar-divider{background-color:#f5f5f5;border:none;display:none;height:2px;margin:.5rem 0}@media screen and (max-width:1023px){.navbar>.container{display:block}.navbar-brand .navbar-item,.navbar-tabs .navbar-item{align-items:center;display:flex}.navbar-link::after{display:none}.navbar-menu{background-color:#fff;box-shadow:0 8px 16px rgba(10,10,10,.1);padding:.5rem 0}.navbar-menu.is-active{display:block}.navbar.is-fixed-bottom-touch,.navbar.is-fixed-top-touch{left:0;position:fixed;right:0;z-index:30}.navbar.is-fixed-bottom-touch{bottom:0}.navbar.is-fixed-bottom-touch.has-shadow{box-shadow:0 -2px 3px rgba(10,10,10,.1)}.navbar.is-fixed-top-touch{top:0}.navbar.is-fixed-top .navbar-menu,.navbar.is-fixed-top-touch .navbar-menu{-webkit-overflow-scrolling:touch;max-height:calc(100vh - 3.25rem);overflow:auto}body.has-navbar-fixed-top-touch,html.has-navbar-fixed-top-touch{padding-top:3.25rem}body.has-navbar-fixed-bottom-touch,html.has-navbar-fixed-bottom-touch{padding-bottom:3.25rem}}@media screen and (min-width:1024px){.navbar,.navbar-end,.navbar-menu,.navbar-start{align-items:stretch;display:flex}.navbar{min-height:3.25rem}.navbar.is-spaced{padding:1rem 2rem}.navbar.is-spaced .navbar-end,.navbar.is-spaced .navbar-start{align-items:center}.navbar.is-spaced .navbar-link,.navbar.is-spaced a.navbar-item{border-radius:4px}.navbar.is-transparent .navbar-link.is-active,.navbar.is-transparent .navbar-link:focus,.navbar.is-transparent .navbar-link:hover,.navbar.is-transparent a.navbar-item.is-active,.navbar.is-transparent a.navbar-item:focus,.navbar.is-transparent a.navbar-item:hover{background-color:transparent!important}.navbar.is-transparent .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:focus .navbar-link,.navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:focus-within .navbar-link,.navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:hover .navbar-link{background-color:transparent!important}.navbar.is-transparent .navbar-dropdown a.navbar-item:focus,.navbar.is-transparent .navbar-dropdown a.navbar-item:hover{background-color:#f5f5f5;color:#0a0a0a}.navbar.is-transparent .navbar-dropdown a.navbar-item.is-active{background-color:#f5f5f5;color:#485fc7}.navbar-burger{display:none}.navbar-item,.navbar-link{align-items:center;display:flex}.navbar-item.has-dropdown{align-items:stretch}.navbar-item.has-dropdown-up .navbar-link::after{transform:rotate(135deg) translate(.25em,-.25em)}.navbar-item.has-dropdown-up .navbar-dropdown{border-bottom:2px solid #dbdbdb;border-radius:6px 6px 0 0;border-top:none;bottom:100%;box-shadow:0 -8px 8px rgba(10,10,10,.1);top:auto}.navbar-item.is-active .navbar-dropdown,.navbar-item.is-hoverable:focus .navbar-dropdown,.navbar-item.is-hoverable:focus-within .navbar-dropdown,.navbar-item.is-hoverable:hover .navbar-dropdown{display:block}.navbar-item.is-active .navbar-dropdown.is-boxed,.navbar-item.is-hoverable:focus .navbar-dropdown.is-boxed,.navbar-item.is-hoverable:focus-within .navbar-dropdown.is-boxed,.navbar-item.is-hoverable:hover .navbar-dropdown.is-boxed,.navbar.is-spaced .navbar-item.is-active .navbar-dropdown,.navbar.is-spaced .navbar-item.is-hoverable:focus .navbar-dropdown,.navbar.is-spaced .navbar-item.is-hoverable:focus-within .navbar-dropdown,.navbar.is-spaced .navbar-item.is-hoverable:hover .navbar-dropdown{opacity:1;pointer-events:auto;transform:translateY(0)}.navbar-menu{flex-grow:1;flex-shrink:0}.navbar-start{justify-content:flex-start;margin-right:auto}.navbar-end{justify-content:flex-end;margin-left:auto}.navbar-dropdown{background-color:#fff;border-bottom-left-radius:6px;border-bottom-right-radius:6px;border-top:2px solid #dbdbdb;box-shadow:0 8px 8px rgba(10,10,10,.1);display:none;font-size:.875rem;left:0;min-width:100%;position:absolute;top:100%;z-index:20}.navbar-dropdown .navbar-item{padding:.375rem 1rem;white-space:nowrap}.navbar-dropdown a.navbar-item{padding-right:3rem}.navbar-dropdown a.navbar-item:focus,.navbar-dropdown a.navbar-item:hover{background-color:#f5f5f5;color:#0a0a0a}.navbar-dropdown a.navbar-item.is-active{background-color:#f5f5f5;color:#485fc7}.navbar-dropdown.is-boxed,.navbar.is-spaced .navbar-dropdown{border-radius:6px;border-top:none;box-shadow:0 8px 8px rgba(10,10,10,.1),0 0 0 1px rgba(10,10,10,.1);display:block;opacity:0;pointer-events:none;top:calc(100% + (-4px));transform:translateY(-5px);transition-duration:86ms;transition-property:opacity,transform}.navbar-dropdown.is-right{left:auto;right:0}.navbar-divider{display:block}.container>.navbar .navbar-brand,.navbar>.container .navbar-brand{margin-left:-.75rem}.container>.navbar .navbar-menu,.navbar>.container .navbar-menu{margin-right:-.75rem}.navbar.is-fixed-bottom-desktop,.navbar.is-fixed-top-desktop{left:0;position:fixed;right:0;z-index:30}.navbar.is-fixed-bottom-desktop{bottom:0}.navbar.is-fixed-bottom-desktop.has-shadow{box-shadow:0 -2px 3px rgba(10,10,10,.1)}.navbar.is-fixed-top-desktop{top:0}body.has-navbar-fixed-top-desktop,html.has-navbar-fixed-top-desktop{padding-top:3.25rem}body.has-navbar-fixed-bottom-desktop,html.has-navbar-fixed-bottom-desktop{padding-bottom:3.25rem}body.has-spaced-navbar-fixed-top,html.has-spaced-navbar-fixed-top{padding-top:5.25rem}body.has-spaced-navbar-fixed-bottom,html.has-spaced-navbar-fixed-bottom{padding-bottom:5.25rem}.navbar-link.is-active,a.navbar-item.is-active{color:#0a0a0a}.navbar-link.is-active:not(:focus):not(:hover),a.navbar-item.is-active:not(:focus):not(:hover){background-color:transparent}.navbar-item.has-dropdown.is-active .navbar-link,.navbar-item.has-dropdown:focus .navbar-link,.navbar-item.has-dropdown:hover .navbar-link{background-color:#fafafa}}.hero.is-fullheight-with-navbar{min-height:calc(100vh - 3.25rem)}.pagination{font-size:1rem;margin:-.25rem}.pagination.is-small{font-size:.75rem}.pagination.is-medium{font-size:1.25rem}.pagination.is-large{font-size:1.5rem}.pagination.is-rounded .pagination-next,.pagination.is-rounded .pagination-previous{padding-left:1em;padding-right:1em;border-radius:9999px}.pagination.is-rounded .pagination-link{border-radius:9999px}.pagination,.pagination-list{align-items:center;display:flex;justify-content:center;text-align:center}.pagination-ellipsis,.pagination-link,.pagination-next,.pagination-previous{font-size:1em;justify-content:center;margin:.25rem;padding-left:.5em;padding-right:.5em;text-align:center}.pagination-link,.pagination-next,.pagination-previous{border-color:#dbdbdb;color:#363636;min-width:2.5em}.pagination-link:hover,.pagination-next:hover,.pagination-previous:hover{border-color:#b5b5b5;color:#363636}.pagination-link:focus,.pagination-next:focus,.pagination-previous:focus{border-color:#485fc7}.pagination-link:active,.pagination-next:active,.pagination-previous:active{box-shadow:inset 0 1px 2px rgba(10,10,10,.2)}.pagination-link.is-disabled,.pagination-link[disabled],.pagination-next.is-disabled,.pagination-next[disabled],.pagination-previous.is-disabled,.pagination-previous[disabled]{background-color:#dbdbdb;border-color:#dbdbdb;box-shadow:none;color:#7a7a7a;opacity:.5}.pagination-next,.pagination-previous{padding-left:.75em;padding-right:.75em;white-space:nowrap}.pagination-link.is-current{background-color:#485fc7;border-color:#485fc7;color:#fff}.pagination-ellipsis{color:#b5b5b5;pointer-events:none}.pagination-list{flex-wrap:wrap}.pagination-list li{list-style:none}@media screen and (max-width:768px){.pagination{flex-wrap:wrap}.pagination-next,.pagination-previous{flex-grow:1;flex-shrink:1}.pagination-list li{flex-grow:1;flex-shrink:1}}@media screen and (min-width:769px),print{.pagination-list{flex-grow:1;flex-shrink:1;justify-content:flex-start;order:1}.pagination-ellipsis,.pagination-link,.pagination-next,.pagination-previous{margin-bottom:0;margin-top:0}.pagination-previous{order:2}.pagination-next{order:3}.pagination{justify-content:space-between;margin-bottom:0;margin-top:0}.pagination.is-centered .pagination-previous{order:1}.pagination.is-centered .pagination-list{justify-content:center;order:2}.pagination.is-centered .pagination-next{order:3}.pagination.is-right .pagination-previous{order:1}.pagination.is-right .pagination-next{order:2}.pagination.is-right .pagination-list{justify-content:flex-end;order:3}}.panel{border-radius:6px;box-shadow:0 .5em 1em -.125em rgba(10,10,10,.1),0 0 0 1px rgba(10,10,10,.02);font-size:1rem}.panel:not(:last-child){margin-bottom:1.5rem}.panel.is-white .panel-heading{background-color:#fff;color:#0a0a0a}.panel.is-white .panel-tabs a.is-active{border-bottom-color:#fff}.panel.is-white .panel-block.is-active .panel-icon{color:#fff}.panel.is-black .panel-heading{background-color:#0a0a0a;color:#fff}.panel.is-black .panel-tabs a.is-active{border-bottom-color:#0a0a0a}.panel.is-black .panel-block.is-active .panel-icon{color:#0a0a0a}.panel.is-light .panel-heading{background-color:#f5f5f5;color:rgba(0,0,0,.7)}.panel.is-light .panel-tabs a.is-active{border-bottom-color:#f5f5f5}.panel.is-light .panel-block.is-active .panel-icon{color:#f5f5f5}.panel.is-dark .panel-heading{background-color:#363636;color:#fff}.panel.is-dark .panel-tabs a.is-active{border-bottom-color:#363636}.panel.is-dark .panel-block.is-active .panel-icon{color:#363636}.panel.is-primary .panel-heading{background-color:#00d1b2;color:#fff}.panel.is-primary .panel-tabs a.is-active{border-bottom-color:#00d1b2}.panel.is-primary .panel-block.is-active .panel-icon{color:#00d1b2}.panel.is-link .panel-heading{background-color:#485fc7;color:#fff}.panel.is-link .panel-tabs a.is-active{border-bottom-color:#485fc7}.panel.is-link .panel-block.is-active .panel-icon{color:#485fc7}.panel.is-info .panel-heading{background-color:#3e8ed0;color:#fff}.panel.is-info .panel-tabs a.is-active{border-bottom-color:#3e8ed0}.panel.is-info .panel-block.is-active .panel-icon{color:#3e8ed0}.panel.is-success .panel-heading{background-color:#48c78e;color:#fff}.panel.is-success .panel-tabs a.is-active{border-bottom-color:#48c78e}.panel.is-success .panel-block.is-active .panel-icon{color:#48c78e}.panel.is-warning .panel-heading{background-color:#ffe08a;color:rgba(0,0,0,.7)}.panel.is-warning .panel-tabs a.is-active{border-bottom-color:#ffe08a}.panel.is-warning .panel-block.is-active .panel-icon{color:#ffe08a}.panel.is-danger .panel-heading{background-color:#f14668;color:#fff}.panel.is-danger .panel-tabs a.is-active{border-bottom-color:#f14668}.panel.is-danger .panel-block.is-active .panel-icon{color:#f14668}.panel-block:not(:last-child),.panel-tabs:not(:last-child){border-bottom:1px solid #ededed}.panel-heading{background-color:#ededed;border-radius:6px 6px 0 0;color:#363636;font-size:1.25em;font-weight:700;line-height:1.25;padding:.75em 1em}.panel-tabs{align-items:flex-end;display:flex;font-size:.875em;justify-content:center}.panel-tabs a{border-bottom:1px solid #dbdbdb;margin-bottom:-1px;padding:.5em}.panel-tabs a.is-active{border-bottom-color:#4a4a4a;color:#363636}.panel-list a{color:#4a4a4a}.panel-list a:hover{color:#485fc7}.panel-block{align-items:center;color:#363636;display:flex;justify-content:flex-start;padding:.5em .75em}.panel-block input[type=checkbox]{margin-right:.75em}.panel-block>.control{flex-grow:1;flex-shrink:1;width:100%}.panel-block.is-wrapped{flex-wrap:wrap}.panel-block.is-active{border-left-color:#485fc7;color:#363636}.panel-block.is-active .panel-icon{color:#485fc7}.panel-block:last-child{border-bottom-left-radius:6px;border-bottom-right-radius:6px}a.panel-block,label.panel-block{cursor:pointer}a.panel-block:hover,label.panel-block:hover{background-color:#f5f5f5}.panel-icon{display:inline-block;font-size:14px;height:1em;line-height:1em;text-align:center;vertical-align:top;width:1em;color:#7a7a7a;margin-right:.75em}.panel-icon .fa{font-size:inherit;line-height:inherit}.tabs{-webkit-overflow-scrolling:touch;align-items:stretch;display:flex;font-size:1rem;justify-content:space-between;overflow:hidden;overflow-x:auto;white-space:nowrap}.tabs a{align-items:center;border-bottom-color:#dbdbdb;border-bottom-style:solid;border-bottom-width:1px;color:#4a4a4a;display:flex;justify-content:center;margin-bottom:-1px;padding:.5em 1em;vertical-align:top}.tabs a:hover{border-bottom-color:#363636;color:#363636}.tabs li{display:block}.tabs li.is-active a{border-bottom-color:#485fc7;color:#485fc7}.tabs ul{align-items:center;border-bottom-color:#dbdbdb;border-bottom-style:solid;border-bottom-width:1px;display:flex;flex-grow:1;flex-shrink:0;justify-content:flex-start}.tabs ul.is-left{padding-right:.75em}.tabs ul.is-center{flex:none;justify-content:center;padding-left:.75em;padding-right:.75em}.tabs ul.is-right{justify-content:flex-end;padding-left:.75em}.tabs .icon:first-child{margin-right:.5em}.tabs .icon:last-child{margin-left:.5em}.tabs.is-centered ul{justify-content:center}.tabs.is-right ul{justify-content:flex-end}.tabs.is-boxed a{border:1px solid transparent;border-radius:4px 4px 0 0}.tabs.is-boxed a:hover{background-color:#f5f5f5;border-bottom-color:#dbdbdb}.tabs.is-boxed li.is-active a{background-color:#fff;border-color:#dbdbdb;border-bottom-color:transparent!important}.tabs.is-fullwidth li{flex-grow:1;flex-shrink:0}.tabs.is-toggle a{border-color:#dbdbdb;border-style:solid;border-width:1px;margin-bottom:0;position:relative}.tabs.is-toggle a:hover{background-color:#f5f5f5;border-color:#b5b5b5;z-index:2}.tabs.is-toggle li+li{margin-left:-1px}.tabs.is-toggle li:first-child a{border-top-left-radius:4px;border-bottom-left-radius:4px}.tabs.is-toggle li:last-child a{border-top-right-radius:4px;border-bottom-right-radius:4px}.tabs.is-toggle li.is-active a{background-color:#485fc7;border-color:#485fc7;color:#fff;z-index:1}.tabs.is-toggle ul{border-bottom:none}.tabs.is-toggle.is-toggle-rounded li:first-child a{border-bottom-left-radius:9999px;border-top-left-radius:9999px;padding-left:1.25em}.tabs.is-toggle.is-toggle-rounded li:last-child a{border-bottom-right-radius:9999px;border-top-right-radius:9999px;padding-right:1.25em}.tabs.is-small{font-size:.75rem}.tabs.is-medium{font-size:1.25rem}.tabs.is-large{font-size:1.5rem}.column{display:block;flex-basis:0;flex-grow:1;flex-shrink:1;padding:.75rem}.columns.is-mobile>.column.is-narrow{flex:none;width:unset}.columns.is-mobile>.column.is-full{flex:none;width:100%}.columns.is-mobile>.column.is-three-quarters{flex:none;width:75%}.columns.is-mobile>.column.is-two-thirds{flex:none;width:66.6666%}.columns.is-mobile>.column.is-half{flex:none;width:50%}.columns.is-mobile>.column.is-one-third{flex:none;width:33.3333%}.columns.is-mobile>.column.is-one-quarter{flex:none;width:25%}.columns.is-mobile>.column.is-one-fifth{flex:none;width:20%}.columns.is-mobile>.column.is-two-fifths{flex:none;width:40%}.columns.is-mobile>.column.is-three-fifths{flex:none;width:60%}.columns.is-mobile>.column.is-four-fifths{flex:none;width:80%}.columns.is-mobile>.column.is-offset-three-quarters{margin-left:75%}.columns.is-mobile>.column.is-offset-two-thirds{margin-left:66.6666%}.columns.is-mobile>.column.is-offset-half{margin-left:50%}.columns.is-mobile>.column.is-offset-one-third{margin-left:33.3333%}.columns.is-mobile>.column.is-offset-one-quarter{margin-left:25%}.columns.is-mobile>.column.is-offset-one-fifth{margin-left:20%}.columns.is-mobile>.column.is-offset-two-fifths{margin-left:40%}.columns.is-mobile>.column.is-offset-three-fifths{margin-left:60%}.columns.is-mobile>.column.is-offset-four-fifths{margin-left:80%}.columns.is-mobile>.column.is-0{flex:none;width:0%}.columns.is-mobile>.column.is-offset-0{margin-left:0}.columns.is-mobile>.column.is-1{flex:none;width:8.33333%}.columns.is-mobile>.column.is-offset-1{margin-left:8.33333%}.columns.is-mobile>.column.is-2{flex:none;width:16.66667%}.columns.is-mobile>.column.is-offset-2{margin-left:16.66667%}.columns.is-mobile>.column.is-3{flex:none;width:25%}.columns.is-mobile>.column.is-offset-3{margin-left:25%}.columns.is-mobile>.column.is-4{flex:none;width:33.33333%}.columns.is-mobile>.column.is-offset-4{margin-left:33.33333%}.columns.is-mobile>.column.is-5{flex:none;width:41.66667%}.columns.is-mobile>.column.is-offset-5{margin-left:41.66667%}.columns.is-mobile>.column.is-6{flex:none;width:50%}.columns.is-mobile>.column.is-offset-6{margin-left:50%}.columns.is-mobile>.column.is-7{flex:none;width:58.33333%}.columns.is-mobile>.column.is-offset-7{margin-left:58.33333%}.columns.is-mobile>.column.is-8{flex:none;width:66.66667%}.columns.is-mobile>.column.is-offset-8{margin-left:66.66667%}.columns.is-mobile>.column.is-9{flex:none;width:75%}.columns.is-mobile>.column.is-offset-9{margin-left:75%}.columns.is-mobile>.column.is-10{flex:none;width:83.33333%}.columns.is-mobile>.column.is-offset-10{margin-left:83.33333%}.columns.is-mobile>.column.is-11{flex:none;width:91.66667%}.columns.is-mobile>.column.is-offset-11{margin-left:91.66667%}.columns.is-mobile>.column.is-12{flex:none;width:100%}.columns.is-mobile>.column.is-offset-12{margin-left:100%}@media screen and (max-width:768px){.column.is-narrow-mobile{flex:none;width:unset}.column.is-full-mobile{flex:none;width:100%}.column.is-three-quarters-mobile{flex:none;width:75%}.column.is-two-thirds-mobile{flex:none;width:66.6666%}.column.is-half-mobile{flex:none;width:50%}.column.is-one-third-mobile{flex:none;width:33.3333%}.column.is-one-quarter-mobile{flex:none;width:25%}.column.is-one-fifth-mobile{flex:none;width:20%}.column.is-two-fifths-mobile{flex:none;width:40%}.column.is-three-fifths-mobile{flex:none;width:60%}.column.is-four-fifths-mobile{flex:none;width:80%}.column.is-offset-three-quarters-mobile{margin-left:75%}.column.is-offset-two-thirds-mobile{margin-left:66.6666%}.column.is-offset-half-mobile{margin-left:50%}.column.is-offset-one-third-mobile{margin-left:33.3333%}.column.is-offset-one-quarter-mobile{margin-left:25%}.column.is-offset-one-fifth-mobile{margin-left:20%}.column.is-offset-two-fifths-mobile{margin-left:40%}.column.is-offset-three-fifths-mobile{margin-left:60%}.column.is-offset-four-fifths-mobile{margin-left:80%}.column.is-0-mobile{flex:none;width:0%}.column.is-offset-0-mobile{margin-left:0}.column.is-1-mobile{flex:none;width:8.33333%}.column.is-offset-1-mobile{margin-left:8.33333%}.column.is-2-mobile{flex:none;width:16.66667%}.column.is-offset-2-mobile{margin-left:16.66667%}.column.is-3-mobile{flex:none;width:25%}.column.is-offset-3-mobile{margin-left:25%}.column.is-4-mobile{flex:none;width:33.33333%}.column.is-offset-4-mobile{margin-left:33.33333%}.column.is-5-mobile{flex:none;width:41.66667%}.column.is-offset-5-mobile{margin-left:41.66667%}.column.is-6-mobile{flex:none;width:50%}.column.is-offset-6-mobile{margin-left:50%}.column.is-7-mobile{flex:none;width:58.33333%}.column.is-offset-7-mobile{margin-left:58.33333%}.column.is-8-mobile{flex:none;width:66.66667%}.column.is-offset-8-mobile{margin-left:66.66667%}.column.is-9-mobile{flex:none;width:75%}.column.is-offset-9-mobile{margin-left:75%}.column.is-10-mobile{flex:none;width:83.33333%}.column.is-offset-10-mobile{margin-left:83.33333%}.column.is-11-mobile{flex:none;width:91.66667%}.column.is-offset-11-mobile{margin-left:91.66667%}.column.is-12-mobile{flex:none;width:100%}.column.is-offset-12-mobile{margin-left:100%}}@media screen and (min-width:769px),print{.column.is-narrow,.column.is-narrow-tablet{flex:none;width:unset}.column.is-full,.column.is-full-tablet{flex:none;width:100%}.column.is-three-quarters,.column.is-three-quarters-tablet{flex:none;width:75%}.column.is-two-thirds,.column.is-two-thirds-tablet{flex:none;width:66.6666%}.column.is-half,.column.is-half-tablet{flex:none;width:50%}.column.is-one-third,.column.is-one-third-tablet{flex:none;width:33.3333%}.column.is-one-quarter,.column.is-one-quarter-tablet{flex:none;width:25%}.column.is-one-fifth,.column.is-one-fifth-tablet{flex:none;width:20%}.column.is-two-fifths,.column.is-two-fifths-tablet{flex:none;width:40%}.column.is-three-fifths,.column.is-three-fifths-tablet{flex:none;width:60%}.column.is-four-fifths,.column.is-four-fifths-tablet{flex:none;width:80%}.column.is-offset-three-quarters,.column.is-offset-three-quarters-tablet{margin-left:75%}.column.is-offset-two-thirds,.column.is-offset-two-thirds-tablet{margin-left:66.6666%}.column.is-offset-half,.column.is-offset-half-tablet{margin-left:50%}.column.is-offset-one-third,.column.is-offset-one-third-tablet{margin-left:33.3333%}.column.is-offset-one-quarter,.column.is-offset-one-quarter-tablet{margin-left:25%}.column.is-offset-one-fifth,.column.is-offset-one-fifth-tablet{margin-left:20%}.column.is-offset-two-fifths,.column.is-offset-two-fifths-tablet{margin-left:40%}.column.is-offset-three-fifths,.column.is-offset-three-fifths-tablet{margin-left:60%}.column.is-offset-four-fifths,.column.is-offset-four-fifths-tablet{margin-left:80%}.column.is-0,.column.is-0-tablet{flex:none;width:0%}.column.is-offset-0,.column.is-offset-0-tablet{margin-left:0}.column.is-1,.column.is-1-tablet{flex:none;width:8.33333%}.column.is-offset-1,.column.is-offset-1-tablet{margin-left:8.33333%}.column.is-2,.column.is-2-tablet{flex:none;width:16.66667%}.column.is-offset-2,.column.is-offset-2-tablet{margin-left:16.66667%}.column.is-3,.column.is-3-tablet{flex:none;width:25%}.column.is-offset-3,.column.is-offset-3-tablet{margin-left:25%}.column.is-4,.column.is-4-tablet{flex:none;width:33.33333%}.column.is-offset-4,.column.is-offset-4-tablet{margin-left:33.33333%}.column.is-5,.column.is-5-tablet{flex:none;width:41.66667%}.column.is-offset-5,.column.is-offset-5-tablet{margin-left:41.66667%}.column.is-6,.column.is-6-tablet{flex:none;width:50%}.column.is-offset-6,.column.is-offset-6-tablet{margin-left:50%}.column.is-7,.column.is-7-tablet{flex:none;width:58.33333%}.column.is-offset-7,.column.is-offset-7-tablet{margin-left:58.33333%}.column.is-8,.column.is-8-tablet{flex:none;width:66.66667%}.column.is-offset-8,.column.is-offset-8-tablet{margin-left:66.66667%}.column.is-9,.column.is-9-tablet{flex:none;width:75%}.column.is-offset-9,.column.is-offset-9-tablet{margin-left:75%}.column.is-10,.column.is-10-tablet{flex:none;width:83.33333%}.column.is-offset-10,.column.is-offset-10-tablet{margin-left:83.33333%}.column.is-11,.column.is-11-tablet{flex:none;width:91.66667%}.column.is-offset-11,.column.is-offset-11-tablet{margin-left:91.66667%}.column.is-12,.column.is-12-tablet{flex:none;width:100%}.column.is-offset-12,.column.is-offset-12-tablet{margin-left:100%}}@media screen and (max-width:1023px){.column.is-narrow-touch{flex:none;width:unset}.column.is-full-touch{flex:none;width:100%}.column.is-three-quarters-touch{flex:none;width:75%}.column.is-two-thirds-touch{flex:none;width:66.6666%}.column.is-half-touch{flex:none;width:50%}.column.is-one-third-touch{flex:none;width:33.3333%}.column.is-one-quarter-touch{flex:none;width:25%}.column.is-one-fifth-touch{flex:none;width:20%}.column.is-two-fifths-touch{flex:none;width:40%}.column.is-three-fifths-touch{flex:none;width:60%}.column.is-four-fifths-touch{flex:none;width:80%}.column.is-offset-three-quarters-touch{margin-left:75%}.column.is-offset-two-thirds-touch{margin-left:66.6666%}.column.is-offset-half-touch{margin-left:50%}.column.is-offset-one-third-touch{margin-left:33.3333%}.column.is-offset-one-quarter-touch{margin-left:25%}.column.is-offset-one-fifth-touch{margin-left:20%}.column.is-offset-two-fifths-touch{margin-left:40%}.column.is-offset-three-fifths-touch{margin-left:60%}.column.is-offset-four-fifths-touch{margin-left:80%}.column.is-0-touch{flex:none;width:0%}.column.is-offset-0-touch{margin-left:0}.column.is-1-touch{flex:none;width:8.33333%}.column.is-offset-1-touch{margin-left:8.33333%}.column.is-2-touch{flex:none;width:16.66667%}.column.is-offset-2-touch{margin-left:16.66667%}.column.is-3-touch{flex:none;width:25%}.column.is-offset-3-touch{margin-left:25%}.column.is-4-touch{flex:none;width:33.33333%}.column.is-offset-4-touch{margin-left:33.33333%}.column.is-5-touch{flex:none;width:41.66667%}.column.is-offset-5-touch{margin-left:41.66667%}.column.is-6-touch{flex:none;width:50%}.column.is-offset-6-touch{margin-left:50%}.column.is-7-touch{flex:none;width:58.33333%}.column.is-offset-7-touch{margin-left:58.33333%}.column.is-8-touch{flex:none;width:66.66667%}.column.is-offset-8-touch{margin-left:66.66667%}.column.is-9-touch{flex:none;width:75%}.column.is-offset-9-touch{margin-left:75%}.column.is-10-touch{flex:none;width:83.33333%}.column.is-offset-10-touch{margin-left:83.33333%}.column.is-11-touch{flex:none;width:91.66667%}.column.is-offset-11-touch{margin-left:91.66667%}.column.is-12-touch{flex:none;width:100%}.column.is-offset-12-touch{margin-left:100%}}@media screen and (min-width:1024px){.column.is-narrow-desktop{flex:none;width:unset}.column.is-full-desktop{flex:none;width:100%}.column.is-three-quarters-desktop{flex:none;width:75%}.column.is-two-thirds-desktop{flex:none;width:66.6666%}.column.is-half-desktop{flex:none;width:50%}.column.is-one-third-desktop{flex:none;width:33.3333%}.column.is-one-quarter-desktop{flex:none;width:25%}.column.is-one-fifth-desktop{flex:none;width:20%}.column.is-two-fifths-desktop{flex:none;width:40%}.column.is-three-fifths-desktop{flex:none;width:60%}.column.is-four-fifths-desktop{flex:none;width:80%}.column.is-offset-three-quarters-desktop{margin-left:75%}.column.is-offset-two-thirds-desktop{margin-left:66.6666%}.column.is-offset-half-desktop{margin-left:50%}.column.is-offset-one-third-desktop{margin-left:33.3333%}.column.is-offset-one-quarter-desktop{margin-left:25%}.column.is-offset-one-fifth-desktop{margin-left:20%}.column.is-offset-two-fifths-desktop{margin-left:40%}.column.is-offset-three-fifths-desktop{margin-left:60%}.column.is-offset-four-fifths-desktop{margin-left:80%}.column.is-0-desktop{flex:none;width:0%}.column.is-offset-0-desktop{margin-left:0}.column.is-1-desktop{flex:none;width:8.33333%}.column.is-offset-1-desktop{margin-left:8.33333%}.column.is-2-desktop{flex:none;width:16.66667%}.column.is-offset-2-desktop{margin-left:16.66667%}.column.is-3-desktop{flex:none;width:25%}.column.is-offset-3-desktop{margin-left:25%}.column.is-4-desktop{flex:none;width:33.33333%}.column.is-offset-4-desktop{margin-left:33.33333%}.column.is-5-desktop{flex:none;width:41.66667%}.column.is-offset-5-desktop{margin-left:41.66667%}.column.is-6-desktop{flex:none;width:50%}.column.is-offset-6-desktop{margin-left:50%}.column.is-7-desktop{flex:none;width:58.33333%}.column.is-offset-7-desktop{margin-left:58.33333%}.column.is-8-desktop{flex:none;width:66.66667%}.column.is-offset-8-desktop{margin-left:66.66667%}.column.is-9-desktop{flex:none;width:75%}.column.is-offset-9-desktop{margin-left:75%}.column.is-10-desktop{flex:none;width:83.33333%}.column.is-offset-10-desktop{margin-left:83.33333%}.column.is-11-desktop{flex:none;width:91.66667%}.column.is-offset-11-desktop{margin-left:91.66667%}.column.is-12-desktop{flex:none;width:100%}.column.is-offset-12-desktop{margin-left:100%}}@media screen and (min-width:1216px){.column.is-narrow-widescreen{flex:none;width:unset}.column.is-full-widescreen{flex:none;width:100%}.column.is-three-quarters-widescreen{flex:none;width:75%}.column.is-two-thirds-widescreen{flex:none;width:66.6666%}.column.is-half-widescreen{flex:none;width:50%}.column.is-one-third-widescreen{flex:none;width:33.3333%}.column.is-one-quarter-widescreen{flex:none;width:25%}.column.is-one-fifth-widescreen{flex:none;width:20%}.column.is-two-fifths-widescreen{flex:none;width:40%}.column.is-three-fifths-widescreen{flex:none;width:60%}.column.is-four-fifths-widescreen{flex:none;width:80%}.column.is-offset-three-quarters-widescreen{margin-left:75%}.column.is-offset-two-thirds-widescreen{margin-left:66.6666%}.column.is-offset-half-widescreen{margin-left:50%}.column.is-offset-one-third-widescreen{margin-left:33.3333%}.column.is-offset-one-quarter-widescreen{margin-left:25%}.column.is-offset-one-fifth-widescreen{margin-left:20%}.column.is-offset-two-fifths-widescreen{margin-left:40%}.column.is-offset-three-fifths-widescreen{margin-left:60%}.column.is-offset-four-fifths-widescreen{margin-left:80%}.column.is-0-widescreen{flex:none;width:0%}.column.is-offset-0-widescreen{margin-left:0}.column.is-1-widescreen{flex:none;width:8.33333%}.column.is-offset-1-widescreen{margin-left:8.33333%}.column.is-2-widescreen{flex:none;width:16.66667%}.column.is-offset-2-widescreen{margin-left:16.66667%}.column.is-3-widescreen{flex:none;width:25%}.column.is-offset-3-widescreen{margin-left:25%}.column.is-4-widescreen{flex:none;width:33.33333%}.column.is-offset-4-widescreen{margin-left:33.33333%}.column.is-5-widescreen{flex:none;width:41.66667%}.column.is-offset-5-widescreen{margin-left:41.66667%}.column.is-6-widescreen{flex:none;width:50%}.column.is-offset-6-widescreen{margin-left:50%}.column.is-7-widescreen{flex:none;width:58.33333%}.column.is-offset-7-widescreen{margin-left:58.33333%}.column.is-8-widescreen{flex:none;width:66.66667%}.column.is-offset-8-widescreen{margin-left:66.66667%}.column.is-9-widescreen{flex:none;width:75%}.column.is-offset-9-widescreen{margin-left:75%}.column.is-10-widescreen{flex:none;width:83.33333%}.column.is-offset-10-widescreen{margin-left:83.33333%}.column.is-11-widescreen{flex:none;width:91.66667%}.column.is-offset-11-widescreen{margin-left:91.66667%}.column.is-12-widescreen{flex:none;width:100%}.column.is-offset-12-widescreen{margin-left:100%}}@media screen and (min-width:1408px){.column.is-narrow-fullhd{flex:none;width:unset}.column.is-full-fullhd{flex:none;width:100%}.column.is-three-quarters-fullhd{flex:none;width:75%}.column.is-two-thirds-fullhd{flex:none;width:66.6666%}.column.is-half-fullhd{flex:none;width:50%}.column.is-one-third-fullhd{flex:none;width:33.3333%}.column.is-one-quarter-fullhd{flex:none;width:25%}.column.is-one-fifth-fullhd{flex:none;width:20%}.column.is-two-fifths-fullhd{flex:none;width:40%}.column.is-three-fifths-fullhd{flex:none;width:60%}.column.is-four-fifths-fullhd{flex:none;width:80%}.column.is-offset-three-quarters-fullhd{margin-left:75%}.column.is-offset-two-thirds-fullhd{margin-left:66.6666%}.column.is-offset-half-fullhd{margin-left:50%}.column.is-offset-one-third-fullhd{margin-left:33.3333%}.column.is-offset-one-quarter-fullhd{margin-left:25%}.column.is-offset-one-fifth-fullhd{margin-left:20%}.column.is-offset-two-fifths-fullhd{margin-left:40%}.column.is-offset-three-fifths-fullhd{margin-left:60%}.column.is-offset-four-fifths-fullhd{margin-left:80%}.column.is-0-fullhd{flex:none;width:0%}.column.is-offset-0-fullhd{margin-left:0}.column.is-1-fullhd{flex:none;width:8.33333%}.column.is-offset-1-fullhd{margin-left:8.33333%}.column.is-2-fullhd{flex:none;width:16.66667%}.column.is-offset-2-fullhd{margin-left:16.66667%}.column.is-3-fullhd{flex:none;width:25%}.column.is-offset-3-fullhd{margin-left:25%}.column.is-4-fullhd{flex:none;width:33.33333%}.column.is-offset-4-fullhd{margin-left:33.33333%}.column.is-5-fullhd{flex:none;width:41.66667%}.column.is-offset-5-fullhd{margin-left:41.66667%}.column.is-6-fullhd{flex:none;width:50%}.column.is-offset-6-fullhd{margin-left:50%}.column.is-7-fullhd{flex:none;width:58.33333%}.column.is-offset-7-fullhd{margin-left:58.33333%}.column.is-8-fullhd{flex:none;width:66.66667%}.column.is-offset-8-fullhd{margin-left:66.66667%}.column.is-9-fullhd{flex:none;width:75%}.column.is-offset-9-fullhd{margin-left:75%}.column.is-10-fullhd{flex:none;width:83.33333%}.column.is-offset-10-fullhd{margin-left:83.33333%}.column.is-11-fullhd{flex:none;width:91.66667%}.column.is-offset-11-fullhd{margin-left:91.66667%}.column.is-12-fullhd{flex:none;width:100%}.column.is-offset-12-fullhd{margin-left:100%}}.columns{margin-left:-.75rem;margin-right:-.75rem;margin-top:-.75rem}.columns:last-child{margin-bottom:-.75rem}.columns:not(:last-child){margin-bottom:calc(1.5rem - .75rem)}.columns.is-centered{justify-content:center}.columns.is-gapless{margin-left:0;margin-right:0;margin-top:0}.columns.is-gapless>.column{margin:0;padding:0!important}.columns.is-gapless:not(:last-child){margin-bottom:1.5rem}.columns.is-gapless:last-child{margin-bottom:0}.columns.is-mobile{display:flex}.columns.is-multiline{flex-wrap:wrap}.columns.is-vcentered{align-items:center}@media screen and (min-width:769px),print{.columns:not(.is-desktop){display:flex}}@media screen and (min-width:1024px){.columns.is-desktop{display:flex}}.columns.is-variable{--columnGap:0.75rem;margin-left:calc(-1 * var(--columnGap));margin-right:calc(-1 * var(--columnGap))}.columns.is-variable>.column{padding-left:var(--columnGap);padding-right:var(--columnGap)}.columns.is-variable.is-0{--columnGap:0rem}@media screen and (max-width:768px){.columns.is-variable.is-0-mobile{--columnGap:0rem}}@media screen and (min-width:769px),print{.columns.is-variable.is-0-tablet{--columnGap:0rem}}@media screen and (min-width:769px) and (max-width:1023px){.columns.is-variable.is-0-tablet-only{--columnGap:0rem}}@media screen and (max-width:1023px){.columns.is-variable.is-0-touch{--columnGap:0rem}}@media screen and (min-width:1024px){.columns.is-variable.is-0-desktop{--columnGap:0rem}}@media screen and (min-width:1024px) and (max-width:1215px){.columns.is-variable.is-0-desktop-only{--columnGap:0rem}}@media screen and (min-width:1216px){.columns.is-variable.is-0-widescreen{--columnGap:0rem}}@media screen and (min-width:1216px) and (max-width:1407px){.columns.is-variable.is-0-widescreen-only{--columnGap:0rem}}@media screen and (min-width:1408px){.columns.is-variable.is-0-fullhd{--columnGap:0rem}}.columns.is-variable.is-1{--columnGap:0.25rem}@media screen and (max-width:768px){.columns.is-variable.is-1-mobile{--columnGap:0.25rem}}@media screen and (min-width:769px),print{.columns.is-variable.is-1-tablet{--columnGap:0.25rem}}@media screen and (min-width:769px) and (max-width:1023px){.columns.is-variable.is-1-tablet-only{--columnGap:0.25rem}}@media screen and (max-width:1023px){.columns.is-variable.is-1-touch{--columnGap:0.25rem}}@media screen and (min-width:1024px){.columns.is-variable.is-1-desktop{--columnGap:0.25rem}}@media screen and (min-width:1024px) and (max-width:1215px){.columns.is-variable.is-1-desktop-only{--columnGap:0.25rem}}@media screen and (min-width:1216px){.columns.is-variable.is-1-widescreen{--columnGap:0.25rem}}@media screen and (min-width:1216px) and (max-width:1407px){.columns.is-variable.is-1-widescreen-only{--columnGap:0.25rem}}@media screen and (min-width:1408px){.columns.is-variable.is-1-fullhd{--columnGap:0.25rem}}.columns.is-variable.is-2{--columnGap:0.5rem}@media screen and (max-width:768px){.columns.is-variable.is-2-mobile{--columnGap:0.5rem}}@media screen and (min-width:769px),print{.columns.is-variable.is-2-tablet{--columnGap:0.5rem}}@media screen and (min-width:769px) and (max-width:1023px){.columns.is-variable.is-2-tablet-only{--columnGap:0.5rem}}@media screen and (max-width:1023px){.columns.is-variable.is-2-touch{--columnGap:0.5rem}}@media screen and (min-width:1024px){.columns.is-variable.is-2-desktop{--columnGap:0.5rem}}@media screen and (min-width:1024px) and (max-width:1215px){.columns.is-variable.is-2-desktop-only{--columnGap:0.5rem}}@media screen and (min-width:1216px){.columns.is-variable.is-2-widescreen{--columnGap:0.5rem}}@media screen and (min-width:1216px) and (max-width:1407px){.columns.is-variable.is-2-widescreen-only{--columnGap:0.5rem}}@media screen and (min-width:1408px){.columns.is-variable.is-2-fullhd{--columnGap:0.5rem}}.columns.is-variable.is-3{--columnGap:0.75rem}@media screen and (max-width:768px){.columns.is-variable.is-3-mobile{--columnGap:0.75rem}}@media screen and (min-width:769px),print{.columns.is-variable.is-3-tablet{--columnGap:0.75rem}}@media screen and (min-width:769px) and (max-width:1023px){.columns.is-variable.is-3-tablet-only{--columnGap:0.75rem}}@media screen and (max-width:1023px){.columns.is-variable.is-3-touch{--columnGap:0.75rem}}@media screen and (min-width:1024px){.columns.is-variable.is-3-desktop{--columnGap:0.75rem}}@media screen and (min-width:1024px) and (max-width:1215px){.columns.is-variable.is-3-desktop-only{--columnGap:0.75rem}}@media screen and (min-width:1216px){.columns.is-variable.is-3-widescreen{--columnGap:0.75rem}}@media screen and (min-width:1216px) and (max-width:1407px){.columns.is-variable.is-3-widescreen-only{--columnGap:0.75rem}}@media screen and (min-width:1408px){.columns.is-variable.is-3-fullhd{--columnGap:0.75rem}}.columns.is-variable.is-4{--columnGap:1rem}@media screen and (max-width:768px){.columns.is-variable.is-4-mobile{--columnGap:1rem}}@media screen and (min-width:769px),print{.columns.is-variable.is-4-tablet{--columnGap:1rem}}@media screen and (min-width:769px) and (max-width:1023px){.columns.is-variable.is-4-tablet-only{--columnGap:1rem}}@media screen and (max-width:1023px){.columns.is-variable.is-4-touch{--columnGap:1rem}}@media screen and (min-width:1024px){.columns.is-variable.is-4-desktop{--columnGap:1rem}}@media screen and (min-width:1024px) and (max-width:1215px){.columns.is-variable.is-4-desktop-only{--columnGap:1rem}}@media screen and (min-width:1216px){.columns.is-variable.is-4-widescreen{--columnGap:1rem}}@media screen and (min-width:1216px) and (max-width:1407px){.columns.is-variable.is-4-widescreen-only{--columnGap:1rem}}@media screen and (min-width:1408px){.columns.is-variable.is-4-fullhd{--columnGap:1rem}}.columns.is-variable.is-5{--columnGap:1.25rem}@media screen and (max-width:768px){.columns.is-variable.is-5-mobile{--columnGap:1.25rem}}@media screen and (min-width:769px),print{.columns.is-variable.is-5-tablet{--columnGap:1.25rem}}@media screen and (min-width:769px) and (max-width:1023px){.columns.is-variable.is-5-tablet-only{--columnGap:1.25rem}}@media screen and (max-width:1023px){.columns.is-variable.is-5-touch{--columnGap:1.25rem}}@media screen and (min-width:1024px){.columns.is-variable.is-5-desktop{--columnGap:1.25rem}}@media screen and (min-width:1024px) and (max-width:1215px){.columns.is-variable.is-5-desktop-only{--columnGap:1.25rem}}@media screen and (min-width:1216px){.columns.is-variable.is-5-widescreen{--columnGap:1.25rem}}@media screen and (min-width:1216px) and (max-width:1407px){.columns.is-variable.is-5-widescreen-only{--columnGap:1.25rem}}@media screen and (min-width:1408px){.columns.is-variable.is-5-fullhd{--columnGap:1.25rem}}.columns.is-variable.is-6{--columnGap:1.5rem}@media screen and (max-width:768px){.columns.is-variable.is-6-mobile{--columnGap:1.5rem}}@media screen and (min-width:769px),print{.columns.is-variable.is-6-tablet{--columnGap:1.5rem}}@media screen and (min-width:769px) and (max-width:1023px){.columns.is-variable.is-6-tablet-only{--columnGap:1.5rem}}@media screen and (max-width:1023px){.columns.is-variable.is-6-touch{--columnGap:1.5rem}}@media screen and (min-width:1024px){.columns.is-variable.is-6-desktop{--columnGap:1.5rem}}@media screen and (min-width:1024px) and (max-width:1215px){.columns.is-variable.is-6-desktop-only{--columnGap:1.5rem}}@media screen and (min-width:1216px){.columns.is-variable.is-6-widescreen{--columnGap:1.5rem}}@media screen and (min-width:1216px) and (max-width:1407px){.columns.is-variable.is-6-widescreen-only{--columnGap:1.5rem}}@media screen and (min-width:1408px){.columns.is-variable.is-6-fullhd{--columnGap:1.5rem}}.columns.is-variable.is-7{--columnGap:1.75rem}@media screen and (max-width:768px){.columns.is-variable.is-7-mobile{--columnGap:1.75rem}}@media screen and (min-width:769px),print{.columns.is-variable.is-7-tablet{--columnGap:1.75rem}}@media screen and (min-width:769px) and (max-width:1023px){.columns.is-variable.is-7-tablet-only{--columnGap:1.75rem}}@media screen and (max-width:1023px){.columns.is-variable.is-7-touch{--columnGap:1.75rem}}@media screen and (min-width:1024px){.columns.is-variable.is-7-desktop{--columnGap:1.75rem}}@media screen and (min-width:1024px) and (max-width:1215px){.columns.is-variable.is-7-desktop-only{--columnGap:1.75rem}}@media screen and (min-width:1216px){.columns.is-variable.is-7-widescreen{--columnGap:1.75rem}}@media screen and (min-width:1216px) and (max-width:1407px){.columns.is-variable.is-7-widescreen-only{--columnGap:1.75rem}}@media screen and (min-width:1408px){.columns.is-variable.is-7-fullhd{--columnGap:1.75rem}}.columns.is-variable.is-8{--columnGap:2rem}@media screen and (max-width:768px){.columns.is-variable.is-8-mobile{--columnGap:2rem}}@media screen and (min-width:769px),print{.columns.is-variable.is-8-tablet{--columnGap:2rem}}@media screen and (min-width:769px) and (max-width:1023px){.columns.is-variable.is-8-tablet-only{--columnGap:2rem}}@media screen and (max-width:1023px){.columns.is-variable.is-8-touch{--columnGap:2rem}}@media screen and (min-width:1024px){.columns.is-variable.is-8-desktop{--columnGap:2rem}}@media screen and (min-width:1024px) and (max-width:1215px){.columns.is-variable.is-8-desktop-only{--columnGap:2rem}}@media screen and (min-width:1216px){.columns.is-variable.is-8-widescreen{--columnGap:2rem}}@media screen and (min-width:1216px) and (max-width:1407px){.columns.is-variable.is-8-widescreen-only{--columnGap:2rem}}@media screen and (min-width:1408px){.columns.is-variable.is-8-fullhd{--columnGap:2rem}}.tile{align-items:stretch;display:block;flex-basis:0;flex-grow:1;flex-shrink:1;min-height:-webkit-min-content;min-height:-moz-min-content;min-height:min-content}.tile.is-ancestor{margin-left:-.75rem;margin-right:-.75rem;margin-top:-.75rem}.tile.is-ancestor:last-child{margin-bottom:-.75rem}.tile.is-ancestor:not(:last-child){margin-bottom:.75rem}.tile.is-child{margin:0!important}.tile.is-parent{padding:.75rem}.tile.is-vertical{flex-direction:column}.tile.is-vertical>.tile.is-child:not(:last-child){margin-bottom:1.5rem!important}@media screen and (min-width:769px),print{.tile:not(.is-child){display:flex}.tile.is-1{flex:none;width:8.33333%}.tile.is-2{flex:none;width:16.66667%}.tile.is-3{flex:none;width:25%}.tile.is-4{flex:none;width:33.33333%}.tile.is-5{flex:none;width:41.66667%}.tile.is-6{flex:none;width:50%}.tile.is-7{flex:none;width:58.33333%}.tile.is-8{flex:none;width:66.66667%}.tile.is-9{flex:none;width:75%}.tile.is-10{flex:none;width:83.33333%}.tile.is-11{flex:none;width:91.66667%}.tile.is-12{flex:none;width:100%}}.has-text-white{color:#fff!important}a.has-text-white:focus,a.has-text-white:hover{color:#e6e6e6!important}.has-background-white{background-color:#fff!important}.has-text-black{color:#0a0a0a!important}a.has-text-black:focus,a.has-text-black:hover{color:#000!important}.has-background-black{background-color:#0a0a0a!important}.has-text-light{color:#f5f5f5!important}a.has-text-light:focus,a.has-text-light:hover{color:#dbdbdb!important}.has-background-light{background-color:#f5f5f5!important}.has-text-dark{color:#363636!important}a.has-text-dark:focus,a.has-text-dark:hover{color:#1c1c1c!important}.has-background-dark{background-color:#363636!important}.has-text-primary{color:#00d1b2!important}a.has-text-primary:focus,a.has-text-primary:hover{color:#009e86!important}.has-background-primary{background-color:#00d1b2!important}.has-text-primary-light{color:#ebfffc!important}a.has-text-primary-light:focus,a.has-text-primary-light:hover{color:#b8fff4!important}.has-background-primary-light{background-color:#ebfffc!important}.has-text-primary-dark{color:#00947e!important}a.has-text-primary-dark:focus,a.has-text-primary-dark:hover{color:#00c7a9!important}.has-background-primary-dark{background-color:#00947e!important}.has-text-link{color:#485fc7!important}a.has-text-link:focus,a.has-text-link:hover{color:#3449a8!important}.has-background-link{background-color:#485fc7!important}.has-text-link-light{color:#eff1fa!important}a.has-text-link-light:focus,a.has-text-link-light:hover{color:#c8cfee!important}.has-background-link-light{background-color:#eff1fa!important}.has-text-link-dark{color:#3850b7!important}a.has-text-link-dark:focus,a.has-text-link-dark:hover{color:#576dcb!important}.has-background-link-dark{background-color:#3850b7!important}.has-text-info{color:#3e8ed0!important}a.has-text-info:focus,a.has-text-info:hover{color:#2b74b1!important}.has-background-info{background-color:#3e8ed0!important}.has-text-info-light{color:#eff5fb!important}a.has-text-info-light:focus,a.has-text-info-light:hover{color:#c6ddf1!important}.has-background-info-light{background-color:#eff5fb!important}.has-text-info-dark{color:#296fa8!important}a.has-text-info-dark:focus,a.has-text-info-dark:hover{color:#368ace!important}.has-background-info-dark{background-color:#296fa8!important}.has-text-success{color:#48c78e!important}a.has-text-success:focus,a.has-text-success:hover{color:#34a873!important}.has-background-success{background-color:#48c78e!important}.has-text-success-light{color:#effaf5!important}a.has-text-success-light:focus,a.has-text-success-light:hover{color:#c8eedd!important}.has-background-success-light{background-color:#effaf5!important}.has-text-success-dark{color:#257953!important}a.has-text-success-dark:focus,a.has-text-success-dark:hover{color:#31a06e!important}.has-background-success-dark{background-color:#257953!important}.has-text-warning{color:#ffe08a!important}a.has-text-warning:focus,a.has-text-warning:hover{color:#ffd257!important}.has-background-warning{background-color:#ffe08a!important}.has-text-warning-light{color:#fffaeb!important}a.has-text-warning-light:focus,a.has-text-warning-light:hover{color:#ffecb8!important}.has-background-warning-light{background-color:#fffaeb!important}.has-text-warning-dark{color:#946c00!important}a.has-text-warning-dark:focus,a.has-text-warning-dark:hover{color:#c79200!important}.has-background-warning-dark{background-color:#946c00!important}.has-text-danger{color:#f14668!important}a.has-text-danger:focus,a.has-text-danger:hover{color:#ee1742!important}.has-background-danger{background-color:#f14668!important}.has-text-danger-light{color:#feecf0!important}a.has-text-danger-light:focus,a.has-text-danger-light:hover{color:#fabdc9!important}.has-background-danger-light{background-color:#feecf0!important}.has-text-danger-dark{color:#cc0f35!important}a.has-text-danger-dark:focus,a.has-text-danger-dark:hover{color:#ee2049!important}.has-background-danger-dark{background-color:#cc0f35!important}.has-text-black-bis{color:#121212!important}.has-background-black-bis{background-color:#121212!important}.has-text-black-ter{color:#242424!important}.has-background-black-ter{background-color:#242424!important}.has-text-grey-darker{color:#363636!important}.has-background-grey-darker{background-color:#363636!important}.has-text-grey-dark{color:#4a4a4a!important}.has-background-grey-dark{background-color:#4a4a4a!important}.has-text-grey{color:#7a7a7a!important}.has-background-grey{background-color:#7a7a7a!important}.has-text-grey-light{color:#b5b5b5!important}.has-background-grey-light{background-color:#b5b5b5!important}.has-text-grey-lighter{color:#dbdbdb!important}.has-background-grey-lighter{background-color:#dbdbdb!important}.has-text-white-ter{color:#f5f5f5!important}.has-background-white-ter{background-color:#f5f5f5!important}.has-text-white-bis{color:#fafafa!important}.has-background-white-bis{background-color:#fafafa!important}.is-flex-direction-row{flex-direction:row!important}.is-flex-direction-row-reverse{flex-direction:row-reverse!important}.is-flex-direction-column{flex-direction:column!important}.is-flex-direction-column-reverse{flex-direction:column-reverse!important}.is-flex-wrap-nowrap{flex-wrap:nowrap!important}.is-flex-wrap-wrap{flex-wrap:wrap!important}.is-flex-wrap-wrap-reverse{flex-wrap:wrap-reverse!important}.is-justify-content-flex-start{justify-content:flex-start!important}.is-justify-content-flex-end{justify-content:flex-end!important}.is-justify-content-center{justify-content:center!important}.is-justify-content-space-between{justify-content:space-between!important}.is-justify-content-space-around{justify-content:space-around!important}.is-justify-content-space-evenly{justify-content:space-evenly!important}.is-justify-content-start{justify-content:start!important}.is-justify-content-end{justify-content:end!important}.is-justify-content-left{justify-content:left!important}.is-justify-content-right{justify-content:right!important}.is-align-content-flex-start{align-content:flex-start!important}.is-align-content-flex-end{align-content:flex-end!important}.is-align-content-center{align-content:center!important}.is-align-content-space-between{align-content:space-between!important}.is-align-content-space-around{align-content:space-around!important}.is-align-content-space-evenly{align-content:space-evenly!important}.is-align-content-stretch{align-content:stretch!important}.is-align-content-start{align-content:start!important}.is-align-content-end{align-content:end!important}.is-align-content-baseline{align-content:baseline!important}.is-align-items-stretch{align-items:stretch!important}.is-align-items-flex-start{align-items:flex-start!important}.is-align-items-flex-end{align-items:flex-end!important}.is-align-items-center{align-items:center!important}.is-align-items-baseline{align-items:baseline!important}.is-align-items-start{align-items:start!important}.is-align-items-end{align-items:end!important}.is-align-items-self-start{align-items:self-start!important}.is-align-items-self-end{align-items:self-end!important}.is-align-self-auto{align-self:auto!important}.is-align-self-flex-start{align-self:flex-start!important}.is-align-self-flex-end{align-self:flex-end!important}.is-align-self-center{align-self:center!important}.is-align-self-baseline{align-self:baseline!important}.is-align-self-stretch{align-self:stretch!important}.is-flex-grow-0{flex-grow:0!important}.is-flex-grow-1{flex-grow:1!important}.is-flex-grow-2{flex-grow:2!important}.is-flex-grow-3{flex-grow:3!important}.is-flex-grow-4{flex-grow:4!important}.is-flex-grow-5{flex-grow:5!important}.is-flex-shrink-0{flex-shrink:0!important}.is-flex-shrink-1{flex-shrink:1!important}.is-flex-shrink-2{flex-shrink:2!important}.is-flex-shrink-3{flex-shrink:3!important}.is-flex-shrink-4{flex-shrink:4!important}.is-flex-shrink-5{flex-shrink:5!important}.is-clearfix::after{clear:both;content:" ";display:table}.is-pulled-left{float:left!important}.is-pulled-right{float:right!important}.is-radiusless{border-radius:0!important}.is-shadowless{box-shadow:none!important}.is-clickable{cursor:pointer!important;pointer-events:all!important}.is-clipped{overflow:hidden!important}.is-relative{position:relative!important}.is-marginless{margin:0!important}.is-paddingless{padding:0!important}.m-0{margin:0!important}.mt-0{margin-top:0!important}.mr-0{margin-right:0!important}.mb-0{margin-bottom:0!important}.ml-0{margin-left:0!important}.mx-0{margin-left:0!important;margin-right:0!important}.my-0{margin-top:0!important;margin-bottom:0!important}.m-1{margin:.25rem!important}.mt-1{margin-top:.25rem!important}.mr-1{margin-right:.25rem!important}.mb-1{margin-bottom:.25rem!important}.ml-1{margin-left:.25rem!important}.mx-1{margin-left:.25rem!important;margin-right:.25rem!important}.my-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.m-2{margin:.5rem!important}.mt-2{margin-top:.5rem!important}.mr-2{margin-right:.5rem!important}.mb-2{margin-bottom:.5rem!important}.ml-2{margin-left:.5rem!important}.mx-2{margin-left:.5rem!important;margin-right:.5rem!important}.my-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.m-3{margin:.75rem!important}.mt-3{margin-top:.75rem!important}.mr-3{margin-right:.75rem!important}.mb-3{margin-bottom:.75rem!important}.ml-3{margin-left:.75rem!important}.mx-3{margin-left:.75rem!important;margin-right:.75rem!important}.my-3{margin-top:.75rem!important;margin-bottom:.75rem!important}.m-4{margin:1rem!important}.mt-4{margin-top:1rem!important}.mr-4{margin-right:1rem!important}.mb-4{margin-bottom:1rem!important}.ml-4{margin-left:1rem!important}.mx-4{margin-left:1rem!important;margin-right:1rem!important}.my-4{margin-top:1rem!important;margin-bottom:1rem!important}.m-5{margin:1.5rem!important}.mt-5{margin-top:1.5rem!important}.mr-5{margin-right:1.5rem!important}.mb-5{margin-bottom:1.5rem!important}.ml-5{margin-left:1.5rem!important}.mx-5{margin-left:1.5rem!important;margin-right:1.5rem!important}.my-5{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.m-6{margin:3rem!important}.mt-6{margin-top:3rem!important}.mr-6{margin-right:3rem!important}.mb-6{margin-bottom:3rem!important}.ml-6{margin-left:3rem!important}.mx-6{margin-left:3rem!important;margin-right:3rem!important}.my-6{margin-top:3rem!important;margin-bottom:3rem!important}.m-auto{margin:auto!important}.mt-auto{margin-top:auto!important}.mr-auto{margin-right:auto!important}.mb-auto{margin-bottom:auto!important}.ml-auto{margin-left:auto!important}.mx-auto{margin-left:auto!important;margin-right:auto!important}.my-auto{margin-top:auto!important;margin-bottom:auto!important}.p-0{padding:0!important}.pt-0{padding-top:0!important}.pr-0{padding-right:0!important}.pb-0{padding-bottom:0!important}.pl-0{padding-left:0!important}.px-0{padding-left:0!important;padding-right:0!important}.py-0{padding-top:0!important;padding-bottom:0!important}.p-1{padding:.25rem!important}.pt-1{padding-top:.25rem!important}.pr-1{padding-right:.25rem!important}.pb-1{padding-bottom:.25rem!important}.pl-1{padding-left:.25rem!important}.px-1{padding-left:.25rem!important;padding-right:.25rem!important}.py-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.p-2{padding:.5rem!important}.pt-2{padding-top:.5rem!important}.pr-2{padding-right:.5rem!important}.pb-2{padding-bottom:.5rem!important}.pl-2{padding-left:.5rem!important}.px-2{padding-left:.5rem!important;padding-right:.5rem!important}.py-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.p-3{padding:.75rem!important}.pt-3{padding-top:.75rem!important}.pr-3{padding-right:.75rem!important}.pb-3{padding-bottom:.75rem!important}.pl-3{padding-left:.75rem!important}.px-3{padding-left:.75rem!important;padding-right:.75rem!important}.py-3{padding-top:.75rem!important;padding-bottom:.75rem!important}.p-4{padding:1rem!important}.pt-4{padding-top:1rem!important}.pr-4{padding-right:1rem!important}.pb-4{padding-bottom:1rem!important}.pl-4{padding-left:1rem!important}.px-4{padding-left:1rem!important;padding-right:1rem!important}.py-4{padding-top:1rem!important;padding-bottom:1rem!important}.p-5{padding:1.5rem!important}.pt-5{padding-top:1.5rem!important}.pr-5{padding-right:1.5rem!important}.pb-5{padding-bottom:1.5rem!important}.pl-5{padding-left:1.5rem!important}.px-5{padding-left:1.5rem!important;padding-right:1.5rem!important}.py-5{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.p-6{padding:3rem!important}.pt-6{padding-top:3rem!important}.pr-6{padding-right:3rem!important}.pb-6{padding-bottom:3rem!important}.pl-6{padding-left:3rem!important}.px-6{padding-left:3rem!important;padding-right:3rem!important}.py-6{padding-top:3rem!important;padding-bottom:3rem!important}.p-auto{padding:auto!important}.pt-auto{padding-top:auto!important}.pr-auto{padding-right:auto!important}.pb-auto{padding-bottom:auto!important}.pl-auto{padding-left:auto!important}.px-auto{padding-left:auto!important;padding-right:auto!important}.py-auto{padding-top:auto!important;padding-bottom:auto!important}.is-size-1{font-size:3rem!important}.is-size-2{font-size:2.5rem!important}.is-size-3{font-size:2rem!important}.is-size-4{font-size:1.5rem!important}.is-size-5{font-size:1.25rem!important}.is-size-6{font-size:1rem!important}.is-size-7{font-size:.75rem!important}@media screen and (max-width:768px){.is-size-1-mobile{font-size:3rem!important}.is-size-2-mobile{font-size:2.5rem!important}.is-size-3-mobile{font-size:2rem!important}.is-size-4-mobile{font-size:1.5rem!important}.is-size-5-mobile{font-size:1.25rem!important}.is-size-6-mobile{font-size:1rem!important}.is-size-7-mobile{font-size:.75rem!important}}@media screen and (min-width:769px),print{.is-size-1-tablet{font-size:3rem!important}.is-size-2-tablet{font-size:2.5rem!important}.is-size-3-tablet{font-size:2rem!important}.is-size-4-tablet{font-size:1.5rem!important}.is-size-5-tablet{font-size:1.25rem!important}.is-size-6-tablet{font-size:1rem!important}.is-size-7-tablet{font-size:.75rem!important}}@media screen and (max-width:1023px){.is-size-1-touch{font-size:3rem!important}.is-size-2-touch{font-size:2.5rem!important}.is-size-3-touch{font-size:2rem!important}.is-size-4-touch{font-size:1.5rem!important}.is-size-5-touch{font-size:1.25rem!important}.is-size-6-touch{font-size:1rem!important}.is-size-7-touch{font-size:.75rem!important}}@media screen and (min-width:1024px){.is-size-1-desktop{font-size:3rem!important}.is-size-2-desktop{font-size:2.5rem!important}.is-size-3-desktop{font-size:2rem!important}.is-size-4-desktop{font-size:1.5rem!important}.is-size-5-desktop{font-size:1.25rem!important}.is-size-6-desktop{font-size:1rem!important}.is-size-7-desktop{font-size:.75rem!important}}@media screen and (min-width:1216px){.is-size-1-widescreen{font-size:3rem!important}.is-size-2-widescreen{font-size:2.5rem!important}.is-size-3-widescreen{font-size:2rem!important}.is-size-4-widescreen{font-size:1.5rem!important}.is-size-5-widescreen{font-size:1.25rem!important}.is-size-6-widescreen{font-size:1rem!important}.is-size-7-widescreen{font-size:.75rem!important}}@media screen and (min-width:1408px){.is-size-1-fullhd{font-size:3rem!important}.is-size-2-fullhd{font-size:2.5rem!important}.is-size-3-fullhd{font-size:2rem!important}.is-size-4-fullhd{font-size:1.5rem!important}.is-size-5-fullhd{font-size:1.25rem!important}.is-size-6-fullhd{font-size:1rem!important}.is-size-7-fullhd{font-size:.75rem!important}}.has-text-centered{text-align:center!important}.has-text-justified{text-align:justify!important}.has-text-left{text-align:left!important}.has-text-right{text-align:right!important}@media screen and (max-width:768px){.has-text-centered-mobile{text-align:center!important}}@media screen and (min-width:769px),print{.has-text-centered-tablet{text-align:center!important}}@media screen and (min-width:769px) and (max-width:1023px){.has-text-centered-tablet-only{text-align:center!important}}@media screen and (max-width:1023px){.has-text-centered-touch{text-align:center!important}}@media screen and (min-width:1024px){.has-text-centered-desktop{text-align:center!important}}@media screen and (min-width:1024px) and (max-width:1215px){.has-text-centered-desktop-only{text-align:center!important}}@media screen and (min-width:1216px){.has-text-centered-widescreen{text-align:center!important}}@media screen and (min-width:1216px) and (max-width:1407px){.has-text-centered-widescreen-only{text-align:center!important}}@media screen and (min-width:1408px){.has-text-centered-fullhd{text-align:center!important}}@media screen and (max-width:768px){.has-text-justified-mobile{text-align:justify!important}}@media screen and (min-width:769px),print{.has-text-justified-tablet{text-align:justify!important}}@media screen and (min-width:769px) and (max-width:1023px){.has-text-justified-tablet-only{text-align:justify!important}}@media screen and (max-width:1023px){.has-text-justified-touch{text-align:justify!important}}@media screen and (min-width:1024px){.has-text-justified-desktop{text-align:justify!important}}@media screen and (min-width:1024px) and (max-width:1215px){.has-text-justified-desktop-only{text-align:justify!important}}@media screen and (min-width:1216px){.has-text-justified-widescreen{text-align:justify!important}}@media screen and (min-width:1216px) and (max-width:1407px){.has-text-justified-widescreen-only{text-align:justify!important}}@media screen and (min-width:1408px){.has-text-justified-fullhd{text-align:justify!important}}@media screen and (max-width:768px){.has-text-left-mobile{text-align:left!important}}@media screen and (min-width:769px),print{.has-text-left-tablet{text-align:left!important}}@media screen and (min-width:769px) and (max-width:1023px){.has-text-left-tablet-only{text-align:left!important}}@media screen and (max-width:1023px){.has-text-left-touch{text-align:left!important}}@media screen and (min-width:1024px){.has-text-left-desktop{text-align:left!important}}@media screen and (min-width:1024px) and (max-width:1215px){.has-text-left-desktop-only{text-align:left!important}}@media screen and (min-width:1216px){.has-text-left-widescreen{text-align:left!important}}@media screen and (min-width:1216px) and (max-width:1407px){.has-text-left-widescreen-only{text-align:left!important}}@media screen and (min-width:1408px){.has-text-left-fullhd{text-align:left!important}}@media screen and (max-width:768px){.has-text-right-mobile{text-align:right!important}}@media screen and (min-width:769px),print{.has-text-right-tablet{text-align:right!important}}@media screen and (min-width:769px) and (max-width:1023px){.has-text-right-tablet-only{text-align:right!important}}@media screen and (max-width:1023px){.has-text-right-touch{text-align:right!important}}@media screen and (min-width:1024px){.has-text-right-desktop{text-align:right!important}}@media screen and (min-width:1024px) and (max-width:1215px){.has-text-right-desktop-only{text-align:right!important}}@media screen and (min-width:1216px){.has-text-right-widescreen{text-align:right!important}}@media screen and (min-width:1216px) and (max-width:1407px){.has-text-right-widescreen-only{text-align:right!important}}@media screen and (min-width:1408px){.has-text-right-fullhd{text-align:right!important}}.is-capitalized{text-transform:capitalize!important}.is-lowercase{text-transform:lowercase!important}.is-uppercase{text-transform:uppercase!important}.is-italic{font-style:italic!important}.is-underlined{text-decoration:underline!important}.has-text-weight-light{font-weight:300!important}.has-text-weight-normal{font-weight:400!important}.has-text-weight-medium{font-weight:500!important}.has-text-weight-semibold{font-weight:600!important}.has-text-weight-bold{font-weight:700!important}.is-family-primary{font-family:BlinkMacSystemFont,-apple-system,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Fira Sans","Droid Sans","Helvetica Neue",Helvetica,Arial,sans-serif!important}.is-family-secondary{font-family:BlinkMacSystemFont,-apple-system,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Fira Sans","Droid Sans","Helvetica Neue",Helvetica,Arial,sans-serif!important}.is-family-sans-serif{font-family:BlinkMacSystemFont,-apple-system,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Fira Sans","Droid Sans","Helvetica Neue",Helvetica,Arial,sans-serif!important}.is-family-monospace{font-family:monospace!important}.is-family-code{font-family:monospace!important}.is-block{display:block!important}@media screen and (max-width:768px){.is-block-mobile{display:block!important}}@media screen and (min-width:769px),print{.is-block-tablet{display:block!important}}@media screen and (min-width:769px) and (max-width:1023px){.is-block-tablet-only{display:block!important}}@media screen and (max-width:1023px){.is-block-touch{display:block!important}}@media screen and (min-width:1024px){.is-block-desktop{display:block!important}}@media screen and (min-width:1024px) and (max-width:1215px){.is-block-desktop-only{display:block!important}}@media screen and (min-width:1216px){.is-block-widescreen{display:block!important}}@media screen and (min-width:1216px) and (max-width:1407px){.is-block-widescreen-only{display:block!important}}@media screen and (min-width:1408px){.is-block-fullhd{display:block!important}}.is-flex{display:flex!important}@media screen and (max-width:768px){.is-flex-mobile{display:flex!important}}@media screen and (min-width:769px),print{.is-flex-tablet{display:flex!important}}@media screen and (min-width:769px) and (max-width:1023px){.is-flex-tablet-only{display:flex!important}}@media screen and (max-width:1023px){.is-flex-touch{display:flex!important}}@media screen and (min-width:1024px){.is-flex-desktop{display:flex!important}}@media screen and (min-width:1024px) and (max-width:1215px){.is-flex-desktop-only{display:flex!important}}@media screen and (min-width:1216px){.is-flex-widescreen{display:flex!important}}@media screen and (min-width:1216px) and (max-width:1407px){.is-flex-widescreen-only{display:flex!important}}@media screen and (min-width:1408px){.is-flex-fullhd{display:flex!important}}.is-inline{display:inline!important}@media screen and (max-width:768px){.is-inline-mobile{display:inline!important}}@media screen and (min-width:769px),print{.is-inline-tablet{display:inline!important}}@media screen and (min-width:769px) and (max-width:1023px){.is-inline-tablet-only{display:inline!important}}@media screen and (max-width:1023px){.is-inline-touch{display:inline!important}}@media screen and (min-width:1024px){.is-inline-desktop{display:inline!important}}@media screen and (min-width:1024px) and (max-width:1215px){.is-inline-desktop-only{display:inline!important}}@media screen and (min-width:1216px){.is-inline-widescreen{display:inline!important}}@media screen and (min-width:1216px) and (max-width:1407px){.is-inline-widescreen-only{display:inline!important}}@media screen and (min-width:1408px){.is-inline-fullhd{display:inline!important}}.is-inline-block{display:inline-block!important}@media screen and (max-width:768px){.is-inline-block-mobile{display:inline-block!important}}@media screen and (min-width:769px),print{.is-inline-block-tablet{display:inline-block!important}}@media screen and (min-width:769px) and (max-width:1023px){.is-inline-block-tablet-only{display:inline-block!important}}@media screen and (max-width:1023px){.is-inline-block-touch{display:inline-block!important}}@media screen and (min-width:1024px){.is-inline-block-desktop{display:inline-block!important}}@media screen and (min-width:1024px) and (max-width:1215px){.is-inline-block-desktop-only{display:inline-block!important}}@media screen and (min-width:1216px){.is-inline-block-widescreen{display:inline-block!important}}@media screen and (min-width:1216px) and (max-width:1407px){.is-inline-block-widescreen-only{display:inline-block!important}}@media screen and (min-width:1408px){.is-inline-block-fullhd{display:inline-block!important}}.is-inline-flex{display:inline-flex!important}@media screen and (max-width:768px){.is-inline-flex-mobile{display:inline-flex!important}}@media screen and (min-width:769px),print{.is-inline-flex-tablet{display:inline-flex!important}}@media screen and (min-width:769px) and (max-width:1023px){.is-inline-flex-tablet-only{display:inline-flex!important}}@media screen and (max-width:1023px){.is-inline-flex-touch{display:inline-flex!important}}@media screen and (min-width:1024px){.is-inline-flex-desktop{display:inline-flex!important}}@media screen and (min-width:1024px) and (max-width:1215px){.is-inline-flex-desktop-only{display:inline-flex!important}}@media screen and (min-width:1216px){.is-inline-flex-widescreen{display:inline-flex!important}}@media screen and (min-width:1216px) and (max-width:1407px){.is-inline-flex-widescreen-only{display:inline-flex!important}}@media screen and (min-width:1408px){.is-inline-flex-fullhd{display:inline-flex!important}}.is-hidden{display:none!important}.is-sr-only{border:none!important;clip:rect(0,0,0,0)!important;height:.01em!important;overflow:hidden!important;padding:0!important;position:absolute!important;white-space:nowrap!important;width:.01em!important}@media screen and (max-width:768px){.is-hidden-mobile{display:none!important}}@media screen and (min-width:769px),print{.is-hidden-tablet{display:none!important}}@media screen and (min-width:769px) and (max-width:1023px){.is-hidden-tablet-only{display:none!important}}@media screen and (max-width:1023px){.is-hidden-touch{display:none!important}}@media screen and (min-width:1024px){.is-hidden-desktop{display:none!important}}@media screen and (min-width:1024px) and (max-width:1215px){.is-hidden-desktop-only{display:none!important}}@media screen and (min-width:1216px){.is-hidden-widescreen{display:none!important}}@media screen and (min-width:1216px) and (max-width:1407px){.is-hidden-widescreen-only{display:none!important}}@media screen and (min-width:1408px){.is-hidden-fullhd{display:none!important}}.is-invisible{visibility:hidden!important}@media screen and (max-width:768px){.is-invisible-mobile{visibility:hidden!important}}@media screen and (min-width:769px),print{.is-invisible-tablet{visibility:hidden!important}}@media screen and (min-width:769px) and (max-width:1023px){.is-invisible-tablet-only{visibility:hidden!important}}@media screen and (max-width:1023px){.is-invisible-touch{visibility:hidden!important}}@media screen and (min-width:1024px){.is-invisible-desktop{visibility:hidden!important}}@media screen and (min-width:1024px) and (max-width:1215px){.is-invisible-desktop-only{visibility:hidden!important}}@media screen and (min-width:1216px){.is-invisible-widescreen{visibility:hidden!important}}@media screen and (min-width:1216px) and (max-width:1407px){.is-invisible-widescreen-only{visibility:hidden!important}}@media screen and (min-width:1408px){.is-invisible-fullhd{visibility:hidden!important}}.hero{align-items:stretch;display:flex;flex-direction:column;justify-content:space-between}.hero .navbar{background:0 0}.hero .tabs ul{border-bottom:none}.hero.is-white{background-color:#fff;color:#0a0a0a}.hero.is-white a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-white strong{color:inherit}.hero.is-white .title{color:#0a0a0a}.hero.is-white .subtitle{color:rgba(10,10,10,.9)}.hero.is-white .subtitle a:not(.button),.hero.is-white .subtitle strong{color:#0a0a0a}@media screen and (max-width:1023px){.hero.is-white .navbar-menu{background-color:#fff}}.hero.is-white .navbar-item,.hero.is-white .navbar-link{color:rgba(10,10,10,.7)}.hero.is-white .navbar-link.is-active,.hero.is-white .navbar-link:hover,.hero.is-white a.navbar-item.is-active,.hero.is-white a.navbar-item:hover{background-color:#f2f2f2;color:#0a0a0a}.hero.is-white .tabs a{color:#0a0a0a;opacity:.9}.hero.is-white .tabs a:hover{opacity:1}.hero.is-white .tabs li.is-active a{color:#fff!important;opacity:1}.hero.is-white .tabs.is-boxed a,.hero.is-white .tabs.is-toggle a{color:#0a0a0a}.hero.is-white .tabs.is-boxed a:hover,.hero.is-white .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-white .tabs.is-boxed li.is-active a,.hero.is-white .tabs.is-boxed li.is-active a:hover,.hero.is-white .tabs.is-toggle li.is-active a,.hero.is-white .tabs.is-toggle li.is-active a:hover{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}.hero.is-white.is-bold{background-image:linear-gradient(141deg,#e6e6e6 0,#fff 71%,#fff 100%)}@media screen and (max-width:768px){.hero.is-white.is-bold .navbar-menu{background-image:linear-gradient(141deg,#e6e6e6 0,#fff 71%,#fff 100%)}}.hero.is-black{background-color:#0a0a0a;color:#fff}.hero.is-black a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-black strong{color:inherit}.hero.is-black .title{color:#fff}.hero.is-black .subtitle{color:rgba(255,255,255,.9)}.hero.is-black .subtitle a:not(.button),.hero.is-black .subtitle strong{color:#fff}@media screen and (max-width:1023px){.hero.is-black .navbar-menu{background-color:#0a0a0a}}.hero.is-black .navbar-item,.hero.is-black .navbar-link{color:rgba(255,255,255,.7)}.hero.is-black .navbar-link.is-active,.hero.is-black .navbar-link:hover,.hero.is-black a.navbar-item.is-active,.hero.is-black a.navbar-item:hover{background-color:#000;color:#fff}.hero.is-black .tabs a{color:#fff;opacity:.9}.hero.is-black .tabs a:hover{opacity:1}.hero.is-black .tabs li.is-active a{color:#0a0a0a!important;opacity:1}.hero.is-black .tabs.is-boxed a,.hero.is-black .tabs.is-toggle a{color:#fff}.hero.is-black .tabs.is-boxed a:hover,.hero.is-black .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-black .tabs.is-boxed li.is-active a,.hero.is-black .tabs.is-boxed li.is-active a:hover,.hero.is-black .tabs.is-toggle li.is-active a,.hero.is-black .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#0a0a0a}.hero.is-black.is-bold{background-image:linear-gradient(141deg,#000 0,#0a0a0a 71%,#181616 100%)}@media screen and (max-width:768px){.hero.is-black.is-bold .navbar-menu{background-image:linear-gradient(141deg,#000 0,#0a0a0a 71%,#181616 100%)}}.hero.is-light{background-color:#f5f5f5;color:rgba(0,0,0,.7)}.hero.is-light a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-light strong{color:inherit}.hero.is-light .title{color:rgba(0,0,0,.7)}.hero.is-light .subtitle{color:rgba(0,0,0,.9)}.hero.is-light .subtitle a:not(.button),.hero.is-light .subtitle strong{color:rgba(0,0,0,.7)}@media screen and (max-width:1023px){.hero.is-light .navbar-menu{background-color:#f5f5f5}}.hero.is-light .navbar-item,.hero.is-light .navbar-link{color:rgba(0,0,0,.7)}.hero.is-light .navbar-link.is-active,.hero.is-light .navbar-link:hover,.hero.is-light a.navbar-item.is-active,.hero.is-light a.navbar-item:hover{background-color:#e8e8e8;color:rgba(0,0,0,.7)}.hero.is-light .tabs a{color:rgba(0,0,0,.7);opacity:.9}.hero.is-light .tabs a:hover{opacity:1}.hero.is-light .tabs li.is-active a{color:#f5f5f5!important;opacity:1}.hero.is-light .tabs.is-boxed a,.hero.is-light .tabs.is-toggle a{color:rgba(0,0,0,.7)}.hero.is-light .tabs.is-boxed a:hover,.hero.is-light .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-light .tabs.is-boxed li.is-active a,.hero.is-light .tabs.is-boxed li.is-active a:hover,.hero.is-light .tabs.is-toggle li.is-active a,.hero.is-light .tabs.is-toggle li.is-active a:hover{background-color:rgba(0,0,0,.7);border-color:rgba(0,0,0,.7);color:#f5f5f5}.hero.is-light.is-bold{background-image:linear-gradient(141deg,#dfd8d9 0,#f5f5f5 71%,#fff 100%)}@media screen and (max-width:768px){.hero.is-light.is-bold .navbar-menu{background-image:linear-gradient(141deg,#dfd8d9 0,#f5f5f5 71%,#fff 100%)}}.hero.is-dark{background-color:#363636;color:#fff}.hero.is-dark a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-dark strong{color:inherit}.hero.is-dark .title{color:#fff}.hero.is-dark .subtitle{color:rgba(255,255,255,.9)}.hero.is-dark .subtitle a:not(.button),.hero.is-dark .subtitle strong{color:#fff}@media screen and (max-width:1023px){.hero.is-dark .navbar-menu{background-color:#363636}}.hero.is-dark .navbar-item,.hero.is-dark .navbar-link{color:rgba(255,255,255,.7)}.hero.is-dark .navbar-link.is-active,.hero.is-dark .navbar-link:hover,.hero.is-dark a.navbar-item.is-active,.hero.is-dark a.navbar-item:hover{background-color:#292929;color:#fff}.hero.is-dark .tabs a{color:#fff;opacity:.9}.hero.is-dark .tabs a:hover{opacity:1}.hero.is-dark .tabs li.is-active a{color:#363636!important;opacity:1}.hero.is-dark .tabs.is-boxed a,.hero.is-dark .tabs.is-toggle a{color:#fff}.hero.is-dark .tabs.is-boxed a:hover,.hero.is-dark .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-dark .tabs.is-boxed li.is-active a,.hero.is-dark .tabs.is-boxed li.is-active a:hover,.hero.is-dark .tabs.is-toggle li.is-active a,.hero.is-dark .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#363636}.hero.is-dark.is-bold{background-image:linear-gradient(141deg,#1f191a 0,#363636 71%,#46403f 100%)}@media screen and (max-width:768px){.hero.is-dark.is-bold .navbar-menu{background-image:linear-gradient(141deg,#1f191a 0,#363636 71%,#46403f 100%)}}.hero.is-primary{background-color:#00d1b2;color:#fff}.hero.is-primary a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-primary strong{color:inherit}.hero.is-primary .title{color:#fff}.hero.is-primary .subtitle{color:rgba(255,255,255,.9)}.hero.is-primary .subtitle a:not(.button),.hero.is-primary .subtitle strong{color:#fff}@media screen and (max-width:1023px){.hero.is-primary .navbar-menu{background-color:#00d1b2}}.hero.is-primary .navbar-item,.hero.is-primary .navbar-link{color:rgba(255,255,255,.7)}.hero.is-primary .navbar-link.is-active,.hero.is-primary .navbar-link:hover,.hero.is-primary a.navbar-item.is-active,.hero.is-primary a.navbar-item:hover{background-color:#00b89c;color:#fff}.hero.is-primary .tabs a{color:#fff;opacity:.9}.hero.is-primary .tabs a:hover{opacity:1}.hero.is-primary .tabs li.is-active a{color:#00d1b2!important;opacity:1}.hero.is-primary .tabs.is-boxed a,.hero.is-primary .tabs.is-toggle a{color:#fff}.hero.is-primary .tabs.is-boxed a:hover,.hero.is-primary .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-primary .tabs.is-boxed li.is-active a,.hero.is-primary .tabs.is-boxed li.is-active a:hover,.hero.is-primary .tabs.is-toggle li.is-active a,.hero.is-primary .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#00d1b2}.hero.is-primary.is-bold{background-image:linear-gradient(141deg,#009e6c 0,#00d1b2 71%,#00e7eb 100%)}@media screen and (max-width:768px){.hero.is-primary.is-bold .navbar-menu{background-image:linear-gradient(141deg,#009e6c 0,#00d1b2 71%,#00e7eb 100%)}}.hero.is-link{background-color:#485fc7;color:#fff}.hero.is-link a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-link strong{color:inherit}.hero.is-link .title{color:#fff}.hero.is-link .subtitle{color:rgba(255,255,255,.9)}.hero.is-link .subtitle a:not(.button),.hero.is-link .subtitle strong{color:#fff}@media screen and (max-width:1023px){.hero.is-link .navbar-menu{background-color:#485fc7}}.hero.is-link .navbar-item,.hero.is-link .navbar-link{color:rgba(255,255,255,.7)}.hero.is-link .navbar-link.is-active,.hero.is-link .navbar-link:hover,.hero.is-link a.navbar-item.is-active,.hero.is-link a.navbar-item:hover{background-color:#3a51bb;color:#fff}.hero.is-link .tabs a{color:#fff;opacity:.9}.hero.is-link .tabs a:hover{opacity:1}.hero.is-link .tabs li.is-active a{color:#485fc7!important;opacity:1}.hero.is-link .tabs.is-boxed a,.hero.is-link .tabs.is-toggle a{color:#fff}.hero.is-link .tabs.is-boxed a:hover,.hero.is-link .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-link .tabs.is-boxed li.is-active a,.hero.is-link .tabs.is-boxed li.is-active a:hover,.hero.is-link .tabs.is-toggle li.is-active a,.hero.is-link .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#485fc7}.hero.is-link.is-bold{background-image:linear-gradient(141deg,#2959b3 0,#485fc7 71%,#5658d2 100%)}@media screen and (max-width:768px){.hero.is-link.is-bold .navbar-menu{background-image:linear-gradient(141deg,#2959b3 0,#485fc7 71%,#5658d2 100%)}}.hero.is-info{background-color:#3e8ed0;color:#fff}.hero.is-info a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-info strong{color:inherit}.hero.is-info .title{color:#fff}.hero.is-info .subtitle{color:rgba(255,255,255,.9)}.hero.is-info .subtitle a:not(.button),.hero.is-info .subtitle strong{color:#fff}@media screen and (max-width:1023px){.hero.is-info .navbar-menu{background-color:#3e8ed0}}.hero.is-info .navbar-item,.hero.is-info .navbar-link{color:rgba(255,255,255,.7)}.hero.is-info .navbar-link.is-active,.hero.is-info .navbar-link:hover,.hero.is-info a.navbar-item.is-active,.hero.is-info a.navbar-item:hover{background-color:#3082c5;color:#fff}.hero.is-info .tabs a{color:#fff;opacity:.9}.hero.is-info .tabs a:hover{opacity:1}.hero.is-info .tabs li.is-active a{color:#3e8ed0!important;opacity:1}.hero.is-info .tabs.is-boxed a,.hero.is-info .tabs.is-toggle a{color:#fff}.hero.is-info .tabs.is-boxed a:hover,.hero.is-info .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-info .tabs.is-boxed li.is-active a,.hero.is-info .tabs.is-boxed li.is-active a:hover,.hero.is-info .tabs.is-toggle li.is-active a,.hero.is-info .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#3e8ed0}.hero.is-info.is-bold{background-image:linear-gradient(141deg,#208fbc 0,#3e8ed0 71%,#4d83db 100%)}@media screen and (max-width:768px){.hero.is-info.is-bold .navbar-menu{background-image:linear-gradient(141deg,#208fbc 0,#3e8ed0 71%,#4d83db 100%)}}.hero.is-success{background-color:#48c78e;color:#fff}.hero.is-success a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-success strong{color:inherit}.hero.is-success .title{color:#fff}.hero.is-success .subtitle{color:rgba(255,255,255,.9)}.hero.is-success .subtitle a:not(.button),.hero.is-success .subtitle strong{color:#fff}@media screen and (max-width:1023px){.hero.is-success .navbar-menu{background-color:#48c78e}}.hero.is-success .navbar-item,.hero.is-success .navbar-link{color:rgba(255,255,255,.7)}.hero.is-success .navbar-link.is-active,.hero.is-success .navbar-link:hover,.hero.is-success a.navbar-item.is-active,.hero.is-success a.navbar-item:hover{background-color:#3abb81;color:#fff}.hero.is-success .tabs a{color:#fff;opacity:.9}.hero.is-success .tabs a:hover{opacity:1}.hero.is-success .tabs li.is-active a{color:#48c78e!important;opacity:1}.hero.is-success .tabs.is-boxed a,.hero.is-success .tabs.is-toggle a{color:#fff}.hero.is-success .tabs.is-boxed a:hover,.hero.is-success .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-success .tabs.is-boxed li.is-active a,.hero.is-success .tabs.is-boxed li.is-active a:hover,.hero.is-success .tabs.is-toggle li.is-active a,.hero.is-success .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#48c78e}.hero.is-success.is-bold{background-image:linear-gradient(141deg,#29b35e 0,#48c78e 71%,#56d2af 100%)}@media screen and (max-width:768px){.hero.is-success.is-bold .navbar-menu{background-image:linear-gradient(141deg,#29b35e 0,#48c78e 71%,#56d2af 100%)}}.hero.is-warning{background-color:#ffe08a;color:rgba(0,0,0,.7)}.hero.is-warning a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-warning strong{color:inherit}.hero.is-warning .title{color:rgba(0,0,0,.7)}.hero.is-warning .subtitle{color:rgba(0,0,0,.9)}.hero.is-warning .subtitle a:not(.button),.hero.is-warning .subtitle strong{color:rgba(0,0,0,.7)}@media screen and (max-width:1023px){.hero.is-warning .navbar-menu{background-color:#ffe08a}}.hero.is-warning .navbar-item,.hero.is-warning .navbar-link{color:rgba(0,0,0,.7)}.hero.is-warning .navbar-link.is-active,.hero.is-warning .navbar-link:hover,.hero.is-warning a.navbar-item.is-active,.hero.is-warning a.navbar-item:hover{background-color:#ffd970;color:rgba(0,0,0,.7)}.hero.is-warning .tabs a{color:rgba(0,0,0,.7);opacity:.9}.hero.is-warning .tabs a:hover{opacity:1}.hero.is-warning .tabs li.is-active a{color:#ffe08a!important;opacity:1}.hero.is-warning .tabs.is-boxed a,.hero.is-warning .tabs.is-toggle a{color:rgba(0,0,0,.7)}.hero.is-warning .tabs.is-boxed a:hover,.hero.is-warning .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-warning .tabs.is-boxed li.is-active a,.hero.is-warning .tabs.is-boxed li.is-active a:hover,.hero.is-warning .tabs.is-toggle li.is-active a,.hero.is-warning .tabs.is-toggle li.is-active a:hover{background-color:rgba(0,0,0,.7);border-color:rgba(0,0,0,.7);color:#ffe08a}.hero.is-warning.is-bold{background-image:linear-gradient(141deg,#ffb657 0,#ffe08a 71%,#fff6a3 100%)}@media screen and (max-width:768px){.hero.is-warning.is-bold .navbar-menu{background-image:linear-gradient(141deg,#ffb657 0,#ffe08a 71%,#fff6a3 100%)}}.hero.is-danger{background-color:#f14668;color:#fff}.hero.is-danger a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-danger strong{color:inherit}.hero.is-danger .title{color:#fff}.hero.is-danger .subtitle{color:rgba(255,255,255,.9)}.hero.is-danger .subtitle a:not(.button),.hero.is-danger .subtitle strong{color:#fff}@media screen and (max-width:1023px){.hero.is-danger .navbar-menu{background-color:#f14668}}.hero.is-danger .navbar-item,.hero.is-danger .navbar-link{color:rgba(255,255,255,.7)}.hero.is-danger .navbar-link.is-active,.hero.is-danger .navbar-link:hover,.hero.is-danger a.navbar-item.is-active,.hero.is-danger a.navbar-item:hover{background-color:#ef2e55;color:#fff}.hero.is-danger .tabs a{color:#fff;opacity:.9}.hero.is-danger .tabs a:hover{opacity:1}.hero.is-danger .tabs li.is-active a{color:#f14668!important;opacity:1}.hero.is-danger .tabs.is-boxed a,.hero.is-danger .tabs.is-toggle a{color:#fff}.hero.is-danger .tabs.is-boxed a:hover,.hero.is-danger .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-danger .tabs.is-boxed li.is-active a,.hero.is-danger .tabs.is-boxed li.is-active a:hover,.hero.is-danger .tabs.is-toggle li.is-active a,.hero.is-danger .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#f14668}.hero.is-danger.is-bold{background-image:linear-gradient(141deg,#fa0a62 0,#f14668 71%,#f7595f 100%)}@media screen and (max-width:768px){.hero.is-danger.is-bold .navbar-menu{background-image:linear-gradient(141deg,#fa0a62 0,#f14668 71%,#f7595f 100%)}}.hero.is-small .hero-body{padding:1.5rem}@media screen and (min-width:769px),print{.hero.is-medium .hero-body{padding:9rem 4.5rem}}@media screen and (min-width:769px),print{.hero.is-large .hero-body{padding:18rem 6rem}}.hero.is-fullheight .hero-body,.hero.is-fullheight-with-navbar .hero-body,.hero.is-halfheight .hero-body{align-items:center;display:flex}.hero.is-fullheight .hero-body>.container,.hero.is-fullheight-with-navbar .hero-body>.container,.hero.is-halfheight .hero-body>.container{flex-grow:1;flex-shrink:1}.hero.is-halfheight{min-height:50vh}.hero.is-fullheight{min-height:100vh}.hero-video{overflow:hidden}.hero-video video{left:50%;min-height:100%;min-width:100%;position:absolute;top:50%;transform:translate3d(-50%,-50%,0)}.hero-video.is-transparent{opacity:.3}@media screen and (max-width:768px){.hero-video{display:none}}.hero-buttons{margin-top:1.5rem}@media screen and (max-width:768px){.hero-buttons .button{display:flex}.hero-buttons .button:not(:last-child){margin-bottom:.75rem}}@media screen and (min-width:769px),print{.hero-buttons{display:flex;justify-content:center}.hero-buttons .button:not(:last-child){margin-right:1.5rem}}.hero-foot,.hero-head{flex-grow:0;flex-shrink:0}.hero-body{flex-grow:1;flex-shrink:0;padding:3rem 1.5rem}@media screen and (min-width:769px),print{.hero-body{padding:3rem 3rem}}.section{padding:3rem 1.5rem}@media screen and (min-width:1024px){.section{padding:3rem 3rem}.section.is-medium{padding:9rem 4.5rem}.section.is-large{padding:18rem 6rem}}.footer{background-color:#fafafa;padding:3rem 1.5rem 6rem}
\ No newline at end of file
diff --git a/mc_openapi/assets/templates/base.html b/mc_openapi/assets/templates/base.html
new file mode 100644
index 0000000000000000000000000000000000000000..0f74a00ba295bc47d253b1ca5cc8855a0e60f334
--- /dev/null
+++ b/mc_openapi/assets/templates/base.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+  <meta charset="utf-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1">
+  <title>DOML Model Checker</title>
+  <link href="{{ url_for('static', path='/bulma.min.css') }}" rel="stylesheet">
+</head>
+
+<body>
+  <section class="section">
+    <div class="container">
+      {% block content %}
+      {% endblock %}
+    </div>
+  </section>
+</body>
+
+</html>
\ No newline at end of file
diff --git a/mc_openapi/assets/templates/csp.html b/mc_openapi/assets/templates/csp.html
new file mode 100644
index 0000000000000000000000000000000000000000..441abc63e7886e1d3197759005162b4eea8dfe83
--- /dev/null
+++ b/mc_openapi/assets/templates/csp.html
@@ -0,0 +1,5 @@
+{% extends "base.html" %}
+
+{% block content %}
+{% include "csp_content.html" %}
+{% endblock content %}
\ No newline at end of file
diff --git a/mc_openapi/assets/templates/csp_content.html b/mc_openapi/assets/templates/csp_content.html
new file mode 100644
index 0000000000000000000000000000000000000000..06d643f9b43a2eb9761fef5878c585f66a248643
--- /dev/null
+++ b/mc_openapi/assets/templates/csp_content.html
@@ -0,0 +1,98 @@
+<h1 class="title">CSP Compatibility Results</h1>
+{# FIX IMPORTS FOR MC #}
+{% if csp %}
+{% set keypairs = csp.keypairs %}
+{% set os = csp.os %}
+{% set arch = csp.arch %}
+{% set minreq = csp.minreq %}
+{% endif %}
+
+<div class="box">
+    {% if keypairs %}
+    <h2 class="title is-4">Keypairs</h2>
+    <div class="table-container">
+        <table class="table is-bordered is-striped is-hoverable">
+            {% for row in keypairs %}
+            {% set outer_loop = loop %}
+            <tr>
+                {% for column in row %}
+                {% if outer_loop.first or loop.first %}
+                <th>{{ column }}</th>
+                {% else %}
+                <td>{{ column }}</td>
+                {% endif %}
+                {% endfor %}
+            </tr>
+            {% endfor %}
+        </table>
+    </div>
+    {% endif %}
+
+    {% if os %}
+    <h2 class="title is-4">OS</h2>
+    <div class="table-container">
+        <table class="table is-bordered is-striped is-hoverable">
+            {% for row in os %}
+            {% set outer_loop = loop %}
+            <tr>
+                {% for column in row %}
+                {% if outer_loop.first or loop.first %}
+                <th>{{ column }}</th>
+                {% else %}
+                <td>{{ column }}</td>
+                {% endif %}
+                {% endfor %}
+            </tr>
+            {% endfor %}
+        </table>
+    </div>
+    {% endif %}
+
+    {% if arch %}
+    <h2 class="title is-4">Architectures</h2>
+    <div class="table-container">
+        <table class="table is-bordered is-striped is-hoverable">
+            {% for row in arch %}
+            {% set outer_loop = loop %}
+            <tr>
+                {% for column in row %}
+                {% if outer_loop.first or loop.first %}
+                <th>{{ column }}</th>
+                {% else %}
+                <td>{{ column }}</td>
+                {% endif %}
+                {% endfor %}
+            </tr>
+            {% endfor %}
+        </table>
+    </div>
+    {% endif %}
+
+    {% if minreq %}
+    <h2 class="title is-4">Minimum Requirements</h2>
+    <div class="table-container">
+        <table class="table is-bordered is-striped is-hoverable">
+            {% for row in minreq %}
+            {% set outer_loop = loop %}
+            <tr>
+                {% for column in row %}
+                {% if outer_loop.first or loop.first %}
+                <th>{{ column }}</th>
+                {% else %}
+                <td>
+                    <ul>
+                        {% for item in column %}
+                        <li>
+                            {{ item }}
+                        </li>
+                        {% endfor %}
+                    </ul>
+                </td>
+                {% endif %}
+                {% endfor %}
+            </tr>
+            {% endfor %}
+        </table>
+    </div>
+</div>
+{% endif %}
\ No newline at end of file
diff --git a/mc_openapi/assets/templates/error.html b/mc_openapi/assets/templates/error.html
new file mode 100644
index 0000000000000000000000000000000000000000..bf76d60a5de0392e59b0f24b2803eae5acbcc525
--- /dev/null
+++ b/mc_openapi/assets/templates/error.html
@@ -0,0 +1,24 @@
+{% extends "base.html" %}
+
+{% block content %}
+
+<h1 class="title">Error</h1>
+<div class="message is-danger">
+    <div class="message-header">
+        <p>
+            An error occurred while validating the DOML
+        </p>
+    </div>
+    <div class="message-body">
+        <h2 class="title is-6 my-2">Description</h2>
+        <pre class="is-family-monospace message-body">{{message}}</pre>
+        <details>
+            <summary class="title is-6 my-2">Debug Message</summary>
+            <pre class="is-family-monospace message-body">
+                {{debug_message}}
+            </pre>
+        </details>
+    </div>
+</div>
+
+{% endblock content %}
\ No newline at end of file
diff --git a/mc_openapi/assets/templates/home.html b/mc_openapi/assets/templates/home.html
new file mode 100644
index 0000000000000000000000000000000000000000..10944849bebc3a32dd9d7d1d04549e14dd04ca6a
--- /dev/null
+++ b/mc_openapi/assets/templates/home.html
@@ -0,0 +1,92 @@
+{% extends "base.html" %}
+
+{% block content %}
+<div class="box">
+    <h1 class="title">DOML Model Checker</h1>
+    <p>Upload a DOMLX file (in PIACERE IDE, <i>Right click > PIACERE > Generate DOMLX</i>) to either validate it with
+        the
+        model checker or the CSP compatibility tool.</p>
+    <br>
+    <div class="columns">
+        <div class="column">
+            <h2 class="subtitle">Model Checker</h2>
+            <div class="file is-boxed">
+                <label class="file-label">
+                    <input class="file-input" type="file" name="resume" id="domlx-mc">
+                    <span class="file-cta">
+                        <span class="file-label">
+                            Choose a file to validate
+                        </span>
+                    </span>
+                </label>
+            </div>
+        </div>
+        <div class="column">
+            <h2 class="subtitle">CSP Compatibility</h2>
+            <div class="file is-boxed">
+                <label class="file-label">
+                    <input class="file-input" type="file" name="resume" id="domlx-csp">
+                    <span class="file-cta">
+                        <span class="file-label">
+                            Choose a file to validate
+                        </span>
+                    </span>
+                </label>
+            </div>
+        </div>
+    </div>
+    <progress id="loading" class="is-hidden progress is-small is-primary" max="100">Loading...</progress>
+    <div id="error" class="notification is-danger is-hidden">
+        There was an issue with the file you uploaded. Is it a DOMLX file?
+        <br>
+        DOML files are not supported!
+    </div>
+</div>
+<script>
+    const input_csp = document.querySelector("#domlx-csp")
+    input_csp.addEventListener('change', readFileCSP, false)
+
+    const input_mc = document.querySelector("#domlx-mc")
+    input_mc.addEventListener('change', readFileMC, false)
+
+    const loadingBar = document.querySelector("#loading")
+    const errorBox = document.querySelector("#error")
+
+    async function readFile(event, url) {
+        const file = event.target.files[0]
+        if (file) {
+            loadingBar.classList.remove("is-hidden")
+            const res = await fetch(url, {
+                method: 'POST',
+                headers: {
+                    "Content-Type": "application/xml",
+                },
+                redirect: "follow",
+                body: await file.text()
+            })
+            if (res.status === 200) {
+                newHtml = await res.text()
+                // Fix escaped quotes for tags
+                // Unescape emojis
+                // See: https://stackoverflow.com/questions/51640509/
+                newHtml = newHtml.replace(/\\u[\dA-F]{4}/gi, function (match) {
+                    return String.fromCharCode(parseInt(match.replace(/\\u/g, ''), 16));
+                })
+                // Remove trailing and heading "
+                document.write(newHtml)
+            } else {
+                loadingBar.classList.add("is-hidden")
+                errorBox.classList.remove("is-hidden")
+            }
+        }
+    }
+
+    async function readFileCSP(event) {
+        readFile(event, '/csp_html')
+    }
+
+    async function readFileMC(event) {
+        readFile(event, '/modelcheck_html')
+    }
+</script>
+{% endblock content %}
\ No newline at end of file
diff --git a/mc_openapi/assets/templates/mc.html b/mc_openapi/assets/templates/mc.html
new file mode 100644
index 0000000000000000000000000000000000000000..019b39595d705c827852170d4a4f68012bb7c913
--- /dev/null
+++ b/mc_openapi/assets/templates/mc.html
@@ -0,0 +1,120 @@
+{% extends "base.html" %}
+
+{% block content %}
+<h1 class="title">DOML Model Checker Results
+    <span class="tags has-addons">
+        <span class="tag is-dark">DOML Version</span>
+        <span class="tag is-info">{{doml_version}}</span>
+    </span>
+</h1>
+<div class="box">
+    <h2 class="title is-4">Result:
+        {% if result == "sat" %}
+        <span class="tag is-success is-medium">Satisfied</span>
+        {% else %}
+        <span class="tag is-danger is-medium">Unsatisfied</span>
+        {% endif %}
+    </h2>
+    <div class="control">
+        <p>Model validated in {{elapsed_time}}s.</p>
+    </div>
+    {% if all_reqs %}
+    <label class="checkbox my-4">
+        <input type="checkbox" id="show-sat-reqs">
+        Show satisfied requirements
+    </label>
+    <ul class="">
+        {% for req in all_reqs %}
+        {% if req.result == "unsat" %}
+        <li class="message is-danger">
+            <div class="message-header">
+                <p>
+                    Unsatisfied ({{req.time}}s)
+                </p>
+                <p>
+                    <span class="tag is-family-monospace is-danger is-light">
+                        {{req.id}}
+                    </span>
+                    <span class="tag is-danger is-light">{{req.type}}</span>
+                </p>
+            </div>
+            <div class="message-body">
+                <h2 class="title is-6 my-2">Description</h2>
+                <p>{{req.description}}</p>
+                <h2 class="title is-6 my-2">Error message:</h2>
+                <p>{{req.message}}</p>
+            </div>
+        </li>
+        {% else %}
+        <li class="message is-success sat-req is-hidden">
+            <div class="message-header">
+                <p>
+                    <span class="tag is-family-monospace is-success is-light">
+                        {{req.id}}
+                    </span>
+                    <span class="tag is-success is-light">{{req.type}}</span>
+                </p>
+                <p>
+                    satisfied ({{req.time}}s)
+                </p>
+            </div>
+            <div class="message-body">
+                <h2 class="title is-6 my-2">Description</h2>
+                <p>{{req.description}}</p>
+            </div>
+        </li>
+        {% endif %}
+        {% endfor %}
+    </ul>
+    {% endif %}
+
+    {% if user %}
+    <h3 class="title is-5">User Requirements</h3>
+    <ul class="">
+        {% for req in user %}
+        <li class="">
+            <h4>{{req[0]}}</h4>
+            <p>{{req[1]}}</p>
+            <ul class="notes">
+                {% for note in req[2] %}
+                <li>{{note}}</li>
+                {% endfor %}
+            </ul>
+        </li>
+        {% endfor %}
+    </ul>
+    {% endif %}
+
+    {% if dontknow %}
+    <article class="message is-warning">
+        <div class="message-header">
+            <p>Timeout!</p>
+        </div>
+        <div class="message-body">
+            There's been a timeout during the validation, so some requirements couldn't be verified.<br>
+            This is not the expected behaviour unless you are using custom requirements or/and very large DOML
+            models.<br>
+            Please report the issue if possible!
+        </div>
+    </article>
+    {% endif %}
+
+    {% if net_validation %}
+    {% include "net.html" %}
+    {% else %}
+    <h3 class="title is-5">Network Validation</h3>
+    No issue detected within the model network configuration.
+    {% endif %}
+</div>
+<script>
+    const checkbox = document.querySelector("#show-sat-reqs")
+    const satReqs = document.querySelectorAll(".sat-req")
+
+    checkbox.addEventListener("click", () => {
+        satReqs.forEach(el => el.classList.toggle('is-hidden'))
+    })
+</script>
+{% if csp %}
+{% include "csp_content.html" %}
+{% endif %}
+{% endblock content %}
\ No newline at end of file
diff --git a/mc_openapi/assets/templates/net.html b/mc_openapi/assets/templates/net.html
new file mode 100644
index 0000000000000000000000000000000000000000..ec8371c861bbd7baae79b25d5d6b707c50e18ab8
--- /dev/null
+++ b/mc_openapi/assets/templates/net.html
@@ -0,0 +1,10 @@
+<h3 class="title is-5">Network Validation</h3>
+<ul>
+    {% for warn in net_validation %}
+    <li class="message">
+        <div class="message-body">
+            {{warn}}
+        </div>
+    </li>
+    {% endfor %}
+</ul>
\ No newline at end of file
diff --git a/mc_openapi/doml_mc/__init__.py b/mc_openapi/doml_mc/__init__.py
index 4bbe1a24dc55d99980d2661e0bcb47d1a011803a..62db218186b30bcc40496d93a14a162c71df83dc 100644
--- a/mc_openapi/doml_mc/__init__.py
+++ b/mc_openapi/doml_mc/__init__.py
@@ -1,5 +1,17 @@
 from .mc import ModelChecker   # noqa: F401
 from .mc_result import MCResult, MCResults   # noqa: F401
+from .intermediate_model.metamodel import DOMLVersion, init_metamodels   # noqa: F401
+from .xmi_parser.doml_model import init_doml_rsets
+from .xmi_parser.special_parsers import init_special_parsers
+from .main import init_model, verify_csp_compatibility, verify_model, synthesize_model
 
-# Load metamodel
-ModelChecker.init_metamodel()
+__all__ = ["ModelChecker", "MCResult", "MCResults", "DOMLVersion"]
+
+# Load metamodels
+init_metamodels()
+
+# Load ecores
+init_doml_rsets()
+
+# Generate SpecialParsers
+init_special_parsers()
diff --git a/mc_openapi/doml_mc/builtin_requirements/__init__.py b/mc_openapi/doml_mc/builtin_requirements/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..3f67bf2dc0630730dc6f61f2c9b6f0698f7025ef
--- /dev/null
+++ b/mc_openapi/doml_mc/builtin_requirements/__init__.py
@@ -0,0 +1,43 @@
+CELEMS_V2_0 = [
+    ("infrastructure_VirtualMachine", "concrete_RuntimeProvider::vms", "concrete_VirtualMachine::maps"),
+    ("infrastructure_VMImage", "concrete_RuntimeProvider::vmImages", "concrete_VMImage::maps"),
+    ("infrastructure_Network", "concrete_RuntimeProvider::networks", "concrete_Network::maps"),
+    ("infrastructure_Storage", "concrete_RuntimeProvider::storages", "concrete_Storage::maps"),
+    ("infrastructure_FunctionAsAService", "concrete_RuntimeProvider::faas","concrete_FunctionAsAService::maps"),
+    ("infrastructure_ComputingGroup", "concrete_RuntimeProvider::group","concrete_ComputingGroup::maps"),
+]
+
+CELEMS_V3_1 = [
+    *CELEMS_V2_0[0:5],
+    ("infrastructure_ComputingGroup", "concrete_RuntimeProvider::autoScalingGroups","concrete_AutoScalingGroup::maps")
+]
+
+from .vm_has_iface import VM_HAS_IFACE, VM_HAS_IFACE_V2_3
+from .software_package_iface_net import SOFTWARE_PACKAGE_IFACE_NET, SOFTWARE_PACKAGE_IFACE_NET_V2_1, SOFTWARE_PACKAGE_IFACE_NET_V2_3, SOFTWARE_PACKAGE_IFACE_NET_V3_1
+from .iface_uniq import IFACE_UNIQ
+from .all_software_components_deployed import ALL_SOFTWARE_COMPONENTS_DEPLOYED
+from .all_infrastructure_elements_deployed import ALL_INFRASTRUCTURE_ELEMENTS_DEPLOYED, ALL_INFRASTRUCTURE_ELEMENTS_DEPLOYED_V3_1
+from .all_concrete_maps_something import ALL_CONCRETE_MAP_SOMETHING, ALL_CONCRETE_MAP_SOMETHING_V3_1
+from .security_group_must_have_iface import SECURITY_GROUP_MUST_HAVE_IFACE, SECURITY_GROUP_MUST_HAVE_IFACE_V3_1
+from .concrete_asg_no_vm import CONCRETE_ASG_NO_VM
+from .vm_os_required import VM_OS_REQUIRED, VM_OS_REQUIRED_V3_1
+
+__ALL__ = [
+    VM_HAS_IFACE,
+    VM_HAS_IFACE_V2_3,
+    SOFTWARE_PACKAGE_IFACE_NET,
+    SOFTWARE_PACKAGE_IFACE_NET_V2_1,
+    SOFTWARE_PACKAGE_IFACE_NET_V2_3,
+    SOFTWARE_PACKAGE_IFACE_NET_V3_1,
+    IFACE_UNIQ,
+    ALL_SOFTWARE_COMPONENTS_DEPLOYED,
+    ALL_INFRASTRUCTURE_ELEMENTS_DEPLOYED,
+    ALL_INFRASTRUCTURE_ELEMENTS_DEPLOYED_V3_1,
+    ALL_CONCRETE_MAP_SOMETHING,
+    ALL_CONCRETE_MAP_SOMETHING_V3_1,
+    SECURITY_GROUP_MUST_HAVE_IFACE,
+    SECURITY_GROUP_MUST_HAVE_IFACE_V3_1,
+    CONCRETE_ASG_NO_VM,
+    VM_OS_REQUIRED,
+    VM_OS_REQUIRED_V3_1
+]
\ No newline at end of file
diff --git a/mc_openapi/doml_mc/builtin_requirements/all_concrete_maps_something.py b/mc_openapi/doml_mc/builtin_requirements/all_concrete_maps_something.py
new file mode 100644
index 0000000000000000000000000000000000000000..01e2f1e7ce243a895b3ef48369ccfc4975c5ce8b
--- /dev/null
+++ b/mc_openapi/doml_mc/builtin_requirements/all_concrete_maps_something.py
@@ -0,0 +1,98 @@
+from z3 import And, Const, Consts, Exists, ExprRef, Not, Or, Solver, Implies
+from mc_openapi.doml_mc.imc import Requirement, SMTEncoding, SMTSorts
+from mc_openapi.doml_mc.intermediate_model import DOMLVersion, IntermediateModel
+from mc_openapi.doml_mc.error_desc_helper import get_user_friendly_name
+from . import CELEMS_V2_0, CELEMS_V3_1
+
+# All elements in the active concretization are mapped to some abstract infrastructure element.
+
+def all_concrete_map_something(smtenc: SMTEncoding, smtsorts: SMTSorts) -> ExprRef:
+    def checkOneClass(ielem, provider, celem, providerAssoc, celemAssoc):
+        return And(
+            smtenc.association_rel(
+                provider, smtenc.associations[providerAssoc], celem),
+            Not(
+                Exists(
+                    [ielem],
+                    smtenc.association_rel(
+                        celem, smtenc.associations[celemAssoc], ielem)
+                )
+            )
+        )
+
+    ielem, concr, provider, celem = Consts(
+       "ielem concr provider celem", smtsorts.element_sort)
+    return And(
+        smtenc.element_class_fun(
+            concr) == smtenc.classes["concrete_ConcreteInfrastructure"],
+        smtenc.association_rel(
+            concr, smtenc.associations["concrete_ConcreteInfrastructure::providers"], provider),
+        Or(
+            *(
+                checkOneClass(
+                    ielem, provider, celem,
+                    providerAssoc, celemAssoc
+                )
+                for _, providerAssoc, celemAssoc in CELEMS_V2_0
+            )
+        )
+    )
+
+def all_concrete_map_something_v3_1(smtenc: SMTEncoding, smtsorts: SMTSorts) -> ExprRef:
+    def checkOneClass(ielem, provider, celem, providerAssoc, celemAssoc):
+        return And(
+            smtenc.association_rel(
+                provider, smtenc.associations[providerAssoc], celem),
+            Not(
+                Exists(
+                    [ielem],
+                    smtenc.association_rel(
+                        celem, smtenc.associations[celemAssoc], ielem)
+                )
+            )
+        )
+
+    ielem, concr, provider, celem = Consts(
+       "ielem concr provider celem", smtsorts.element_sort)
+    return And(
+        smtenc.element_class_fun(
+            concr) == smtenc.classes["concrete_ConcreteInfrastructure"],
+        smtenc.association_rel(
+            concr, smtenc.associations["concrete_ConcreteInfrastructure::providers"], provider),
+        Or(
+            *(
+                checkOneClass(
+                    ielem, provider, celem,
+                    providerAssoc, celemAssoc
+                )
+                for _, providerAssoc, celemAssoc in CELEMS_V3_1
+            )
+        )
+    )
+
+
+def ed_all_concrete_map_something(solver: Solver, smtsorts: SMTSorts, intermediate_model: IntermediateModel) -> str:
+    try:
+        celem = Const("celem", smtsorts.element_sort)
+        celem_name = get_user_friendly_name(
+            intermediate_model, solver.model(), celem)
+        if celem_name:
+            return f"Concrete infrastructure element '{celem_name}' is not mapped to any abstract infrastructure element."
+    except:
+        return "A concrete infrastructure element is not mapped to any abstract infrastructure element."
+
+MSG = "All elements in the active concretization are mapped to some abstract infrastructure element."
+
+ALL_CONCRETE_MAP_SOMETHING = (
+    all_concrete_map_something,
+    "all_concrete_map_something",
+    MSG,
+    ed_all_concrete_map_something
+)
+
+ALL_CONCRETE_MAP_SOMETHING_V3_1 = (
+    all_concrete_map_something_v3_1,
+    "all_concrete_map_something",
+    MSG,
+    ed_all_concrete_map_something
+)
\ No newline at end of file
diff --git a/mc_openapi/doml_mc/builtin_requirements/all_infrastructure_elements_deployed.py b/mc_openapi/doml_mc/builtin_requirements/all_infrastructure_elements_deployed.py
new file mode 100644
index 0000000000000000000000000000000000000000..7e4b4e300caa546a06f9f110de3f34af7d0e8a27
--- /dev/null
+++ b/mc_openapi/doml_mc/builtin_requirements/all_infrastructure_elements_deployed.py
@@ -0,0 +1,167 @@
+from z3 import And, Const, Consts, Exists, ExprRef, Not, Or, Solver, Implies
+from mc_openapi.doml_mc.imc import Requirement, SMTEncoding, SMTSorts
+from mc_openapi.doml_mc.intermediate_model import DOMLVersion, IntermediateModel
+from mc_openapi.doml_mc.error_desc_helper import get_user_friendly_name
+from . import CELEMS_V2_0, CELEMS_V3_1
+
+# Provider > elements generated by IOP only have "commons_DOMLElement::annotations" as an association
+# and do not have maps. Also networks are not generated by the IOP. But they are the same class
+# (concrete_infrastructure), so I can't make distinction.
+
+def all_infrastructure_elements_deployed(smtenc: SMTEncoding, smtsorts: SMTSorts) -> ExprRef:
+    """Checks:
+        - infrastructure_VMImage
+        - infrastructure_Network
+        - infrastructure_Storage
+        - infrastructure_FunctionAsAService
+        - infrastructure_ComputingGroup
+    """
+    def checkOneClass(ielem, cinfr, provider, celem, ielemClass, providerAssoc, celemAssoc):
+        return And(
+            smtenc.element_class_fun(ielem) == smtenc.classes[ielemClass],
+            Not(
+                Exists(
+                    [provider, celem],
+                    And(
+                        smtenc.association_rel(
+                            cinfr, smtenc.associations["concrete_ConcreteInfrastructure::providers"], provider),
+                        smtenc.association_rel(
+                            provider, smtenc.associations[providerAssoc], celem),
+                        smtenc.association_rel(
+                            celem, smtenc.associations[celemAssoc], ielem)
+                    )
+                )
+            )
+        )
+
+    ielem, concr, provider, celem, asg = Consts("ielem concr provider celem asg", smtsorts.element_sort)
+    return And(
+        smtenc.element_class_fun(
+            concr) == smtenc.classes["concrete_ConcreteInfrastructure"],
+        Or(
+            *(
+                checkOneClass(
+                    ielem, concr, provider, celem,
+                    ielemClass, providerAssoc, celemAssoc
+                ) 
+                for ielemClass, providerAssoc, celemAssoc in CELEMS_V2_0
+                if ielemClass != 'infrastructure_VirtualMachine' # handle special case separately in concrete_asg_no_vm and below
+            ),
+            And(
+                smtenc.element_class_fun(ielem) == smtenc.classes["infrastructure_VirtualMachine"],
+                Not(Exists([asg],
+                    Or(
+                        smtenc.association_rel(
+                            asg, smtenc.associations["infrastructure_AutoScalingGroup::machineDefinition"], ielem),
+                        Exists(
+                            [provider, celem],
+                            And(
+                                smtenc.association_rel(
+                                    concr, smtenc.associations["concrete_ConcreteInfrastructure::providers"], provider),
+                                smtenc.association_rel(
+                                    provider, smtenc.associations["concrete_RuntimeProvider::vms"], celem),
+                                smtenc.association_rel(
+                                    celem, smtenc.associations["concrete_VirtualMachine::maps"], ielem)
+                            )
+                        )
+                    )
+                ))
+            )
+        )
+    )
+
+def all_infrastructure_elements_deployed_v3_1(smtenc: SMTEncoding, smtsorts: SMTSorts) -> ExprRef:
+    def checkOneClass(ielem, cinfr, provider, celem, ielemClass, providerAssoc, celemAssoc):
+        return And(
+            smtenc.element_class_fun(ielem) == smtenc.classes[ielemClass],
+            Not(
+                Exists(
+                    [provider, celem],
+                    And(
+                        smtenc.association_rel(
+                            cinfr, smtenc.associations["concrete_ConcreteInfrastructure::providers"], provider),
+                        smtenc.association_rel(
+                            provider, smtenc.associations[providerAssoc], celem),
+                        smtenc.association_rel(
+                            celem, smtenc.associations[celemAssoc], ielem)
+                    )
+                )
+            )
+        )
+
+    ielem, concr, provider, celem, net, asg = Consts("ielem concr provider celem net asg", smtsorts.element_sort)
+    return And(
+        smtenc.element_class_fun(
+            concr) == smtenc.classes["concrete_ConcreteInfrastructure"],
+        Or(
+            *(
+                checkOneClass(
+                    ielem, concr, provider, celem,
+                    ielemClass, providerAssoc, celemAssoc
+                ) 
+                for ielemClass, providerAssoc, celemAssoc in CELEMS_V3_1
+                if ielemClass != 'infrastructure_VirtualMachine' # handle special case separately in concrete_asg_no_vm and below
+            ),
+            And(
+                smtenc.element_class_fun(ielem) == smtenc.classes["infrastructure_VirtualMachine"],
+                Not(Exists([asg],
+                    Or(
+                        smtenc.association_rel(
+                            asg, smtenc.associations["infrastructure_AutoScalingGroup::machineDefinition"], ielem),
+                        Exists(
+                            [provider, celem],
+                            And(
+                                smtenc.association_rel(
+                                    concr, smtenc.associations["concrete_ConcreteInfrastructure::providers"], provider),
+                                smtenc.association_rel(
+                                    provider, smtenc.associations["concrete_RuntimeProvider::vms"], celem),
+                                smtenc.association_rel(
+                                    celem, smtenc.associations["concrete_VirtualMachine::maps"], ielem)
+                            )
+                        )
+                    )
+                ))
+            ),
+            And(
+                smtenc.element_class_fun(ielem) == smtenc.classes["infrastructure_Subnet"],
+                Not(Exists([provider, net, celem],
+                    And(
+                        smtenc.association_rel(
+                            concr, smtenc.associations["concrete_ConcreteInfrastructure::providers"], provider),
+                        smtenc.association_rel(
+                            provider, smtenc.associations["concrete_RuntimeProvider::networks"], net),
+                        smtenc.association_rel(
+                            net, smtenc.associations["concrete_Network::subnets"], celem),
+                        smtenc.association_rel(
+                            celem, smtenc.associations["concrete_Network::maps"], ielem)
+                    )
+                ))
+            )
+        )
+    )
+
+def ed_all_infrastructure_elements_deployed(solver: Solver, smtsorts: SMTSorts, intermediate_model: IntermediateModel) -> str:
+    try:
+        ielem = Const("ielem", smtsorts.element_sort)
+        ielem_name = get_user_friendly_name(
+            intermediate_model, solver.model(), ielem)
+        if ielem_name:
+            return f"Abstract infrastructure element '{ielem_name}' is not mapped to any element in the active concretization."
+    except:
+        return "An abstract infrastructure element has is not mapped to any element in the active concretization."
+
+MSG = "All abstract infrastructure elements are mapped to an element in the active concretization."
+
+ALL_INFRASTRUCTURE_ELEMENTS_DEPLOYED = (
+    all_infrastructure_elements_deployed,
+    "all_infrastructure_elements_deployed",
+    MSG,
+    ed_all_infrastructure_elements_deployed
+)
+
+ALL_INFRASTRUCTURE_ELEMENTS_DEPLOYED_V3_1 = (
+    all_infrastructure_elements_deployed_v3_1,
+    "all_infrastructure_elements_deployed",
+    MSG,
+    ed_all_infrastructure_elements_deployed
+)
\ No newline at end of file
diff --git a/mc_openapi/doml_mc/builtin_requirements/all_software_components_deployed.py b/mc_openapi/doml_mc/builtin_requirements/all_software_components_deployed.py
new file mode 100644
index 0000000000000000000000000000000000000000..a10d5025a6df3aa63107bf6393f107e8670b4813
--- /dev/null
+++ b/mc_openapi/doml_mc/builtin_requirements/all_software_components_deployed.py
@@ -0,0 +1,43 @@
+from z3 import And, Const, Consts, Exists, ExprRef, Not, Or, Solver, Implies
+from mc_openapi.doml_mc.imc import Requirement, SMTEncoding, SMTSorts
+from mc_openapi.doml_mc.intermediate_model import DOMLVersion, IntermediateModel
+from mc_openapi.doml_mc.error_desc_helper import get_user_friendly_name
+
+# All software components have been deployed to some node.
+
+def all_software_components_deployed(smtenc: SMTEncoding, smtsorts: SMTSorts) -> ExprRef:
+    sc, deployment, ielem = Consts("sc deployment ielem", smtsorts.element_sort)
+    return And(
+        smtenc.element_class_fun(
+            sc) == smtenc.classes["application_SoftwareComponent"],
+        Not(
+            Exists(
+                [deployment, ielem],
+                And(
+                    smtenc.association_rel(
+                        deployment, smtenc.associations["commons_Deployment::component"], sc),
+                    smtenc.association_rel(
+                        deployment, smtenc.associations["commons_Deployment::node"], ielem),
+                )
+            )
+        )
+    )
+
+def ed_all_software_components_deployed(solver: Solver, smtsorts: SMTSorts, intermediate_model: IntermediateModel) -> str:
+    try:
+        sc = Const("sc", smtsorts.element_sort)
+        sc_name = get_user_friendly_name(
+            intermediate_model, solver.model(), sc)
+        if sc_name:
+            return f"Software component '{sc_name}' is not deployed to any abstract infrastructure node."
+    except:
+        return "A software component is not deployed to any abstract infrastructure node."
+
+MSG = "All software components have been deployed to some node."
+
+ALL_SOFTWARE_COMPONENTS_DEPLOYED = (
+    all_software_components_deployed,
+    "all_software_components_deployed",
+    MSG,
+    ed_all_software_components_deployed
+)
\ No newline at end of file
diff --git a/mc_openapi/doml_mc/builtin_requirements/concrete_asg_no_vm.py b/mc_openapi/doml_mc/builtin_requirements/concrete_asg_no_vm.py
new file mode 100644
index 0000000000000000000000000000000000000000..445e8e9d13c3fb98fc73bf54acf022f763f6c16e
--- /dev/null
+++ b/mc_openapi/doml_mc/builtin_requirements/concrete_asg_no_vm.py
@@ -0,0 +1,43 @@
+from z3 import And, Const, Consts, Exists, ExprRef, Not, Or, Solver, Implies
+from mc_openapi.doml_mc.imc import Requirement, SMTEncoding, SMTSorts
+from mc_openapi.doml_mc.intermediate_model import DOMLVersion, IntermediateModel
+from mc_openapi.doml_mc.error_desc_helper import get_user_friendly_name
+
+def concrete_asg_no_vm(smtenc: SMTEncoding, smtsorts: SMTSorts) -> ExprRef:
+    ielem, concr, provider, celem, asg = Consts("ielem concr provider celem asg", smtsorts.element_sort)
+    return And(
+        smtenc.element_class_fun(
+            concr) == smtenc.classes["concrete_ConcreteInfrastructure"],
+        # We don't want the following to happen:
+        # If exists ASG(infr) -> VM(infr), then exists a VM(concr) -> VM(infr) 
+        And(
+            smtenc.element_class_fun(ielem) == smtenc.classes["infrastructure_VirtualMachine"],
+            smtenc.association_rel(
+                asg, smtenc.associations["infrastructure_AutoScalingGroup::machineDefinition"], ielem),
+            (Exists(
+                [celem],
+                smtenc.association_rel(celem, smtenc.associations["concrete_VirtualMachine::maps"], ielem)
+            ))
+        )
+    )
+
+
+def ed_concrete_asg_no_vm(solver: Solver, smtsorts: SMTSorts, intermediate_model: IntermediateModel) -> str:
+    try:
+        ielem = Const("ielem", smtsorts.element_sort)
+        asg = Const("asg", smtsorts.element_sort)
+        ielem_name = get_user_friendly_name(
+            intermediate_model, solver.model(), ielem)
+        if ielem_name:
+            return f"Virtual machine '{ielem_name}' in AutoScale Group '{asg}' should not be present in the concretization layer."
+    except:
+        return "Any virtual machine in an AutoScale Group should not be present in the concretization layer."
+
+MSG = "All virtual machines in an autoscale group in the infrastructure layer should not be mapped in the concretization layer."
+
+CONCRETE_ASG_NO_VM = (
+    concrete_asg_no_vm,
+    "concrete_asg_no_vm",
+    MSG,
+    ed_concrete_asg_no_vm
+)
\ No newline at end of file
diff --git a/mc_openapi/doml_mc/builtin_requirements/iface_uniq.py b/mc_openapi/doml_mc/builtin_requirements/iface_uniq.py
new file mode 100644
index 0000000000000000000000000000000000000000..669c8d0dedaa09b8673db74cd7d21d16bdb7cd62
--- /dev/null
+++ b/mc_openapi/doml_mc/builtin_requirements/iface_uniq.py
@@ -0,0 +1,35 @@
+from z3 import And, Const, Consts, Exists, ExprRef, Not, Or, Solver, Implies
+from mc_openapi.doml_mc.imc import Requirement, SMTEncoding, SMTSorts
+from mc_openapi.doml_mc.intermediate_model import DOMLVersion, IntermediateModel
+from mc_openapi.doml_mc.error_desc_helper import get_user_friendly_name
+
+# There are no duplicated interfaces.
+def iface_uniq(smtenc: SMTEncoding, smtsorts: SMTSorts) -> ExprRef:
+    endPointAttr = smtenc.attributes["infrastructure_NetworkInterface::endPoint"]
+    ni1, ni2 = Consts("ni1 ni2", smtsorts.element_sort)
+    value = Const("value", smtsorts.attr_data_sort)
+    return And(
+        smtenc.attribute_rel(ni1, endPointAttr, value),
+        smtenc.attribute_rel(ni2, endPointAttr, value),
+        ni1 != ni2,
+    )
+
+def ed_iface_uniq(solver: Solver, smtsorts: SMTSorts, intermediate_model: IntermediateModel) -> str:
+    try:
+        ni1, ni2 = Consts("ni1 ni2", smtsorts.element_sort)
+        model = solver.model()
+        ni1_name = get_user_friendly_name(intermediate_model, model, ni1)
+        ni2_name = get_user_friendly_name(intermediate_model, model, ni2)
+        if ni1_name and ni2_name:
+            return f"Network interfaces '{ni1_name}' and '{ni2_name}' share the same IP address."
+    except:
+        return "Two network interfaces share the same IP address."
+
+MSG = "There are no duplicated interfaces."
+
+IFACE_UNIQ = (
+    iface_uniq,
+    "iface_uniq",
+    MSG,
+    ed_iface_uniq
+)
\ No newline at end of file
diff --git a/mc_openapi/doml_mc/builtin_requirements/security_group_must_have_iface.py b/mc_openapi/doml_mc/builtin_requirements/security_group_must_have_iface.py
new file mode 100644
index 0000000000000000000000000000000000000000..6e9cbabf07ee335e565146c45d66e5145239f61c
--- /dev/null
+++ b/mc_openapi/doml_mc/builtin_requirements/security_group_must_have_iface.py
@@ -0,0 +1,61 @@
+from z3 import And, Const, Consts, Exists, ExprRef, Not, Or, Solver, Implies
+from mc_openapi.doml_mc.imc import Requirement, SMTEncoding, SMTSorts
+from mc_openapi.doml_mc.intermediate_model import DOMLVersion, IntermediateModel
+from mc_openapi.doml_mc.error_desc_helper import get_user_friendly_name
+
+# From DOML V2.3+:
+# The association between security groups and network interfaces can now be done only
+# in the security groups definition through the “ifaces” keyword (removed the "security"
+# keyword in the network interface definition)
+def security_group_must_have_iface(smtenc: SMTEncoding, smtsorts: SMTSorts) -> ExprRef:
+    sg, iface = Consts("sg iface", smtsorts.element_sort)
+    return And(
+        smtenc.element_class_fun(
+            sg) == smtenc.classes["infrastructure_SecurityGroup"],
+        Not(Exists([iface],
+            smtenc.association_rel(
+                iface, smtenc.associations["infrastructure_NetworkInterface::associated"], sg)
+        ))
+    )
+
+def security_group_must_have_iface_v3_1(smtenc: SMTEncoding, smtsorts: SMTSorts) -> ExprRef:
+    sg, elem = Consts("sg elem", smtsorts.element_sort)
+    return And(
+        smtenc.element_class_fun(
+            sg) == smtenc.classes["infrastructure_SecurityGroup"],
+        Not(Exists([elem],
+            Or(
+                smtenc.association_rel(
+                    elem, smtenc.associations["infrastructure_NetworkInterface::associated"], sg),
+                smtenc.association_rel(
+                    elem, smtenc.associations["infrastructure_ExecutionEnvironment::securityGroups"], sg)
+            )
+        ))
+    )
+
+
+def ed_security_group_must_have_iface(solver: Solver, smtsorts: SMTSorts, intermediate_model: IntermediateModel) -> str:
+    try:
+        sg = Const("sg", smtsorts.element_sort)
+        sg_name = get_user_friendly_name(
+            intermediate_model, solver.model(), sg)
+        if sg_name:
+            return f"Security group '{sg_name}' is not associated with any network interface. You should probably remove it."
+    except:
+        return "A security group is not associated with any element. You should probably remove it."
+
+MSG = "All security group should be a associated to an element."
+
+SECURITY_GROUP_MUST_HAVE_IFACE = (
+    security_group_must_have_iface,
+    "security_group_must_have_iface",
+    MSG,
+    ed_security_group_must_have_iface
+)
+
+SECURITY_GROUP_MUST_HAVE_IFACE_V3_1 = (
+    security_group_must_have_iface_v3_1,
+    "security_group_must_have_iface",
+    MSG,
+    ed_security_group_must_have_iface
+)
\ No newline at end of file
diff --git a/mc_openapi/doml_mc/builtin_requirements/software_package_iface_net.py b/mc_openapi/doml_mc/builtin_requirements/software_package_iface_net.py
new file mode 100644
index 0000000000000000000000000000000000000000..e570717bb4833641014f7076d0ae94f2c625ad3b
--- /dev/null
+++ b/mc_openapi/doml_mc/builtin_requirements/software_package_iface_net.py
@@ -0,0 +1,710 @@
+from z3 import And, Const, Consts, Exists, ExprRef, Not, Or, Solver, Implies
+from mc_openapi.doml_mc.imc import Requirement, SMTEncoding, SMTSorts
+from mc_openapi.doml_mc.intermediate_model import DOMLVersion, IntermediateModel
+from mc_openapi.doml_mc.error_desc_helper import get_user_friendly_name
+
+# All software packages can see the interfaces they need through a common network.
+
+def software_package_iface_net(smtenc: SMTEncoding, smtsorts: SMTSorts) -> ExprRef:
+    asc_consumer, asc_exposer, siface, net, net_iface, cnode, cdeployment, enode, edeployment, vm, csubnet, esubnet = Consts(
+        "asc_consumer asc_exposer siface net net_iface cnode cdeployment enode edeployment vm csubnet esubnet", smtsorts.element_sort
+    )
+    return And(
+        smtenc.association_rel(
+            asc_consumer, smtenc.associations["application_SoftwareComponent::exposedInterfaces"], siface),
+        smtenc.association_rel(
+            asc_exposer, smtenc.associations["application_SoftwareComponent::consumedInterfaces"], siface),
+        Not(
+            Or(
+                Exists(
+                    [cdeployment, cnode, edeployment, enode, net],
+                    And(
+                        smtenc.association_rel(
+                            cdeployment, smtenc.associations["commons_Deployment::component"], asc_consumer),
+                        smtenc.association_rel(
+                            cdeployment, smtenc.associations["commons_Deployment::node"], cnode),
+                        Exists(
+                            [vm, net_iface],
+                            Or(
+                                And(  # asc_consumer is deployed on a component with an interface in network n
+                                    smtenc.association_rel(
+                                        cnode, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface),
+                                    smtenc.association_rel(
+                                        net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net),
+                                ),
+                                And(  # asc_consumer is deployed on a container hosted in a VM with an interface in network n
+                                    smtenc.association_rel(
+                                        cnode, smtenc.associations["infrastructure_Container::hosts"], vm),
+                                    smtenc.association_rel(
+                                        vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface),
+                                    smtenc.association_rel(
+                                        net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net),
+                                ),
+                                And(  # asc_consumer is deployed on a VM in an AutoScalingGroup with an interface in network n
+                                    smtenc.association_rel(
+                                        cnode, smtenc.associations["infrastructure_AutoScalingGroup::machineDefinition"], vm),
+                                    smtenc.association_rel(
+                                        vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface),
+                                    smtenc.association_rel(
+                                        net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net),
+                                ),
+                            )
+                        ),
+                        smtenc.association_rel(
+                            edeployment, smtenc.associations["commons_Deployment::component"], asc_exposer),
+                        smtenc.association_rel(
+                            edeployment, smtenc.associations["commons_Deployment::node"], enode),
+                        Exists(
+                            [vm, net_iface],
+                            Or(
+                                And(  # asc_exposer is deployed on a component with an interface in network n
+                                    # ASC_EXPLORER > CN > IFACE > NET
+                                    smtenc.association_rel(
+                                        enode, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface),
+                                    smtenc.association_rel(
+                                        net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net),
+                                ),
+                                And(  # asc_exposer is deployed on a container hosted on a VM with an interface in network n
+                                    # ASC_EXPOSER > CONTAINER > CN > IFACE > NET
+                                    smtenc.association_rel(
+                                        enode, smtenc.associations["infrastructure_Container::hosts"], vm),
+                                    smtenc.association_rel(
+                                        vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface),
+                                    smtenc.association_rel(
+                                        net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net),
+                                ),
+                                And(  # asc_exposer is deployed on a VM in an AutoScalingGroup with an interface in network n
+                                    # ASC_EXPLORER > ASG > CN > IFACE > NET
+                                    smtenc.association_rel(
+                                        enode, smtenc.associations["infrastructure_AutoScalingGroup::machineDefinition"], vm),
+                                    smtenc.association_rel(
+                                        vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface),
+                                    smtenc.association_rel(
+                                        net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net),
+                                ),
+                            )
+                        )
+                    )
+                ),  #  OR
+                Exists(
+                    [cdeployment, cnode, edeployment, enode, csubnet, esubnet],
+                    And(
+                        smtenc.association_rel(
+                            cdeployment, smtenc.associations["commons_Deployment::component"], asc_consumer),
+                        smtenc.association_rel(
+                            cdeployment, smtenc.associations["commons_Deployment::node"], cnode),
+                        Or(
+                            smtenc.association_rel(
+                                csubnet, smtenc.associations["infrastructure_Subnet::connectedTo"], esubnet),
+                            smtenc.association_rel(
+                                esubnet, smtenc.associations["infrastructure_Subnet::connectedTo"], csubnet),
+                        ),
+                        Exists(
+                            [vm, net_iface],
+                            Or(
+                                And(  # asc_consumer is deployed on a component with an interface in network n
+                                    # ASC_CONSUMER > CN > IFACE > csubnet
+                                    smtenc.association_rel(
+                                        cnode, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface),
+                                    smtenc.association_rel(
+                                        net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], csubnet),
+                                ),
+                                And(  # asc_consumer is deployed on a container hosted in a VM with an interface in network n
+                                    # ASC_CONSUMER > CONTAINER > CN > IFACE > csubnet
+                                    smtenc.association_rel(
+                                        cnode, smtenc.associations["infrastructure_Container::hosts"], vm),
+                                    smtenc.association_rel(
+                                        vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface),
+                                    smtenc.association_rel(
+                                        net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], csubnet),
+                                ),
+                                And(  # asc_consumer is deployed on a VM in an AutoScalingGroup with an interface in network n
+                                    # ASC_CONSUMER > ASG > CN > IFACE > csubnet
+                                    smtenc.association_rel(
+                                        cnode, smtenc.associations["infrastructure_AutoScalingGroup::machineDefinition"], vm),
+                                    smtenc.association_rel(
+                                        vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface),
+                                    smtenc.association_rel(
+                                        net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], csubnet),
+                                ),
+                            )
+                        ),
+                        smtenc.association_rel(
+                            edeployment, smtenc.associations["commons_Deployment::component"], asc_exposer),
+                        smtenc.association_rel(
+                            edeployment, smtenc.associations["commons_Deployment::node"], enode),
+                        Exists(
+                            [vm, net_iface],
+                            Or(
+                                And(  # asc_exposer is deployed on a component with an interface in network n
+                                    # ASC_EXPOSER > CN > IFACE > esubnet
+                                    smtenc.association_rel(
+                                        enode, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface),
+                                    smtenc.association_rel(
+                                        net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], esubnet),
+                                ),
+                                And(  # asc_exposer is deployed on a container hosted on a VM with an interface in network n
+                                    # ASC_EXPOSER > CONTAINER > CN > IFACE > esubnet
+                                    smtenc.association_rel(
+                                        enode, smtenc.associations["infrastructure_Container::hosts"], vm),
+                                    smtenc.association_rel(
+                                        vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface),
+                                    smtenc.association_rel(
+                                        net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], esubnet),
+                                ),
+                                And(  # asc_exposer is deployed on a VM in an AutoScalingGroup with an interface in network n
+                                    # ASC_EXPLORER > ASG > CN > IFACE > esubnet
+                                    smtenc.association_rel(
+                                        enode, smtenc.associations["infrastructure_AutoScalingGroup::machineDefinition"], vm),
+                                    smtenc.association_rel(
+                                        vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface),
+                                    smtenc.association_rel(
+                                        net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], esubnet),
+                                )
+                            )
+                        )
+                    )
+                )
+            )
+        )
+    )
+
+def software_package_iface_net_v2_1(smtenc: SMTEncoding, smtsorts: SMTSorts) -> ExprRef:
+    asc_consumer, asc_exposer, siface, net, net_iface, cnode, cdeployment, enode, edeployment, vm, cconf, csubnet, esubnet = Consts(
+        "asc_consumer asc_exposer siface net net_iface cnode cdeployment enode edeployment vm cconf csubnet esubnet", smtsorts.element_sort
+    )
+    return And(
+        smtenc.association_rel(
+            asc_consumer, smtenc.associations["application_SoftwareComponent::exposedInterfaces"], siface),
+        smtenc.association_rel(
+            asc_exposer, smtenc.associations["application_SoftwareComponent::consumedInterfaces"], siface),
+        Not(
+            Or(
+                Exists(
+                    [cdeployment, cnode, edeployment, enode, net],
+                    And(
+                        smtenc.association_rel(
+                            cdeployment, smtenc.associations["commons_Deployment::component"], asc_consumer),
+                        smtenc.association_rel(
+                            cdeployment, smtenc.associations["commons_Deployment::node"], cnode),
+                        Exists(
+                            [vm, net_iface, cconf],
+                            Or(
+                                And(  # asc_consumer is deployed on a component with an interface in network n
+                                    smtenc.association_rel(
+                                        cnode, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface),
+                                    smtenc.association_rel(
+                                        net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net),
+                                ),
+                                And(  # asc_consumer is deployed on a container hosted in a VM with an interface in network n
+                                    smtenc.association_rel(
+                                        cnode, smtenc.associations["infrastructure_Container::configs"], cconf),
+                                    smtenc.association_rel(
+                                        cconf, smtenc.associations["infrastructure_ContainerConfig::host"], vm),
+                                    smtenc.association_rel(
+                                        vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface),
+                                    smtenc.association_rel(
+                                        net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net),
+                                ),
+                                And(  # asc_consumer is deployed on a VM in an AutoScalingGroup with an interface in network n
+                                    smtenc.association_rel(
+                                        cnode, smtenc.associations["infrastructure_AutoScalingGroup::machineDefinition"], vm),
+                                    smtenc.association_rel(
+                                        vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface),
+                                    smtenc.association_rel(
+                                        net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net),
+                                ),
+                            )
+                        ),
+                        smtenc.association_rel(
+                            edeployment, smtenc.associations["commons_Deployment::component"], asc_exposer),
+                        smtenc.association_rel(
+                            edeployment, smtenc.associations["commons_Deployment::node"], enode),
+                        Exists(
+                            [vm, net_iface, cconf],
+                            Or(
+                                And(  # asc_exposer is deployed on a component with an interface in network n
+                                    smtenc.association_rel(
+                                        enode, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface),
+                                    smtenc.association_rel(
+                                        net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net),
+                                ),
+                                And(  # asc_exposer is deployed on a container hosted on a VM with an interface in network n
+                                    smtenc.association_rel(
+                                        enode, smtenc.associations["infrastructure_Container::configs"], cconf),
+                                    smtenc.association_rel(
+                                        cconf, smtenc.associations["infrastructure_ContainerConfig::host"], vm),
+                                    smtenc.association_rel(
+                                        vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface),
+                                    smtenc.association_rel(
+                                        net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net),
+                                ),
+                                And(  # asc_exposer is deployed on a VM in an AutoScalingGroup with an interface in network n
+                                    smtenc.association_rel(
+                                        enode, smtenc.associations["infrastructure_AutoScalingGroup::machineDefinition"], vm),
+                                    smtenc.association_rel(
+                                        vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface),
+                                    smtenc.association_rel(
+                                        net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net),
+                                ),
+                            )
+                        )
+                    )
+                ),  # OR
+                Exists(
+                    [cdeployment, cnode, edeployment, enode, csubnet, esubnet],
+                    And(
+                        smtenc.association_rel(
+                            cdeployment, smtenc.associations["commons_Deployment::component"], asc_consumer),
+                        smtenc.association_rel(
+                            cdeployment, smtenc.associations["commons_Deployment::node"], cnode),
+                        Or(
+                            smtenc.association_rel(
+                                csubnet, smtenc.associations["infrastructure_Subnet::connectedTo"], esubnet),
+                            smtenc.association_rel(
+                                esubnet, smtenc.associations["infrastructure_Subnet::connectedTo"], csubnet),
+                        ),
+                        Exists(
+                            [vm, net_iface, cconf],
+                            Or(
+                                And(  # asc_consumer is deployed on a component with an interface in network n
+                                    smtenc.association_rel(
+                                        cnode, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface),
+                                    smtenc.association_rel(
+                                        net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], csubnet),
+                                ),
+                                And(  # asc_consumer is deployed on a container hosted in a VM with an interface in network n
+                                    smtenc.association_rel(
+                                        cnode, smtenc.associations["infrastructure_Container::configs"], cconf),
+                                    smtenc.association_rel(
+                                        cconf, smtenc.associations["infrastructure_ContainerConfig::host"], vm),
+                                    smtenc.association_rel(
+                                        vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface),
+                                    smtenc.association_rel(
+                                        net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], csubnet),
+                                ),
+                                And(  # asc_consumer is deployed on a VM in an AutoScalingGroup with an interface in network n
+                                    smtenc.association_rel(
+                                        cnode, smtenc.associations["infrastructure_AutoScalingGroup::machineDefinition"], vm),
+                                    smtenc.association_rel(
+                                        vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface),
+                                    smtenc.association_rel(
+                                        net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], csubnet),
+                                ),
+                            )
+                        ),
+                        smtenc.association_rel(
+                            edeployment, smtenc.associations["commons_Deployment::component"], asc_exposer),
+                        smtenc.association_rel(
+                            edeployment, smtenc.associations["commons_Deployment::node"], enode),
+                        Exists(
+                            [vm, net_iface, cconf],
+                            Or(
+                                And(  # asc_exposer is deployed on a component with an interface in network n
+                                    smtenc.association_rel(
+                                        enode, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface),
+                                    smtenc.association_rel(
+                                        net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], esubnet),
+                                ),
+                                And(  # asc_exposer is deployed on a container hosted on a VM with an interface in network n
+                                    smtenc.association_rel(
+                                        enode, smtenc.associations["infrastructure_Container::configs"], cconf),
+                                    smtenc.association_rel(
+                                        cconf, smtenc.associations["infrastructure_ContainerConfig::host"], vm),
+                                    smtenc.association_rel(
+                                        vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface),
+                                    smtenc.association_rel(
+                                        net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], esubnet),
+                                ),
+                                And(  # asc_exposer is deployed on a VM in an AutoScalingGroup with an interface in network n
+                                    smtenc.association_rel(
+                                        enode, smtenc.associations["infrastructure_AutoScalingGroup::machineDefinition"], vm),
+                                    smtenc.association_rel(
+                                        vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface),
+                                    smtenc.association_rel(
+                                        net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], esubnet),
+                                )
+                            )
+                        )
+                    )
+                )
+            )
+        )
+    )
+
+def software_package_iface_net_v2_3(smtenc: SMTEncoding, smtsorts: SMTSorts) -> ExprRef:
+    asc_consumer, asc_exposer, siface, net, net_iface, cnode, cdeployment, enode, edeployment, vm, cconf, csubnet, esubnet = Consts(
+        "asc_consumer asc_exposer siface net net_iface cnode cdeployment enode edeployment vm cconf csubnet esubnet", smtsorts.element_sort
+    )
+    return And(
+        smtenc.association_rel(
+            asc_consumer, smtenc.associations["application_SoftwareComponent::exposedInterfaces"], siface),
+        smtenc.association_rel(
+            asc_exposer, smtenc.associations["application_SoftwareComponent::consumedInterfaces"], siface),
+        Not(
+            Or(
+                Exists(
+                    [cdeployment, cnode, edeployment, enode, net],
+                    And(
+                        smtenc.association_rel(
+                            cdeployment, smtenc.associations["commons_Deployment::component"], asc_consumer),
+                        smtenc.association_rel(
+                            cdeployment, smtenc.associations["commons_Deployment::node"], cnode),
+                        Exists(
+                            [vm, net_iface, cconf],
+                            Or(
+                                And(  # asc_consumer is deployed on a component with an interface in network n
+                                    smtenc.association_rel(
+                                        cnode, smtenc.associations["infrastructure_Node::ifaces"], net_iface),
+                                    smtenc.association_rel(
+                                        net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net),
+                                ),
+                                And(  # asc_consumer is deployed on a container hosted in a VM with an interface in network n
+                                    smtenc.association_rel(
+                                        cnode, smtenc.associations["infrastructure_Container::configs"], cconf),
+                                    smtenc.association_rel(
+                                        cconf, smtenc.associations["infrastructure_ContainerConfig::host"], vm),
+                                    smtenc.association_rel(
+                                        vm, smtenc.associations["infrastructure_Node::ifaces"], net_iface),
+                                    smtenc.association_rel(
+                                        net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net),
+                                ),
+                                And(  # asc_consumer is deployed on a VM in an AutoScalingGroup with an interface in network n
+                                    smtenc.association_rel(
+                                        cnode, smtenc.associations["infrastructure_AutoScalingGroup::machineDefinition"], vm),
+                                    smtenc.association_rel(
+                                        vm, smtenc.associations["infrastructure_Node::ifaces"], net_iface),
+                                    smtenc.association_rel(
+                                        net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net),
+                                ),
+                            )
+                        ),
+                        smtenc.association_rel(
+                            edeployment, smtenc.associations["commons_Deployment::component"], asc_exposer),
+                        smtenc.association_rel(
+                            edeployment, smtenc.associations["commons_Deployment::node"], enode),
+                        Exists(
+                            [vm, net_iface, cconf],
+                            Or(
+                                And(  # asc_exposer is deployed on a component with an interface in network n
+                                    smtenc.association_rel(
+                                        enode, smtenc.associations["infrastructure_Node::ifaces"], net_iface),
+                                    smtenc.association_rel(
+                                        net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net),
+                                ),
+                                And(  # asc_exposer is deployed on a container hosted on a VM with an interface in network n
+                                    smtenc.association_rel(
+                                        enode, smtenc.associations["infrastructure_Container::configs"], cconf),
+                                    smtenc.association_rel(
+                                        cconf, smtenc.associations["infrastructure_ContainerConfig::host"], vm),
+                                    smtenc.association_rel(
+                                        vm, smtenc.associations["infrastructure_Node::ifaces"], net_iface),
+                                    smtenc.association_rel(
+                                        net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net),
+                                ),
+                                And(  # asc_exposer is deployed on a VM in an AutoScalingGroup with an interface in network n
+                                    smtenc.association_rel(
+                                        enode, smtenc.associations["infrastructure_AutoScalingGroup::machineDefinition"], vm),
+                                    smtenc.association_rel(
+                                        vm, smtenc.associations["infrastructure_Node::ifaces"], net_iface),
+                                    smtenc.association_rel(
+                                        net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net),
+                                ),
+                            )
+                        )
+                    )
+                ),  # OR
+                Exists(
+                    [cdeployment, cnode, edeployment, enode, csubnet, esubnet],
+                    And(
+                        smtenc.association_rel(
+                            cdeployment, smtenc.associations["commons_Deployment::component"], asc_consumer),
+                        smtenc.association_rel(
+                            cdeployment, smtenc.associations["commons_Deployment::node"], cnode),
+                        Or(
+                            smtenc.association_rel(
+                                csubnet, smtenc.associations["infrastructure_Subnet::connectedTo"], esubnet),
+                            smtenc.association_rel(
+                                esubnet, smtenc.associations["infrastructure_Subnet::connectedTo"], csubnet),
+                        ),
+                        Exists(
+                            [vm, net_iface, cconf],
+                            Or(
+                                And(  # asc_consumer is deployed on a component with an interface in network n
+                                    smtenc.association_rel(
+                                        cnode, smtenc.associations["infrastructure_Node::ifaces"], net_iface),
+                                    smtenc.association_rel(
+                                        net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], csubnet),
+                                ),
+                                And(  # asc_consumer is deployed on a container hosted in a VM with an interface in network n
+                                    smtenc.association_rel(
+                                        cnode, smtenc.associations["infrastructure_Container::configs"], cconf),
+                                    smtenc.association_rel(
+                                        cconf, smtenc.associations["infrastructure_ContainerConfig::host"], vm),
+                                    smtenc.association_rel(
+                                        vm, smtenc.associations["infrastructure_Node::ifaces"], net_iface),
+                                    smtenc.association_rel(
+                                        net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], csubnet),
+                                ),
+                                And(  # asc_consumer is deployed on a VM in an AutoScalingGroup with an interface in network n
+                                    smtenc.association_rel(
+                                        cnode, smtenc.associations["infrastructure_AutoScalingGroup::machineDefinition"], vm),
+                                    smtenc.association_rel(
+                                        vm, smtenc.associations["infrastructure_Node::ifaces"], net_iface),
+                                    smtenc.association_rel(
+                                        net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], csubnet),
+                                ),
+                            )
+                        ),
+                        smtenc.association_rel(
+                            edeployment, smtenc.associations["commons_Deployment::component"], asc_exposer),
+                        smtenc.association_rel(
+                            edeployment, smtenc.associations["commons_Deployment::node"], enode),
+                        Exists(
+                            [vm, net_iface, cconf],
+                            Or(
+                                And(  # asc_exposer is deployed on a component with an interface in network n
+                                    smtenc.association_rel(
+                                        enode, smtenc.associations["infrastructure_Node::ifaces"], net_iface),
+                                    smtenc.association_rel(
+                                        net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], esubnet),
+                                ),
+                                And(  # asc_exposer is deployed on a container hosted on a VM with an interface in network n
+                                    smtenc.association_rel(
+                                        enode, smtenc.associations["infrastructure_Container::configs"], cconf),
+                                    smtenc.association_rel(
+                                        cconf, smtenc.associations["infrastructure_ContainerConfig::host"], vm),
+                                    smtenc.association_rel(
+                                        vm, smtenc.associations["infrastructure_Node::ifaces"], net_iface),
+                                    smtenc.association_rel(
+                                        net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], esubnet),
+                                ),
+                                And(  # asc_exposer is deployed on a VM in an AutoScalingGroup with an interface in network n
+                                    smtenc.association_rel(
+                                        enode, smtenc.associations["infrastructure_AutoScalingGroup::machineDefinition"], vm),
+                                    smtenc.association_rel(
+                                        vm, smtenc.associations["infrastructure_Node::ifaces"], net_iface),
+                                    smtenc.association_rel(
+                                        net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], esubnet),
+                                )
+                            )
+                        )
+                    )
+                )
+            )
+        )
+    )
+
+def software_package_iface_net_v3_1(smtenc: SMTEncoding, smtsorts: SMTSorts) -> ExprRef:
+    asc_consumer, asc_exposer, siface, net, net_iface, cnode, cdeployment, enode, edeployment, vm, cconf, csubnet, esubnet = Consts(
+        "asc_consumer asc_exposer siface net net_iface cnode cdeployment enode edeployment vm cconf csubnet esubnet", smtsorts.element_sort
+    )
+    return And(
+        smtenc.association_rel(
+            asc_consumer, smtenc.associations["application_SoftwareComponent::exposedInterfaces"], siface),
+        smtenc.association_rel(
+            asc_exposer, smtenc.associations["application_SoftwareComponent::consumedInterfaces"], siface),
+        Not(
+            Or(
+                Exists(
+                    [cdeployment, cnode, edeployment, enode, net],
+                    And(
+                        smtenc.association_rel(
+                            cdeployment, smtenc.associations["commons_Deployment::component"], asc_consumer),
+                        smtenc.association_rel(
+                            cdeployment, smtenc.associations["commons_Deployment::node"], cnode),
+                        Exists(
+                            [vm, net_iface, cconf],
+                            Or(
+                                And(  # asc_consumer is deployed on a component with an interface in network n
+                                    smtenc.association_rel(
+                                        cnode, smtenc.associations["infrastructure_Node::ifaces"], net_iface),
+                                    smtenc.association_rel(
+                                        net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net),
+                                ),
+                                And(  # asc_consumer is deployed on a container hosted in a VM with an interface in network n
+                                    smtenc.association_rel(
+                                        cnode, smtenc.associations["infrastructure_Container::hostConfigs"], cconf),
+                                    smtenc.association_rel(
+                                        cconf, smtenc.associations["infrastructure_ContainerHostConfig::host"], vm),
+                                    smtenc.association_rel(
+                                        vm, smtenc.associations["infrastructure_Node::ifaces"], net_iface),
+                                    smtenc.association_rel(
+                                        net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net),
+                                ),
+                                And(  # asc_consumer is deployed on a VM in an AutoScalingGroup with an interface in network n
+                                    smtenc.association_rel(
+                                        cnode, smtenc.associations["infrastructure_AutoScalingGroup::machineDefinition"], vm),
+                                    smtenc.association_rel(
+                                        vm, smtenc.associations["infrastructure_Node::ifaces"], net_iface),
+                                    smtenc.association_rel(
+                                        net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net),
+                                ),
+                            )
+                        ),
+                        smtenc.association_rel(
+                            edeployment, smtenc.associations["commons_Deployment::component"], asc_exposer),
+                        smtenc.association_rel(
+                            edeployment, smtenc.associations["commons_Deployment::node"], enode),
+                        Exists(
+                            [vm, net_iface, cconf],
+                            Or(
+                                And(  # asc_exposer is deployed on a component with an interface in network n
+                                    smtenc.association_rel(
+                                        enode, smtenc.associations["infrastructure_Node::ifaces"], net_iface),
+                                    smtenc.association_rel(
+                                        net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net),
+                                ),
+                                And(  # asc_exposer is deployed on a container hosted on a VM with an interface in network n
+                                    smtenc.association_rel(
+                                        enode, smtenc.associations["infrastructure_Container::hostConfigs"], cconf),
+                                    smtenc.association_rel(
+                                        cconf, smtenc.associations["infrastructure_ContainerHostConfig::host"], vm),
+                                    smtenc.association_rel(
+                                        vm, smtenc.associations["infrastructure_Node::ifaces"], net_iface),
+                                    smtenc.association_rel(
+                                        net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net),
+                                ),
+                                And(  # asc_exposer is deployed on a VM in an AutoScalingGroup with an interface in network n
+                                    smtenc.association_rel(
+                                        enode, smtenc.associations["infrastructure_AutoScalingGroup::machineDefinition"], vm),
+                                    smtenc.association_rel(
+                                        vm, smtenc.associations["infrastructure_Node::ifaces"], net_iface),
+                                    smtenc.association_rel(
+                                        net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net),
+                                ),
+                            )
+                        )
+                    )
+                ),  # OR
+                Exists(
+                    [cdeployment, cnode, edeployment, enode, csubnet, esubnet],
+                    And(
+                        smtenc.association_rel(
+                            cdeployment, smtenc.associations["commons_Deployment::component"], asc_consumer),
+                        smtenc.association_rel(
+                            cdeployment, smtenc.associations["commons_Deployment::node"], cnode),
+                        Or(
+                            smtenc.association_rel(
+                                csubnet, smtenc.associations["infrastructure_Subnet::connectedTo"], esubnet),
+                            smtenc.association_rel(
+                                esubnet, smtenc.associations["infrastructure_Subnet::connectedTo"], csubnet),
+                        ),
+                        Exists(
+                            [vm, net_iface, cconf],
+                            Or(
+                                And(  # asc_consumer is deployed on a component with an interface in network n
+                                    smtenc.association_rel(
+                                        cnode, smtenc.associations["infrastructure_Node::ifaces"], net_iface),
+                                    smtenc.association_rel(
+                                        net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], csubnet),
+                                ),
+                                And(  # asc_consumer is deployed on a container hosted in a VM with an interface in network n
+                                    smtenc.association_rel(
+                                        cnode, smtenc.associations["infrastructure_Container::hostConfigs"], cconf),
+                                    smtenc.association_rel(
+                                        cconf, smtenc.associations["infrastructure_ContainerHostConfig::host"], vm),
+                                    smtenc.association_rel(
+                                        vm, smtenc.associations["infrastructure_Node::ifaces"], net_iface),
+                                    smtenc.association_rel(
+                                        net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], csubnet),
+                                ),
+                                And(  # asc_consumer is deployed on a VM in an AutoScalingGroup with an interface in network n
+                                    smtenc.association_rel(
+                                        cnode, smtenc.associations["infrastructure_AutoScalingGroup::machineDefinition"], vm),
+                                    smtenc.association_rel(
+                                        vm, smtenc.associations["infrastructure_Node::ifaces"], net_iface),
+                                    smtenc.association_rel(
+                                        net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], csubnet),
+                                ),
+                            )
+                        ),
+                        smtenc.association_rel(
+                            edeployment, smtenc.associations["commons_Deployment::component"], asc_exposer),
+                        smtenc.association_rel(
+                            edeployment, smtenc.associations["commons_Deployment::node"], enode),
+                        Exists(
+                            [vm, net_iface, cconf],
+                            Or(
+                                And(  # asc_exposer is deployed on a component with an interface in network n
+                                    smtenc.association_rel(
+                                        enode, smtenc.associations["infrastructure_Node::ifaces"], net_iface),
+                                    smtenc.association_rel(
+                                        net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], esubnet),
+                                ),
+                                And(  # asc_exposer is deployed on a container hosted on a VM with an interface in network n
+                                    smtenc.association_rel(
+                                        enode, smtenc.associations["infrastructure_Container::hostConfigs"], cconf),
+                                    smtenc.association_rel(
+                                        cconf, smtenc.associations["infrastructure_ContainerHostConfig::host"], vm),
+                                    smtenc.association_rel(
+                                        vm, smtenc.associations["infrastructure_Node::ifaces"], net_iface),
+                                    smtenc.association_rel(
+                                        net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], esubnet),
+                                ),
+                                And(  # asc_exposer is deployed on a VM in an AutoScalingGroup with an interface in network n
+                                    smtenc.association_rel(
+                                        enode, smtenc.associations["infrastructure_AutoScalingGroup::machineDefinition"], vm),
+                                    smtenc.association_rel(
+                                        vm, smtenc.associations["infrastructure_Node::ifaces"], net_iface),
+                                    smtenc.association_rel(
+                                        net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], esubnet),
+                                )
+                            )
+                        )
+                    )
+                )
+            )
+        )
+    )
+
+
+def ed_software_package_iface_net(solver: Solver, smtsorts: SMTSorts, intermediate_model: IntermediateModel) -> str:
+    try:
+        asc_consumer, asc_exposer, siface = Consts(
+            "asc_consumer asc_exposer siface", smtsorts.element_sort
+        )
+        model = solver.model()
+        asc_consumer_name = get_user_friendly_name(
+            intermediate_model, model, asc_consumer)
+        asc_exposer_name = get_user_friendly_name(
+            intermediate_model, model, asc_exposer)
+        siface_name = get_user_friendly_name(intermediate_model, model, siface)
+        if asc_consumer_name and asc_exposer_name and siface_name:
+            return (
+                f"Software components '{asc_consumer_name}' and '{asc_exposer_name}' "
+                f"are supposed to communicate through interface '{siface_name}', "
+                "but they are deployed to nodes that cannot communicate through a common network."
+            )
+    except:
+        return "A software package is deployed on a node that has no access to an interface it consumes."
+    
+MSG = "All software packages can see the interfaces they need through a common network."
+
+SOFTWARE_PACKAGE_IFACE_NET = (
+    software_package_iface_net, 
+    "software_package_iface_net",
+    MSG,
+    ed_software_package_iface_net
+)
+
+SOFTWARE_PACKAGE_IFACE_NET_V2_1 = (
+    software_package_iface_net_v2_1, 
+    "software_package_iface_net",
+    MSG,
+    ed_software_package_iface_net
+)
+
+SOFTWARE_PACKAGE_IFACE_NET_V2_3 = (
+    software_package_iface_net_v2_3,
+    "software_package_iface_net",
+    MSG,
+    ed_software_package_iface_net
+)
+
+SOFTWARE_PACKAGE_IFACE_NET_V3_1 = (
+    software_package_iface_net_v3_1,
+    "software_package_iface_net",
+    MSG,
+    ed_software_package_iface_net
+)
\ No newline at end of file
diff --git a/mc_openapi/doml_mc/builtin_requirements/vm_has_iface.py b/mc_openapi/doml_mc/builtin_requirements/vm_has_iface.py
new file mode 100644
index 0000000000000000000000000000000000000000..bfb43d5d1051dd1d28f9f9b7d326f810d9273747
--- /dev/null
+++ b/mc_openapi/doml_mc/builtin_requirements/vm_has_iface.py
@@ -0,0 +1,59 @@
+from z3 import And, Const, Consts, Exists, ExprRef, Not, Or, Solver, Implies
+from mc_openapi.doml_mc.imc import Requirement, SMTEncoding, SMTSorts
+from mc_openapi.doml_mc.intermediate_model import DOMLVersion, IntermediateModel
+from mc_openapi.doml_mc.error_desc_helper import get_user_friendly_name
+
+
+def vm_has_iface(smtenc: SMTEncoding, smtsorts: SMTSorts) -> ExprRef:
+    vm, iface = Consts("vm iface", smtsorts.element_sort)
+    return And(
+        smtenc.element_class_fun(
+            vm) == smtenc.classes["infrastructure_VirtualMachine"],
+        Not(
+            Exists(
+                [iface],
+                smtenc.association_rel(
+                    vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], iface)
+            )
+        )
+    )
+
+def vm_has_iface_v2_3(smtenc: SMTEncoding, smtsorts: SMTSorts) -> ExprRef:
+    vm, iface = Consts("vm iface", smtsorts.element_sort)
+    return And(
+        smtenc.element_class_fun(
+            vm) == smtenc.classes["infrastructure_VirtualMachine"],
+        Not(
+            Exists(
+                [iface],
+                smtenc.association_rel(
+                    vm, smtenc.associations["infrastructure_Node::ifaces"], iface)
+            )
+        )
+    )
+
+def ed_vm_has_iface(solver: Solver, smtsorts: SMTSorts, intermediate_model: IntermediateModel) -> str:
+    try:
+        vm = Const("vm", smtsorts.element_sort)
+        vm_name = get_user_friendly_name(
+            intermediate_model, solver.model(), vm)
+        if vm_name:
+            return f"Virtual machine {vm_name} is not connected to any network interface."
+    except:
+        return "A virtual machine is not connected to any network interface."
+    
+MSG = "All virtual machines must be connected to at least one network interface."
+
+VM_HAS_IFACE = (
+    vm_has_iface, 
+    "vm_has_iface",
+    MSG,
+    ed_vm_has_iface
+)
+
+VM_HAS_IFACE_V2_3 = (
+    vm_has_iface_v2_3,
+    "vm_has_iface",
+    MSG,
+    ed_vm_has_iface
+)
\ No newline at end of file
diff --git a/mc_openapi/doml_mc/builtin_requirements/vm_os_required.py b/mc_openapi/doml_mc/builtin_requirements/vm_os_required.py
new file mode 100644
index 0000000000000000000000000000000000000000..73a6ce4d5ade7a56c48c4319720989ef4b7a4e20
--- /dev/null
+++ b/mc_openapi/doml_mc/builtin_requirements/vm_os_required.py
@@ -0,0 +1,81 @@
+from z3 import And, Const, Consts, Exists, ExprRef, Not, Or, Solver, Implies
+from mc_openapi.doml_mc.imc import Requirement, SMTEncoding, SMTSorts
+from mc_openapi.doml_mc.intermediate_model import DOMLVersion, IntermediateModel
+from mc_openapi.doml_mc.error_desc_helper import get_user_friendly_name
+
+
+def vm_os_required(smtenc: SMTEncoding, smtsorts: SMTSorts) -> ExprRef:
+    vm, cont, ccfg = Consts("vm cont ccfg", smtsorts.element_sort)
+    os = Const("os", smtsorts.attr_data_sort)
+    return And(
+        smtenc.element_class_fun(
+            vm) == smtenc.classes["infrastructure_VirtualMachine"],
+        smtenc.element_class_fun(
+            cont) == smtenc.classes["infrastructure_Container"],
+        Not(
+            Exists(
+                [vm, os, ccfg],
+                And(
+                    smtenc.association_rel(
+                        cont, smtenc.associations["infrastructure_Container::configs"], ccfg),
+                    smtenc.association_rel(
+                        ccfg, smtenc.associations["infrastructure_ContainerConfig::host"], vm),
+                    smtenc.attribute_rel(
+                        vm, smtenc.attributes["infrastructure_ComputingNode::os"], os)
+                )
+            )
+        )
+    )
+
+def vm_os_required_v3_1(smtenc: SMTEncoding, smtsorts: SMTSorts) -> ExprRef:
+    vm, cont, ccfg = Consts("vm cont ccfg", smtsorts.element_sort)
+    os = Const("os", smtsorts.attr_data_sort)
+    return And(
+        smtenc.element_class_fun(
+            vm) == smtenc.classes["infrastructure_VirtualMachine"],
+        smtenc.element_class_fun(
+            cont) == smtenc.classes["infrastructure_Container"],
+        Not(
+            Exists(
+                [vm, os, ccfg],
+                And(
+                    smtenc.association_rel(
+                        cont, smtenc.associations["infrastructure_Container::hostConfigs"], ccfg),
+                    smtenc.association_rel(
+                        ccfg, smtenc.associations["infrastructure_ContainerHostConfig::host"], vm),
+                    smtenc.attribute_rel(
+                        vm, smtenc.attributes["infrastructure_ComputingNode::os"], os)
+                )
+            )
+        )
+    )
+
+def ed_vm_os_required(solver: Solver, smtsorts: SMTSorts, intermediate_model: IntermediateModel) -> str:
+    try:
+        cont = Const("cont", smtsorts.element_sort)
+        vm = Const("vm", smtsorts.element_sort)
+        cont_name = get_user_friendly_name(
+            intermediate_model, solver.model(), cont)
+        vm_name = get_user_friendly_name(
+            intermediate_model, solver.model(), vm)
+        if cont_name and vm_name:
+            return f"The virtual machine '{vm_name}' hosting container '{cont_name}' needs an OS."
+    except:
+        return "A Virtual machine hosting a container needs an OS."
+    
+
+MSG = "When something is hosted on a virtual machine (e.g.: containers), the VM must have the 'os' specified."
+
+VM_OS_REQUIRED = (
+    vm_os_required, 
+    "vm_os_required",
+    MSG,
+    ed_vm_os_required
+)
+
+VM_OS_REQUIRED_V3_1 = (
+    vm_os_required_v3_1, 
+    "vm_os_required",
+    MSG,
+    ed_vm_os_required
+)
\ No newline at end of file
diff --git a/mc_openapi/doml_mc/common_reqs.py b/mc_openapi/doml_mc/common_reqs.py
index d45c369da44045f7dcdb86834743a786a7706aa0..74edd900f6dea5d2695f8be48488e851b3b27d56 100644
--- a/mc_openapi/doml_mc/common_reqs.py
+++ b/mc_openapi/doml_mc/common_reqs.py
@@ -1,197 +1,78 @@
-from z3 import (
-    Consts, ExprRef,
-    Exists, And, Or, Not
-)
-
-from .imc import (
-    SMTEncoding, SMTSorts, Requirement, RequirementStore
-)
-
-
-def get_consts(smtsorts: SMTSorts, consts: list[str]) -> list[ExprRef]:
-    return Consts(" ".join(consts), smtsorts.element_sort)
-
-
-def vm_iface(smtenc: SMTEncoding, smtsorts: SMTSorts) -> ExprRef:
-    vm, iface = get_consts(smtsorts, ["vm", "iface"])
-    return Exists(
-        [vm],
-        And(
-            smtenc.element_class_fun(vm) == smtenc.classes["infrastructure_VirtualMachine"],
-            Not(
-                Exists(
-                    [iface],
-                    smtenc.association_rel(vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], iface)
-                )
-            )
-        )
-    )
-
-
-def software_package_iface_net(smtenc: SMTEncoding, smtsorts: SMTSorts) -> ExprRef:
-    asc_consumer, asc_exposer, siface, net, net_iface, cnode, cdeployment, enode, edeployment, vm, dc = get_consts(
-        smtsorts,
-        ["asc_consumer", "asc_exposer", "siface", "net", "net_iface", "cnode", "cdeployment", "enode", "edeployment", "vm", "dc"]
-    )
-    return Exists(
-        [asc_consumer, asc_exposer, siface],
-        And(
-            smtenc.association_rel(asc_consumer, smtenc.associations["application_SoftwareComponent::exposedInterfaces"], siface),
-            smtenc.association_rel(asc_exposer, smtenc.associations["application_SoftwareComponent::consumedInterfaces"], siface),
-            Not(
-                Exists(
-                    [cdeployment, cnode, edeployment, enode, net],
-                    And(
-                        smtenc.association_rel(cdeployment, smtenc.associations["commons_Deployment::component"], asc_consumer),
-                        smtenc.association_rel(cdeployment, smtenc.associations["commons_Deployment::node"], cnode),
-                        Exists(
-                            [vm, net_iface],
-                            Or(
-                                And(  # asc_consumer is deployed on a component with an interface in network n
-                                    smtenc.association_rel(cnode, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface),
-                                    smtenc.association_rel(net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net),
-                                ),
-                                And(  # asc_consumer is deployed on a container hosted in a VM with an interface in network n
-                                    smtenc.association_rel(cnode, smtenc.associations["infrastructure_Container::hosts"], vm),
-                                    smtenc.association_rel(vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface),
-                                    smtenc.association_rel(net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net),
-                                ),
-                                And(  # asc_consumer is deployed on a VM in an AutoScalingGroup with an interface in network n
-                                    smtenc.association_rel(cnode, smtenc.associations["infrastructure_AutoScalingGroup::machineDefinition"], vm),
-                                    smtenc.association_rel(vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface),
-                                    smtenc.association_rel(net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net),
-                                ),
-                            )
-                        ),
-                        smtenc.association_rel(edeployment, smtenc.associations["commons_Deployment::component"], asc_exposer),
-                        smtenc.association_rel(edeployment, smtenc.associations["commons_Deployment::node"], enode),
-                        Exists(
-                            [vm, net_iface],
-                            Or(
-                                And(  # asc_exposer is deployed on a component with an interface in network n
-                                    smtenc.association_rel(enode, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface),
-                                    smtenc.association_rel(net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net),
-                                ),
-                                And(  # asc_exposer is deployed on a container hosted on a VM with an interface in network n
-                                    smtenc.association_rel(enode, smtenc.associations["infrastructure_Container::hosts"], vm),
-                                    smtenc.association_rel(vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface),
-                                    smtenc.association_rel(net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net),
-                                ),
-                                And(  # asc_exposer is deployed on a VM in an AutoScalingGroup with an interface in network n
-                                    smtenc.association_rel(enode, smtenc.associations["infrastructure_AutoScalingGroup::machineDefinition"], vm),
-                                    smtenc.association_rel(vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], net_iface),
-                                    smtenc.association_rel(net_iface, smtenc.associations["infrastructure_NetworkInterface::belongsTo"], net),
-                                ),
-                            )
-                        )
-                    )
-                )
-            )
-        )
-    )
-
-
-def iface_uniq(smtenc: SMTEncoding, smtsorts: SMTSorts) -> ExprRef:
-    def any_iface(elem, iface):
-        ifaces_assocs = [
-            "infrastructure_ComputingNode::ifaces",
-            "infrastructure_Storage::ifaces",
-            "infrastructure_FunctionAsAService::ifaces"
-        ]
-        return Or(*(smtenc.association_rel(elem, smtenc.associations[assoc_name], iface) for assoc_name in ifaces_assocs))
-
-    e1, e2, ni = get_consts(smtsorts, ["e1", "e2", "i"])
-    return Exists(
-        [e1, e2, ni],
-        And(
-            any_iface(e1, ni),
-            any_iface(e2, ni),
-            e1 != e2
-        )
-    )
-
-
-def all_SoftwareComponents_deployed(smtenc: SMTEncoding, smtsorts: SMTSorts) -> ExprRef:
-    sc, deployment, ielem = get_consts(smtsorts, ["sc", "deployment", "ielem"])
-    return Exists(
-        [sc],
-        And(
-            smtenc.element_class_fun(sc) == smtenc.classes["application_SoftwareComponent"],
-            Not(
-                Exists(
-                    [deployment, ielem],
-                    And(
-                        smtenc.association_rel(deployment, smtenc.associations["commons_Deployment::component"], sc),
-                        smtenc.association_rel(deployment, smtenc.associations["commons_Deployment::node"], ielem),
-                    )
-                )
-            )
-        )
-    )
-
-
-def all_infrastructure_elements_deployed(smtenc: SMTEncoding, smtsorts: SMTSorts) -> ExprRef:
-    def checkOneClass(ielem, concr, provider, celem, ielemClass, providerAssoc, celemAssoc):
-        return And(
-            smtenc.element_class_fun(ielem) == smtenc.classes[ielemClass],
-            Not(
-                Exists(
-                    [provider, celem],
-                    And(
-                        smtenc.association_rel(concr, smtenc.associations["concrete_ConcreteInfrastructure::providers"], provider),
-                        smtenc.association_rel(provider, smtenc.associations[providerAssoc], celem),
-                        smtenc.association_rel(celem, smtenc.associations[celemAssoc], ielem)
-                    )
-                )
-            )
-        )
-
-    ielem, concr, provider, celem = get_consts(smtsorts, ["ielem", "concr", "provider", "celem"])
-    return Exists(
-        [concr],
-        And(
-            smtenc.element_class_fun(concr) == smtenc.classes["concrete_ConcreteInfrastructure"],
-            Exists(
-                [ielem],
-                Or(
-                    checkOneClass(
-                        ielem, concr, provider, celem,
-                        "infrastructure_VirtualMachine",
-                        "concrete_RuntimeProvider::vms",
-                        "concrete_VirtualMachine::maps"
-                    ),
-                    checkOneClass(
-                        ielem, concr, provider, celem,
-                        "infrastructure_Network",
-                        "concrete_RuntimeProvider::networks",
-                        "concrete_Network::maps"
-                    ),
-                    checkOneClass(
-                        ielem, concr, provider, celem,
-                        "infrastructure_Storage",
-                        "concrete_RuntimeProvider::storages",
-                        "concrete_Storage::maps"
-                    ),
-                    checkOneClass(
-                        ielem, concr, provider, celem,
-                        "infrastructure_FunctionAsAService",
-                        "concrete_RuntimeProvider::faas",
-                        "concrete_FunctionAsAService::maps"
-                    ),
-                )
-            )
-        )
-    )
 
+from .imc import Requirement, RequirementStore
+from .intermediate_model import DOMLVersion
+from .builtin_requirements import *
+
+REQUIREMENTS = {
+    DOMLVersion.V2_0: [
+        VM_HAS_IFACE,
+        SOFTWARE_PACKAGE_IFACE_NET,
+        IFACE_UNIQ,
+        ALL_SOFTWARE_COMPONENTS_DEPLOYED,
+        ALL_INFRASTRUCTURE_ELEMENTS_DEPLOYED,
+        ALL_CONCRETE_MAP_SOMETHING,
+        SECURITY_GROUP_MUST_HAVE_IFACE
+    ],
+    DOMLVersion.V2_1: [
+        VM_HAS_IFACE,
+        SOFTWARE_PACKAGE_IFACE_NET_V2_1,
+        IFACE_UNIQ,
+        ALL_SOFTWARE_COMPONENTS_DEPLOYED,
+        ALL_INFRASTRUCTURE_ELEMENTS_DEPLOYED,
+        ALL_CONCRETE_MAP_SOMETHING,
+        SECURITY_GROUP_MUST_HAVE_IFACE
+    ],
+    DOMLVersion.V2_2: [
+        VM_HAS_IFACE,
+        SOFTWARE_PACKAGE_IFACE_NET_V2_1,
+        IFACE_UNIQ,
+        ALL_SOFTWARE_COMPONENTS_DEPLOYED,
+        ALL_INFRASTRUCTURE_ELEMENTS_DEPLOYED,
+        ALL_CONCRETE_MAP_SOMETHING,
+        SECURITY_GROUP_MUST_HAVE_IFACE,
+        CONCRETE_ASG_NO_VM,
+        VM_OS_REQUIRED
+    ],
+    DOMLVersion.V2_3: [
+        VM_HAS_IFACE_V2_3,
+        SOFTWARE_PACKAGE_IFACE_NET_V2_3,
+        IFACE_UNIQ,
+        ALL_SOFTWARE_COMPONENTS_DEPLOYED,
+        ALL_INFRASTRUCTURE_ELEMENTS_DEPLOYED,
+        ALL_CONCRETE_MAP_SOMETHING,
+        SECURITY_GROUP_MUST_HAVE_IFACE,
+        CONCRETE_ASG_NO_VM,
+        VM_OS_REQUIRED
+    ],
+    DOMLVersion.V3_0: [
+        VM_HAS_IFACE_V2_3,
+        SOFTWARE_PACKAGE_IFACE_NET_V2_3,
+        IFACE_UNIQ,
+        ALL_SOFTWARE_COMPONENTS_DEPLOYED,
+        ALL_INFRASTRUCTURE_ELEMENTS_DEPLOYED,
+        ALL_CONCRETE_MAP_SOMETHING,
+        SECURITY_GROUP_MUST_HAVE_IFACE,
+        CONCRETE_ASG_NO_VM,
+        VM_OS_REQUIRED
+    ],
+    DOMLVersion.V3_1: [
+        VM_HAS_IFACE_V2_3,
+        SOFTWARE_PACKAGE_IFACE_NET_V3_1,
+        IFACE_UNIQ,
+        ALL_SOFTWARE_COMPONENTS_DEPLOYED,
+        ALL_INFRASTRUCTURE_ELEMENTS_DEPLOYED_V3_1,
+        ALL_CONCRETE_MAP_SOMETHING_V3_1,
+        SECURITY_GROUP_MUST_HAVE_IFACE_V3_1,
+        CONCRETE_ASG_NO_VM,
+        VM_OS_REQUIRED_V3_1
+    ]
+}
 
-CommonRequirements = RequirementStore(
+CommonRequirements = {ver: RequirementStore(
     [
-        Requirement(*rt) for rt in [
-            (vm_iface, "vm_iface", "All virtual machines must be connected to at least one network interface.", "A virtual machine is connected to no network interface."),
-            (software_package_iface_net, "software_package_iface_net", "All software packages can see the interfaces they need through a common network.", "A software package is deployed on a node that has no access to an interface it consumes."),
-            (iface_uniq, "iface_uniq", "There are no duplicated interfaces.", "There is a duplicated interface."),
-            (all_SoftwareComponents_deployed, "all_SoftwareComponents_deployed", "All software components have been deployed to some node.", "A software component has not been deployed to any node."),
-            (all_infrastructure_elements_deployed, "all_infrastructure_elements_deployed", "All abstract infrastructure elements are mapped to an element in the active concretization.", "An abstract infrastructure element has not been mapped to any element in the active concretization."),
-        ]
-    ]
-)
+        Requirement(
+            *rt[:-1], error_description=("BUILTIN", rt[-1]), flipped=True
+        ) for rt in reqs
+    ])
+    for ver, reqs in REQUIREMENTS.items()
+}
diff --git a/mc_openapi/doml_mc/consistency_reqs.py b/mc_openapi/doml_mc/consistency_reqs.py
index e9324b951631002577c2ffe490607810db845d33..64d98422848ddfc2821852a44085dda75280a090 100644
--- a/mc_openapi/doml_mc/consistency_reqs.py
+++ b/mc_openapi/doml_mc/consistency_reqs.py
@@ -8,7 +8,7 @@ from .intermediate_model.metamodel import get_subclasses_dict
 from .imc import (
     SMTEncoding, SMTSorts, Requirement, RequirementStore
 )
-from .z3encoding.utils import Iff
+from .utils import Iff
 
 
 def subclass_cond(smtenc: SMTEncoding, subclasses: set[str], elem: ExprRef) -> ExprRef:
@@ -19,7 +19,7 @@ def subclass_cond(smtenc: SMTEncoding, subclasses: set[str], elem: ExprRef) -> E
         )
     )
 
-
+# TODO: CHECK WHAT IS WRONG ELSE SKIP IT
 def get_attribute_type_reqs(mm: MetaModel) -> RequirementStore:
     subclasses_dict = get_subclasses_dict(mm)
     # A type validity constraint is added for every attribute:
@@ -41,17 +41,14 @@ def get_attribute_type_reqs(mm: MetaModel) -> RequirementStore:
                     tgt_type_cond = smtsorts.attr_data_sort.is_ss(attr_val)  # type: ignore
                 else:  # mm_attr.type == "GeneratorKind"
                     tgt_type_cond = Or(
-                        attr_val == smtsorts.attr_data_sort.ss(smtenc.str_symbols["IMAGE"]),  # type: ignore
-                        attr_val == smtsorts.attr_data_sort.ss(smtenc.str_symbols["SCRIPT"]),  # type: ignore
+                        attr_val == smtsorts.attr_data_sort.str(smtenc.str_symbols["IMAGE"]),  # type: ignore
+                        attr_val == smtsorts.attr_data_sort.str(smtenc.str_symbols["SCRIPT"]),  # type: ignore
                     )
-                return Exists(
-                    [elem, attr_val],
-                    And(
-                        smtenc.attribute_rel(elem, smtenc.attributes[f"{cname}::{mm_attr.name}"], attr_val),
-                        Or(
-                            Not(src_subclass_cond),
-                            Not(tgt_type_cond),
-                        ),
+                return And(
+                    smtenc.attribute_rel(elem, smtenc.attributes[f"{cname}::{mm_attr.name}"], attr_val),
+                    Or(
+                        Not(src_subclass_cond),
+                        Not(tgt_type_cond),
                     ),
                 )
 
@@ -60,7 +57,8 @@ def get_attribute_type_reqs(mm: MetaModel) -> RequirementStore:
                     req_assertion,
                     f"attribute_st_types {cname}::{mm_attr.name}",
                     f"Attribute {mm_attr.name} from class {cname} must have type {mm_attr.type}.",
-                    f"Attribute {mm_attr.name} from class {cname} has a type different from {mm_attr.type}.",
+                    lambda _s, _m, _i: f"Attribute {mm_attr.name} from class {cname} has a type different from {mm_attr.type}.",
+                    flipped=True
                 )
             )
     return RequirementStore(reqs)
@@ -76,29 +74,23 @@ def get_attribute_multiplicity_reqs(mm: MetaModel) -> RequirementStore:
                 elem = Const("elem", smtsorts.element_sort)
                 attr_val = Const("attr_val", smtsorts.attr_data_sort)
                 src_subclass_cond = subclass_cond(smtenc, subclasses_dict[cname], elem)  # Source subclass condition
-                return Exists(
-                    [elem],
-                    And(
-                        src_subclass_cond,
-                        Not(
-                            Exists(
-                                [attr_val],
-                                smtenc.attribute_rel(elem, smtenc.attributes[f"{cname}::{mm_attr.name}"], attr_val),
-                            ),
-                        )
-                    ),
+                return And(
+                    src_subclass_cond,
+                    Not(
+                        Exists(
+                            [attr_val],
+                            smtenc.attribute_rel(elem, smtenc.attributes[f"{cname}::{mm_attr.name}"], attr_val),
+                        ),
+                    )
                 )
 
             def req_assertion_ub(smtenc: SMTEncoding, smtsorts: SMTSorts, cname=cname, mm_attr=mm_attr) -> ExprRef:
                 elem = Const("elem", smtsorts.element_sort)
                 attr_val1, attr_val2 = Consts("attr_val1 attr_val2", smtsorts.attr_data_sort)
-                return Exists(
-                    [elem, attr_val1, attr_val2],
-                    And(
-                        smtenc.attribute_rel(elem, smtenc.attributes[f"{cname}::{mm_attr.name}"], attr_val1),
-                        smtenc.attribute_rel(elem, smtenc.attributes[f"{cname}::{mm_attr.name}"], attr_val2),
-                        attr_val1 != attr_val2,
-                    ),
+                return And(
+                    smtenc.attribute_rel(elem, smtenc.attributes[f"{cname}::{mm_attr.name}"], attr_val1),
+                    smtenc.attribute_rel(elem, smtenc.attributes[f"{cname}::{mm_attr.name}"], attr_val2),
+                    attr_val1 != attr_val2,
                 )
 
             lb, ub = mm_attr.multiplicity
@@ -108,7 +100,8 @@ def get_attribute_multiplicity_reqs(mm: MetaModel) -> RequirementStore:
                         req_assertion_lb,
                         f"attribute_mult_lb {cname}::{mm_attr.name}",
                         f"Attribute {mm_attr.name} from class {cname} must have at least one value.",
-                        f"Mandatory attribute {mm_attr.name} from class {cname} has no value.",
+                        lambda _s, _m, _i: f"Mandatory attribute {mm_attr.name} from class {cname} has no value.",
+                        flipped=True
                     )
                 )
             if ub == "1":
@@ -117,7 +110,8 @@ def get_attribute_multiplicity_reqs(mm: MetaModel) -> RequirementStore:
                         req_assertion_ub,
                         f"attribute_mult_ub {cname}::{mm_attr.name}",
                         f"Attribute {mm_attr.name} from class {cname} must have at most one value.",
-                        f"Attribute {mm_attr.name} from class {cname} has more than one value.",
+                        lambda _s, _m, _i: f"Attribute {mm_attr.name} from class {cname} has more than one value.",
+                        flipped=True
                     )
                 )
     return RequirementStore(reqs)
@@ -134,15 +128,12 @@ def get_association_type_reqs(mm: MetaModel) -> RequirementStore:
             # of the association.
             def req_assertion(smtenc: SMTEncoding, smtsorts: SMTSorts, cname=cname, mm_assoc=mm_assoc) -> ExprRef:
                 es, et = Consts("es et", smtsorts.element_sort)
-                return Exists(
-                    [es, et],
-                    And(
-                        smtenc.association_rel(es, smtenc.associations[f"{cname}::{mm_assoc.name}"], et),
-                        Not(
-                            And(
-                                subclass_cond(smtenc, subclasses_dict[cname], es),  # Source subclass condition
-                                subclass_cond(smtenc, subclasses_dict[mm_assoc.class_], et)  # Target subclass condition
-                            ),
+                return And(
+                    smtenc.association_rel(es, smtenc.associations[f"{cname}::{mm_assoc.name}"], et),
+                    Not(
+                        And(
+                            subclass_cond(smtenc, subclasses_dict[cname], es),  # Source subclass condition
+                            subclass_cond(smtenc, subclasses_dict[mm_assoc.class_], et)  # Target subclass condition
                         ),
                     ),
                 )
@@ -152,7 +143,8 @@ def get_association_type_reqs(mm: MetaModel) -> RequirementStore:
                     req_assertion,
                     f"association_st_classes {cname}::{mm_assoc.name}",
                     f"Association {mm_assoc.name} from class {cname} must target class {mm_assoc.class_}.",
-                    f"Association {mm_assoc.name} from class {cname} has a class different from {mm_assoc.class_}.",
+                    lambda _s, _m, _i: f"Association {mm_assoc.name} from class {cname} has a class different from {mm_assoc.class_}.",
+                    flipped=True
                 )
             )
     return RequirementStore(reqs)
@@ -166,28 +158,22 @@ def get_association_multiplicity_reqs(mm: MetaModel) -> RequirementStore:
         for mm_assoc in c.associations.values():
             def req_assertion_lb(smtenc: SMTEncoding, smtsorts: SMTSorts, cname=cname, mm_assoc=mm_assoc) -> ExprRef:
                 es, et = Consts("es et", smtsorts.element_sort)
-                return Exists(
-                    [es],
-                    And(
-                        subclass_cond(smtenc, subclasses_dict[cname], es),  # Source subclass condition
-                        Not(
-                            Exists(
-                                [et],
-                                smtenc.association_rel(es, smtenc.associations[f"{cname}::{mm_assoc.name}"], et),
-                            ),
-                        )
-                    ),
+                return And(
+                    subclass_cond(smtenc, subclasses_dict[cname], es),  # Source subclass condition
+                    Not(
+                        Exists(
+                            [et],
+                            smtenc.association_rel(es, smtenc.associations[f"{cname}::{mm_assoc.name}"], et),
+                        ),
+                    )
                 )
 
             def req_assertion_ub(smtenc: SMTEncoding, smtsorts: SMTSorts, cname=cname, mm_assoc=mm_assoc) -> ExprRef:
                 es, et1, et2 = Consts("es et1 et2", smtsorts.element_sort)
-                return Exists(
-                    [es, et1, et2],
-                    And(
-                        smtenc.association_rel(es, smtenc.associations[f"{cname}::{mm_assoc.name}"], et1),
-                        smtenc.association_rel(es, smtenc.associations[f"{cname}::{mm_assoc.name}"], et2),
-                        et1 != et2,
-                    ),
+                return And(
+                    smtenc.association_rel(es, smtenc.associations[f"{cname}::{mm_assoc.name}"], et1),
+                    smtenc.association_rel(es, smtenc.associations[f"{cname}::{mm_assoc.name}"], et2),
+                    et1 != et2,
                 )
 
             lb, ub = mm_assoc.multiplicity
@@ -197,7 +183,8 @@ def get_association_multiplicity_reqs(mm: MetaModel) -> RequirementStore:
                         req_assertion_lb,
                         f"association_mult_lb {cname}::{mm_assoc.name}",
                         f"Association {mm_assoc.name} from class {cname} must have at least one target.",
-                        f"Mandatory association {mm_assoc.name} is missing from an element of class {cname}.",
+                        lambda _s, _m, _i: f"Mandatory association {mm_assoc.name} is missing from an element of class {cname}.",
+                        flipped=True
                     )
                 )
             if ub == "1":
@@ -206,7 +193,8 @@ def get_association_multiplicity_reqs(mm: MetaModel) -> RequirementStore:
                         req_assertion_ub,
                         f"association_mult_ub {cname}::{mm_assoc.name}",
                         f"Association {mm_assoc.name} from class {cname} must have at most one target.",
-                        f"Association {mm_assoc.name} has more than one target in an element of class {cname}.",
+                        lambda _s, _m, _i: f"Association {mm_assoc.name} has more than one target in an element of class {cname}.",
+                        flipped=True
                     )
                 )
     return RequirementStore(reqs)
@@ -218,14 +206,11 @@ def get_inverse_association_reqs(inv_assoc: list[tuple[str, str]]) -> Requiremen
     for an1, an2 in inv_assoc:
         def req_assertion(smtenc: SMTEncoding, smtsorts: SMTSorts, an1=an1, an2=an2) -> ExprRef:
             es, et = Consts("es et", smtsorts.element_sort)
-            return Exists(
-                [es, et],
-                Not(
-                    Iff(
-                        smtenc.association_rel(es, smtenc.associations[an1], et),
-                        smtenc.association_rel(et, smtenc.associations[an2], es)
-                    ),
-                )
+            return Not(
+                Iff(
+                    smtenc.association_rel(es, smtenc.associations[an1], et),
+                    smtenc.association_rel(et, smtenc.associations[an2], es)
+                ),
             )
 
         reqs.append(
@@ -233,7 +218,8 @@ def get_inverse_association_reqs(inv_assoc: list[tuple[str, str]]) -> Requiremen
                 req_assertion,
                 f"association_inverse {an1} {an2}",
                 f"Association {an1} must be the inverse of {an2}.",
-                f"Association {an1} is not the inverse of {an2}.",
+                lambda _s, _m, _i: f"Association {an1} is not the inverse of {an2}.",
+                flipped=True
             )
         )
     return RequirementStore(reqs)
@@ -268,8 +254,8 @@ def assert_attribute_rel_constraints(
                 tgt_type_cond = smtsorts.attr_data_sort.is_ss(ad)  # type: ignore
             else:  # mm_attr.type == "GeneratorKind"
                 tgt_type_cond = Or(
-                    ad == smtsorts.attr_data_sort.ss(smtenc.str_symbols["IMAGE"]),  # type: ignore
-                    ad == smtsorts.attr_data_sort.ss(smtenc.str_symbols["SCRIPT"]),  # type: ignore
+                    ad == smtsorts.attr_data_sort.str(smtenc.str_symbols["IMAGE"]),  # type: ignore
+                    ad == smtsorts.attr_data_sort.str(smtenc.str_symbols["SCRIPT"]),  # type: ignore
                 )
             assn = ForAll(
                 [es, ad],
diff --git a/mc_openapi/doml_mc/csp_compatibility/__init__.py b/mc_openapi/doml_mc/csp_compatibility/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..27620127f693445ba8ab6f9846b1f25d7a511d14
--- /dev/null
+++ b/mc_openapi/doml_mc/csp_compatibility/__init__.py
@@ -0,0 +1,22 @@
+from .allowlist_check_v1 import CSPCompatibilityValidator
+import importlib.resources as ilres
+from ... import assets
+import yaml
+
+FILE = lambda filename: ilres.files(assets).joinpath(f"csp/{filename}")
+
+SOURCES = [
+    'keypair',
+    'arch',
+    'os',
+    'minimum_setup'
+]
+
+DATA = {}
+
+for src in SOURCES:
+    with open(FILE(f'{src}.yml')) as data:
+        DATA[src] = yaml.safe_load(data)
+
+CSPCompatibilityValidator = CSPCompatibilityValidator(DATA)
+
diff --git a/mc_openapi/doml_mc/csp_compatibility/_iec_check.py b/mc_openapi/doml_mc/csp_compatibility/_iec_check.py
new file mode 100644
index 0000000000000000000000000000000000000000..809c26b31ba10e39e0d125c62b817bf8068ae343
--- /dev/null
+++ b/mc_openapi/doml_mc/csp_compatibility/_iec_check.py
@@ -0,0 +1,110 @@
+from itertools import groupby
+import re
+import requests
+from mc_openapi.doml_mc.imc import IntermediateModelChecker
+from mc_openapi.doml_mc.intermediate_model.metamodel import DOMLVersion
+
+# DEPRECATED
+# Doing this would overlap with IOP tool, therefore checks will be performed using the other tool
+
+
+IEC_API = 'https://iec.ci.piacere.digital.tecnalia.dev/services/iecbackend/api/root-services/catalogue'
+
+def check_csp_compatibility(model: IntermediateModelChecker, doml_version: DOMLVersion):
+    if doml_version != DOMLVersion.V2_2 and doml_version != DOMLVersion.V2_2_1:
+        print("Unsupported DOML version!")
+
+    all_json = requests.get(IEC_API).json()
+
+    all_json = [
+        {
+            'name': x['serviceName'],
+            'class': x['serviceClass']['serviceClassName'],
+            'props': x['serviceAttributeValues']
+        }
+        for x in all_json
+    ]
+
+    def filterByClass(name: str):
+        return [vm for vm in all_json if vm['class'] == name]
+
+    def groupByProvider(elems: list):
+        def flatten_properties(el):
+            for p in el['props']:
+                el[p['serviceAttributeType']['name'].lower()] = p['serviceAttributeValue'] or None
+            el.pop('props', None)
+            return el
+
+        elems = [flatten_properties(elem) for elem in elems]
+
+        return { k: list(v) for k, v in groupby(sorted(elems, key=lambda elem: elem['provider']), lambda elem: elem['provider'])}
+
+
+    # Catalog IEC Elements
+    iec_vms = groupByProvider(filterByClass('Virtual Machine'))
+    iec_stos = groupByProvider(filterByClass('Storage'))
+    iec_dbs = groupByProvider(filterByClass('Database'))
+
+    # DOML IM Elements
+    im_elems = model.values()
+
+    compnodes = [cn for cn in im_elems if re.match(r"infrastructure_(ComputingNode|Container|PhysicalComputingNode|VirtualMachine)", cn.class_)]
+    locations = [lc for lc in im_elems if lc.class_ == 'infrastructure_Location']
+
+    # print(compnodes)
+    # print(locations)
+
+    # for each provider
+    #   check if the available elements have all the properties of doml elements
+    #   if not, mark provider as unsupported and report the unsupported element and its value
+
+    for provider, avail_vms in iec_vms.items():
+        print(f'==={provider}===')
+        for cn in compnodes:
+            # attributes are list|None!
+            name = cn.attributes.get('commons_DOMLElement::name')
+            cpu_count = cn.attributes.get('infrastructure_ComputingNode::cpu_count')
+            memory_mb = cn.attributes.get('infrastructure_ComputingNode::memory_mb')
+            location = cn.associations.get('infrastructure_ComputingNode::location')
+            region = None
+            zone = None
+            if location:
+                location = model[list(location)[0]]
+                region = location.attributes.get('infrastructure_Location::region')
+                zone = location.attributes.get('infrastructure_Location::zone')
+            # not in IEC
+            # arch = cn.attributes.get('infrastructure_ComputingNode::architecture')
+            # os = cn.attributes.get('infrastructure_ComputingNode::os')
+
+            print(f'---{name[0]}---')
+
+            valid_configs = avail_vms
+
+            if cpu_count:
+                valid_configs = [
+                    avm for avm in valid_configs 
+                    if (int(avm['virtual cpu cores']) == cpu_count[0] if cpu_count else False)
+                ]
+            
+            if memory_mb:
+                valid_configs = [
+                    avm for avm in valid_configs 
+                    if (float(avm['memory']) * 1000 == float(memory_mb[0]) if memory_mb else False)
+                ]
+
+            if region:
+                valid_configs = [
+                    avm for avm in valid_configs 
+                    if (avm['region'] == region[0] if region else False)
+                ]
+            
+            if zone:
+                valid_configs = [
+                    avm for avm in valid_configs 
+                    if (avm['zone'] == zone[0] if zone else False)
+                ]
+
+            # print(valid_configs)            
+
+
+            
diff --git a/mc_openapi/doml_mc/csp_compatibility/allowlist_check_v1.py b/mc_openapi/doml_mc/csp_compatibility/allowlist_check_v1.py
new file mode 100644
index 0000000000000000000000000000000000000000..3c8b0c4aadfd7f7ad42b2daba1160d18ab849fe1
--- /dev/null
+++ b/mc_openapi/doml_mc/csp_compatibility/allowlist_check_v1.py
@@ -0,0 +1,131 @@
+
+
+from mc_openapi.doml_mc.intermediate_model.doml_element import DOMLElement, IntermediateModel
+from mc_openapi.doml_mc.intermediate_model.metamodel import DOMLVersion
+from difflib import SequenceMatcher
+
+import re
+
+class CSPCompatibilityValidator:
+    def __init__(self, data: dict) -> None:
+        self.data = data
+
+    def check(self, model: IntermediateModel, doml_version: DOMLVersion) -> dict[str, list]:
+        """Returns a list of CSP supported by the model"""
+
+        ret = {}
+
+        # Check KeyPair
+        keypairs = self.check_keypair(model)
+        if len(keypairs) > 1:
+            ret['keypairs'] = keypairs
+        # ComputingNode and inheritors
+        arch, os, minreq = self.check_computing_nodes(model)
+        if len(arch) > 1:
+            ret['arch'] = arch
+        if len(os) > 1:
+            ret['os'] = os
+        if len(minreq) > 1:
+            ret['minreq'] = minreq
+
+        return ret
+
+    def check_keypair(self, model: IntermediateModel):
+        elems = model.values()
+        keypairs = [kp for kp in elems if kp.class_ == 'commons_KeyPair']
+        TABLE = [['KeyPair', 'Algorithm', *self.data['keypair'].keys()]]
+        for kp in keypairs:
+            name = kp.user_friendly_name
+            algorithm = kp.attributes.get('commons_KeyPair::algorithm')
+            bits = kp.attributes.get('commons_KeyPair::bits')
+            # For each vendor, check if there's at least one supported configuration
+            if algorithm is not None and len(algorithm) > 0:
+                algorithm = algorithm[0].upper()
+                ROW = [name, algorithm]
+                for _, valid_algos in self.data['keypair'].items():
+                    value = '✅' if algorithm in valid_algos else '❌'
+                    ROW.append(value)
+                TABLE.append(ROW)
+        return TABLE
+    
+    def check_computing_nodes(self, model: IntermediateModel):
+        elems = model.values()
+        compnodes = [cn for cn in elems if re.match(r"infrastructure_(ComputingNode|Container|PhysicalComputingNode|VirtualMachine)", cn.class_)]
+        ARCH_TABLE = [['Node', 'Arch', *self.data['arch'].keys()]]
+        OS_TABLE = [['Node', 'OS', *self.data['os'].keys()]]
+        MINREQ_TABLE = [['Node', *self.data['minimum_setup'].keys()]]
+
+        VALID_OS_MATCH_PERCENT = 0.33
+
+        for el in compnodes:
+            name = el.user_friendly_name or el.attributes.get('commons_DOMLElement::name') or f'[{el.class_}]'
+            arch = el.attributes.get('infrastructure_ComputingNode::architecture')
+            os = el.attributes.get('infrastructure_ComputingNode::os')
+            # cpu_count = el.attributes.get('infrastructure_ComputingNode::cpu_count')
+            # memory_mb = el.attributes.get('infrastructure_ComputingNode::memory_mb')
+
+            # CHECK ARCH
+            if arch and len(arch) > 0:
+                arch = arch[0].upper()
+                ROW = [name, arch]
+                for _, valid_archs in self.data['arch'].items():
+                    valid_archs = [v.upper() for v in valid_archs]
+                    value = '✅' if arch in valid_archs else '❌'
+                    ROW.append(value)
+                ARCH_TABLE.append(ROW)
+
+            # CHECK OS
+            if os and len(os) > 0:
+                os = os[0].upper()
+                ROW = [name, os]
+                for _, valid_os in self.data['os'].items():
+                    valid_os = [distro.upper() for os_family in valid_os for distro in valid_os[os_family]]
+                    compatible_os = [v for v in valid_os if v in os or os in v]
+                    alt_compatible_os = [(v, SequenceMatcher(None, v, os).ratio()) for v in valid_os if SequenceMatcher(None, v, os).ratio() > VALID_OS_MATCH_PERCENT]
+                    alt_compatible_os = sorted(alt_compatible_os, key=lambda x: x[1])
+                    value = any(compatible_os)
+                    value = '✅' if value else '❌' if len(alt_compatible_os) == 0 else '❓' 
+                    if len(compatible_os) > 0:
+                        value += f' ({compatible_os[0].lower()})'
+                    if value == '❓':
+                        alt_os_name, alt_os_ratio = alt_compatible_os[0]
+                        value += f' ({alt_os_name.lower()}, {alt_os_ratio*100:.{1}f}%)'
+                    ROW.append(value)
+                OS_TABLE.append(ROW)
+               
+            # CHECK MINIMUM REQUIREMENTS FOR CSP
+            ROW = [name]
+            for vendor, reqs in self.data['minimum_setup'].items():
+                CHECKS = {}
+                for req in reqs:
+                    if isinstance(req, list):
+                        try:
+                            dep = list(el.associations.get(req[0]))[0]
+                            dep = model[dep]
+                            CHECKS[str(req)] = dep.associations.get(req[1]) is not None or el.attributes.get(req[1]) is not None
+                        except:
+                            CHECKS[str(req)] = False
+                    if isinstance(req, str):
+                        CHECKS[req] = el.associations.get(req) is not None or el.attributes.get(req) is not None
+                
+                all_req_valid = all([v for v in CHECKS.values()])
+                value = ['✅' if all_req_valid else '❌']
+                if not all_req_valid:
+                    value += [
+                        re.sub(r"\s*,\s*", " -> ", k)
+                        .replace("_", ".", 1)
+                        .replace("::", ".")
+                        .replace("[", "")
+                        .replace("]", "")
+                        .replace("'", "")
+                        for k, v in CHECKS.items() 
+                        if v is False
+                    ]
+                ROW.append(value)
+            MINREQ_TABLE.append(ROW)
+
+        return ARCH_TABLE, OS_TABLE, MINREQ_TABLE
+    
+       
+
+    
diff --git a/mc_openapi/doml_mc/domlr_parser/__init__.py b/mc_openapi/doml_mc/domlr_parser/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..7e7d69b9817656cb7984292858fb371e41694891
--- /dev/null
+++ b/mc_openapi/doml_mc/domlr_parser/__init__.py
@@ -0,0 +1,3 @@
+from .transformer import DOMLRTransformer
+from .synthesis_transformer import SynthesisDOMLRTransformer
+from .parser import Parser
\ No newline at end of file
diff --git a/mc_openapi/doml_mc/domlr_parser/exceptions.py b/mc_openapi/doml_mc/domlr_parser/exceptions.py
new file mode 100644
index 0000000000000000000000000000000000000000..44ba418127398291a5449923bc729fe06596be0d
--- /dev/null
+++ b/mc_openapi/doml_mc/domlr_parser/exceptions.py
@@ -0,0 +1,25 @@
+class RequirementException(Exception):
+    message: str
+    def __repr__(self) -> str:
+        return self.message
+
+class RequirementMissingKeyException(RequirementException):
+    def __init__(self, key_type: str, key: str, close_matches: list[str], *args: object) -> None:
+        super().__init__(*args)
+        fix_syntax = lambda x: x.replace("_", ".", 1).replace("::", ".")
+        key = fix_syntax(key)
+        close_matches = list(map(fix_syntax, close_matches))
+        self.message = f"Error: no {key_type} found named '{key}'.\n"
+        if close_matches:
+            self.message += "Perhaps you meant...\n"
+            self.message += "".join([f"- '{match}'\n" for match in close_matches])
+
+class RequirementBadSyntaxException(RequirementException):
+    def __init__(self, line: int, col: int, message: str, *args: object) -> None:
+        super().__init__(*args)
+        self.message = f"Syntax Error at Ln {line}, Col {col}:\n{message}"
+
+class ParserException(Exception):
+    def __init__(self, *args: object) -> None:
+        super().__init__(*args)
+        self.errors = "Failed to parse DOMLR."
\ No newline at end of file
diff --git a/mc_openapi/doml_mc/domlr_parser/exceptions.yaml b/mc_openapi/doml_mc/domlr_parser/exceptions.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..f04cf3429d4ab3fcd5c414ac9d8661a63c4a8454
--- /dev/null
+++ b/mc_openapi/doml_mc/domlr_parser/exceptions.yaml
@@ -0,0 +1,43 @@
+TOKENS:
+  FLIP_EXPR: |
+    a declaration of a requirement.
+      To declare a requirement use:
+      • '+' to declare a requirement
+      • '-' to declare a requirement in negation form, which means
+        that if it's satisfied, then the DOML does not respect the 
+        requirements.
+
+  ESCAPED_STRING: a string. Strings are enclosed by double quotes '"'.
+  BOOL: a boolean value. It can be 'true' or 'false'.
+  NUMBER: a number. It must be an integer.
+  VALUE: a value constant. Values must start with an uppercase letter.
+  CONST: a logic variable. Variables must start with a lowercase letter.
+
+  IS: |
+    a statement such as:
+    • 'is', 'is not' followed by a class or a variable
+    • 'has' followed by an relationship name and then a variable or value
+
+  NOT: a 'not' before an expression or a quantifier.
+  OR: a logical connective such as 'or' between expressions.
+  AND: a logical connective such as 'and' between expressions.
+  IFF: a logical connective such as 'iff' between expressions.
+  IMPLIES: a logical connective such as 'implies' between expressions.
+
+  COMMA: a ',' separating bounded variables after an 'exists'/'forall'
+
+  LPAR: a '(' after which an expression begins.
+  RPAR: a ')' closing a previous '('.
+
+  RELATIONSHIP: |
+    a valid relationship name.
+      Relationships consists of 'package.class->relationship', with no spaces around '.' and '->'.
+
+
+  EXISTS: a 'exists' quantifier. 
+  FORALL: a 'forall' quantifier.
+
+  CLASS_PREFIX: a 'class' followed by a class name
+  ERR_DESC_SYMBOL: a 'error:' to separate the logic expression from the error message.
+HINTS:
+  DOT: If you're trying to use a class, did you put 'class' before the class name?
\ No newline at end of file
diff --git a/mc_openapi/doml_mc/domlr_parser/grammar.lark b/mc_openapi/doml_mc/domlr_parser/grammar.lark
new file mode 100644
index 0000000000000000000000000000000000000000..896cf3a64f41f0743b44246c05acdbd7393e07b9
--- /dev/null
+++ b/mc_openapi/doml_mc/domlr_parser/grammar.lark
@@ -0,0 +1,82 @@
+start          : (flags)? (requirements)?
+
+flags           : flag (flag)*
+
+flag            : "%IGNORE" CONST       -> flag_requirement_ignore
+                | "%IGNORE_BUILTIN"     -> flag_requirement_ignore_builtin
+                | "%CHECK" CONST        -> flag_requirement_check
+                | "%CHECK_CONSISTENCY"   -> flag_requirement_check_consistency
+                | "%CSP"                -> flag_csp 
+
+requirements    : requirement (requirement)*
+
+requirement     : FLIP_EXPR req_name expression "error:" error_desc
+
+req_name        : ESCAPED_STRING
+error_desc      : ESCAPED_STRING
+
+?expression     : iff_expr
+
+?iff_expr       : (implies_expr "iff")? implies_expr
+
+?implies_expr   : (and_expr "implies")? and_expr
+
+?and_expr       : (or_expr "and")* or_expr
+
+?or_expr        : (not_expr "or")* not_expr
+
+?not_expr       : "not" not_expr -> negation
+                | quantification
+
+?quantification : "exists" bound_consts "(" expression ")" -> exists
+                | "forall" bound_consts "(" expression ")" -> forall
+                | "(" expression ")"
+                | property
+
+?property       : CONST "has" RELATIONSHIP CONST                            -> rel_assoc_expr
+                | CONST "has" RELATIONSHIP COMPARISON_OP value              -> rel_attr_value_expr
+                | CONST "has" RELATIONSHIP COMPARISON_OP CONST RELATIONSHIP -> rel_attr_elem_expr
+                | const_or_class "is" const_or_class                        -> equality
+                | const_or_class "is not" const_or_class                    -> inequality
+
+
+bound_consts    : [CONST ("," CONST)*]
+
+const_or_class  : "class" CLASS
+                | CONST
+
+value           : ESCAPED_STRING
+                | NUMBER
+                | BOOL
+
+FLIP_EXPR       : "+"
+                | "-"
+
+COMPARISON_OP   : ">" | ">="
+                | "<" | "<="
+                | "==" | "!="
+
+BOOL            : ":true"
+                | ":false"
+
+// regex: /[a-zA-Z]+_[a-zA-Z]+::[a-zA-Z]+/
+RELATIONSHIP: /[^\W\d_]+\.[^\W\d_]+\.([^\W\d]|_)+/
+
+CLASS: /[^\W\d_]+\.[^\W\d_]+/
+
+// Const must start with lowercase letter
+CONST: (LCASE_LETTER) ("_"|LETTER|DIGIT)*
+
+// Comment: python/sh style
+COMMENT: /#[^\n]*/
+
+%import common.ESCAPED_STRING
+%import common.NEWLINE
+%import common.LETTER
+%import common.DIGIT
+%import common.NUMBER
+%import common.LCASE_LETTER
+%import common.UCASE_LETTER
+%import common.WS
+%ignore WS
+%ignore COMMENT
diff --git a/mc_openapi/doml_mc/domlr_parser/parser.py b/mc_openapi/doml_mc/domlr_parser/parser.py
new file mode 100644
index 0000000000000000000000000000000000000000..00fdc260421d328c5149200e8865e1cb4f839fa2
--- /dev/null
+++ b/mc_openapi/doml_mc/domlr_parser/parser.py
@@ -0,0 +1,90 @@
+import os
+
+import yaml
+from doml_synthesis import State
+from lark import Lark, UnexpectedCharacters, UnexpectedEOF
+from z3 import Not
+
+from mc_openapi.doml_mc.domlr_parser.exceptions import ParserException, RequirementBadSyntaxException, RequirementMissingKeyException
+from mc_openapi.doml_mc.domlr_parser.utils import StringValuesCache, VarStore
+from mc_openapi.doml_mc.imc import RequirementStore
+
+class ParserData:
+    def __init__(self) -> None:
+        grammar_path = os.path.join(os.path.dirname(__file__), "grammar.lark")
+        exceptions_path = os.path.join(
+            os.path.dirname(__file__), "exceptions.yaml")
+        with open(grammar_path, "r") as grammar:
+            self.grammar = grammar.read()
+        with open(exceptions_path, "r") as exceptions:
+            self.exceptions = yaml.safe_load(exceptions)
+
+
+PARSER_DATA = ParserData()
+
+
+class Parser:
+    def __init__(self, transformer, grammar: str = PARSER_DATA.grammar):
+        self.parser = Lark(grammar, start="start", parser="lalr")
+        self.transformer = transformer
+
+    def parse(self, input: str, for_synthesis: bool = False) -> tuple[RequirementStore, list[str], dict[str, bool]]:
+        """Parse the input string containing the DOMLR requirements and
+           returns a tuple with:
+           - RequirementStore with the parsed requirements inside
+           - A list of strings to be added to the string constant EnumSort
+           - A dictionary of all the flags
+        """
+        try:
+            self.tree = self.parser.parse(input)
+
+            const_store = VarStore()
+            user_values_cache = StringValuesCache()
+
+            transformer = self.transformer(const_store, user_values_cache)
+
+            if not for_synthesis:
+                reqs, flags = transformer.transform(self.tree)
+                return (
+                    RequirementStore(reqs),
+                    user_values_cache.get_list(),
+                    flags
+                )
+            else:
+                reqs = transformer.transform(self.tree)
+
+                # This function has to return state or it will break the
+                # synthesis solver
+                def user_reqs(state: State):
+                    for (req, id, negated) in reqs:
+                        state.solver.assert_and_track(
+                            req(state) if not negated else Not(req(state)), f'Requirement {id}')
+                    return state
+
+                return user_reqs, user_values_cache.get_list()
+
+        except UnexpectedEOF as e:
+            msg = "Unexpected End of File:\n"
+            msg += "Did you forget the `error:` keyword at the end of a requirement?"
+            raise Exception(msg)
+
+        except UnexpectedCharacters as e:
+            msg = _get_error_desc_for_unexpected_characters(e, input)
+            raise RequirementBadSyntaxException(e.line, e.column, msg)
+
+
+def _get_error_desc_for_unexpected_characters(e: UnexpectedCharacters, input: str):
+    # Error description
+    msg = "Syntax Error:\n\n"
+    msg += e.get_context(input)
+    msg += "Expected one of the following:\n"
+    for val in e.allowed:
+        val = PARSER_DATA.exceptions["TOKENS"].get(val, "")
+        msg += (f"• {val}\n")
+    # Suggestion that might be useful
+    if e.char == ".":
+        msg += "HINTS:\n"
+        msg += PARSER_DATA.exceptions["HINTS"]["DOT"]
+    # Print line highlighting the error
+
+    return msg
diff --git a/mc_openapi/doml_mc/domlr_parser/synthesis_transformer.py b/mc_openapi/doml_mc/domlr_parser/synthesis_transformer.py
new file mode 100644
index 0000000000000000000000000000000000000000..46de50cf0803ad26a82b2d4ff676141add729581
--- /dev/null
+++ b/mc_openapi/doml_mc/domlr_parser/synthesis_transformer.py
@@ -0,0 +1,248 @@
+from typing import Callable
+
+from doml_synthesis import State
+from lark import Transformer
+from z3 import And, Exists, ExprRef, ForAll, Implies, Not, Or
+
+from mc_openapi.doml_mc.domlr_parser.utils import (StringValuesCache,
+                                                   SynthesisRefHandler,
+                                                   VarStore)
+
+
+class SynthesisDOMLRTransformer(Transformer):
+    # These callbacks will be called when a rule with the same name
+    # is matched. It starts from the leaves.
+    def __init__(self,
+                 const_store: VarStore,
+                 user_values_cache: StringValuesCache,
+                 visit_tokens: bool = True
+                 ) -> None:
+        super().__init__(visit_tokens)
+        self.const_store = const_store
+        self.user_values_cache = user_values_cache
+
+    def __default__(self, data, children, meta):
+        return children
+
+    # start
+    def requirements(self, args) -> list[tuple]:
+        return args
+
+    def requirement(self, args) -> tuple:
+        flip_expr: bool = args[0].value == "-"
+        name: str = args[1]
+        expr: Callable[[State], ExprRef] = args[2]
+        return (
+            expr,
+            name.lower().replace(" ", "_"),  # id
+            flip_expr
+        )
+
+    def req_name(self, args) -> str:
+        return str(args[0].value.replace('"', ''))
+
+    # Requirement requirement expression
+
+    def bound_consts(self, args):
+        const_names = list(map(lambda arg: arg.value, args))
+        for name in const_names:
+            self.const_store.use(name)
+            self.const_store.quantify(name)
+        return lambda state: SynthesisRefHandler.get_consts(const_names, state)
+
+    def negation(self, args):
+        return lambda state: Not(args[0](state))
+
+    def iff_expr(self, args):
+        return lambda state: args[0](state) == args[1](state)
+
+    def implies_expr(self, args):
+        return lambda state: Implies(args[0](state), args[1](state))
+
+    def and_expr(self, args):
+        return lambda state: And([arg(state) for arg in args])
+
+    def or_expr(self, args):
+        return lambda state: Or([arg(state) for arg in args])
+
+    def exists(self, args):
+        return lambda state: Exists(args[0](state), args[1](state))
+
+    def forall(self, args):
+        return lambda state: ForAll(args[0](state), args[1](state))
+
+    def rel_assoc_expr(self, args):
+        """An ASSOCIATION relationship"""
+        rel_name = args[1].value
+        self.const_store.use(args[0].value)
+        self.const_store.use(args[2].value)
+
+        def _gen_rel_elem_expr(state: State):
+            rel = SynthesisRefHandler.get_assoc(state, rel_name)
+
+            return state.rels.AssocRel(
+                SynthesisRefHandler.get_const(args[0].value, state),
+                rel.ref,
+                SynthesisRefHandler.get_const(args[2].value, state)
+            )
+        return _gen_rel_elem_expr
+
+    def rel_attr_value_expr(self, args):
+        """An ATTRIBUTE relationship with a rhs that is a value
+
+           CONST "has" RELATIONSHIP COMPARISON_OP value
+           0           1            2             3
+        """
+
+        rel_name = args[1].value
+
+        def _gen_rel_attr_value_expr(state: State):
+            elem = SynthesisRefHandler.get_const(args[0].value, state)
+            rel = SynthesisRefHandler.get_attr(state, rel_name)
+
+            rhs_value, rhs_value_type = args[3]
+            rhs_value = rhs_value(state)
+            op = args[2].value
+
+            if rhs_value_type == SynthesisRefHandler.INTEGER and rel.type == 'Integer':
+                lhs_value = state.rels.int.AttrValueRel(elem, rel.ref)
+                return And(
+                    self.compare(op, lhs_value, rhs_value),
+                    state.rels.int.AttrSynthRel(elem, rel.ref)
+                )
+            elif op != "==" and op != "!=":
+                raise "You can only use == and != to compare Strings and Booleans!"
+            elif rhs_value_type == SynthesisRefHandler.STRING:
+                lhs_value = state.rels.str.AttrValueRel(elem, rel.ref)
+
+                return And(
+                    lhs_value == rhs_value if op == "==" else lhs_value != rhs_value,
+                    state.rels.str.AttrSynthRel(elem, rel.ref)
+                )
+            elif rhs_value_type == SynthesisRefHandler.BOOLEAN:
+                lhs_value = state.rels.bool.AttrValueRel(elem, rel.ref)
+                return And(
+                    lhs_value == rhs_value if op == "==" else lhs_value != rhs_value,
+                    state.rels.bool.AttrSynthRel(elem, rel.ref)
+                )
+            else:
+                raise f'Invalid value {rhs_value} during parsing for synthesis.'
+
+        return _gen_rel_attr_value_expr
+
+    def rel_attr_elem_expr(self, args):
+        """An ATTRIBUTE relationship with a rhs that is another element
+           CONST "has" RELATIONSHIP COMPARISON_OP CONST RELATIONSHIP
+           0           1            2             3     4
+        """
+
+        rel1_name = args[1].value
+        rel2_name = args[4].value
+        op = args[2].value
+
+        def _gen_rel_attr_elem_expr(state: State):
+            elem1 = SynthesisRefHandler.get_const(args[0].value, state)
+            elem2 = SynthesisRefHandler.get_const(args[3].value, state)
+            rel1 = SynthesisRefHandler.get_attr(state, rel1_name)
+            rel2 = SynthesisRefHandler.get_attr(state, rel2_name)
+
+            if rel1.type == rel2.type == 'Integer':
+                return And(
+                    state.rels.int.AttrSynthRel(elem1, rel1.ref),
+                    state.rels.int.AttrSynthRel(elem2, rel2.ref),
+                    self.compare(
+                        op,
+                        state.rels.int.AttrValueRel(elem1, rel1.ref),
+                        state.rels.int.AttrValueRel(elem2, rel2.ref)
+                    )
+                )
+            if rel1.type == rel2.type == 'Boolean':
+                return And(
+                    state.rels.bool.AttrSynthRel(elem1, rel1.ref),
+                    state.rels.bool.AttrSynthRel(elem2, rel2.ref),
+                    self.compare(
+                        op,
+                        state.rels.bool.AttrValueRel(elem1, rel1.ref),
+                        state.rels.bool.AttrValueRel(elem2, rel2.ref)
+                    )
+                )
+            if rel1.type == rel2.type == 'String':
+                return And(
+                    state.rels.str.AttrSynthRel(elem1, rel1.ref),
+                    state.rels.str.AttrSynthRel(elem2, rel2.ref),
+                    self.compare(
+                        op,
+                        state.rels.str.AttrValueRel(elem1, rel1.ref),
+                        state.rels.str.AttrValueRel(elem2, rel2.ref)
+                    )
+                )
+            raise f'Attribute relationships {rel1_name} ({rel1.type}) and {rel2_name} ({rel2.type}) have mismatch type.'
+
+        return _gen_rel_attr_elem_expr
+
+    def _get_equality_sides(self, arg1, arg2):
+        # We track use of const in const_or_class
+        if arg1.type == "CONST" and arg2.type == "CONST":
+            return (
+                lambda state: SynthesisRefHandler.get_const(arg1.value, state),
+                lambda state: SynthesisRefHandler.get_const(arg2.value, state)
+            )
+
+        if arg1.type == "CLASS":
+            def arg1_ret(state): return SynthesisRefHandler.get_class(
+                state, arg1.value)
+        else:
+            def arg1_ret(state): return SynthesisRefHandler.get_element_class(
+                state, SynthesisRefHandler.get_const(arg1.value, state))
+
+        if arg2.type == "CLASS":
+            def arg2_ret(state): return SynthesisRefHandler.get_class(
+                state, arg2.value)
+        else:
+            def arg2_ret(state): return SynthesisRefHandler.get_element_class(
+                state, SynthesisRefHandler.get_const(arg2.value, state))
+
+        return (arg1_ret, arg2_ret)
+
+    def equality(self, args):
+        a, b = self._get_equality_sides(args[0], args[1])
+        return lambda state: a(state) == b(state)
+
+    def inequality(self, args):
+        a, b = self._get_equality_sides(args[0], args[1])
+        return lambda state: a(state) != b(state)
+
+    def const_or_class(self, args):
+        if args[0].type == "CONST":
+            self.const_store.use(args[0].value)
+        return args[0]
+
+    def compare(self, op: str, a, b):
+
+        if op == ">":
+            return a > b
+        if op == ">=":
+            return a >= b
+        if op == "<":
+            return a < b
+        if op == "<=":
+            return a <= b
+        if op == "==":
+            return a == b
+        if op == "!=":
+            return a != b
+        raise f"Invalid Compare Operator Symbol: {op}"
+
+    def value(self, args):
+        type = args[0].type
+        value = args[0].value
+
+        if type == "ESCAPED_STRING":
+            value = value.replace('"', '')
+            self.user_values_cache.add(value)
+            return lambda state: SynthesisRefHandler.get_str(value, state), SynthesisRefHandler.STRING
+        elif type == "NUMBER":
+            return lambda _: value, SynthesisRefHandler.INTEGER
+        elif type == "BOOL":
+            return lambda _: SynthesisRefHandler.get_bool(value), SynthesisRefHandler.BOOLEAN
+
diff --git a/mc_openapi/doml_mc/domlr_parser/transformer.py b/mc_openapi/doml_mc/domlr_parser/transformer.py
new file mode 100644
index 0000000000000000000000000000000000000000..624d6003a3a675297e91e2b73bec601385b8f851
--- /dev/null
+++ b/mc_openapi/doml_mc/domlr_parser/transformer.py
@@ -0,0 +1,334 @@
+import logging
+import re
+from collections import ChainMap
+from typing import Callable, Literal
+
+from lark import Transformer
+from z3 import And, Exists, ExprRef, ForAll, Implies, Not, Or, Solver
+
+from mc_openapi.doml_mc.domlr_parser.utils import (RefHandler,
+                                                   StringValuesCache, VarStore)
+from mc_openapi.doml_mc.error_desc_helper import get_user_friendly_name
+from mc_openapi.doml_mc.imc import Requirement, SMTEncoding, SMTSorts
+from mc_openapi.doml_mc.intermediate_model.doml_element import \
+    IntermediateModel
+
+
+class DOMLRTransformer(Transformer):
+    # These callbacks will be called when a rule with the same name
+    # is matched. It starts from the leaves.
+    def __init__(self,
+                 const_store: VarStore,
+                 user_values_cache: StringValuesCache,
+                 visit_tokens: bool = True
+                 ) -> None:
+        super().__init__(visit_tokens)
+        self.const_store = const_store
+        self.user_values_cache = user_values_cache
+
+    def __default__(self, data, children, meta):
+        return children
+
+    # start
+    def start(self, args) -> tuple[list[Requirement], dict[str, str]]:
+        if not isinstance(args[0], dict): # there aren't flags
+            return args[0], {}
+        elif len(args) == 1 and isinstance(args[0], dict): # There are just the flags
+            return [], args[0]
+        return args[1], args[0]
+    
+    def flags(self, args) -> dict:
+        return dict(ChainMap(*list(args)))
+
+    def flag_requirement_check(self, args) -> dict:
+        return { args[0].value : True }
+
+    def flag_requirement_check_consistency(self, args) -> dict:
+        return { '_check_consistency' : True }
+
+    def flag_requirement_ignore(self, args) -> dict:
+        return { args[0].value : False }
+
+    def flag_requirement_ignore_builtin(self, args) -> dict:
+        return { '_ignore_builtin' : True }
+
+    def flag_csp(self, args) -> dict:
+        return { '_csp' : True }
+
+    def requirements(self, args) -> list[Requirement]:
+        return args
+
+    def requirement(self, args) -> Requirement:
+        flip_expr: bool = args[0].value == "-"
+        name: str = args[1]
+        expr: Callable[[SMTEncoding, SMTSorts], ExprRef] = args[2]
+        errd: tuple[Literal["USER", "BUILTIN"], Callable[[Solver, SMTSorts,
+                                                          IntermediateModel, int], str]] = args[3]
+        index = self.const_store.get_index_and_push()
+        return Requirement(
+            expr,
+            name.lower().replace(" ", "_"),
+            name,
+            (errd[0], lambda solver, sorts, model: errd[1](
+                solver, sorts, model,
+                index,
+                name
+            )),
+            flipped=flip_expr
+        )
+
+    def req_name(self, args) -> str:
+        return str(args[0].value.replace('"', ''))
+
+    # Requirement requirement expression
+
+    def bound_consts(self, args):
+        const_names = list(map(lambda arg: arg.value, args))
+        for name in const_names:
+            self.const_store.use(name)
+            self.const_store.quantify(name)
+        return lambda _, sorts: RefHandler.get_consts(const_names, sorts)
+
+    def negation(self, args):
+        return lambda enc, sorts: Not(args[0](enc, sorts))
+
+    def iff_expr(self, args):
+        return lambda enc, sorts: args[0](enc, sorts) == args[1](enc, sorts)
+
+    def implies_expr(self, args):
+        return lambda enc, sorts: Implies(args[0](enc, sorts), args[1](enc, sorts))
+
+    def and_expr(self, args):
+        return lambda enc, sorts: And([arg(enc, sorts) for arg in args])
+
+    def or_expr(self, args):
+        return lambda enc, sorts: Or([arg(enc, sorts) for arg in args])
+
+    def exists(self, args):
+        return lambda enc, sorts: Exists(args[0](enc, sorts), args[1](enc, sorts))
+
+    def forall(self, args):
+        return lambda enc, sorts: ForAll(args[0](enc, sorts), args[1](enc, sorts))
+
+    def rel_assoc_expr(self, args):
+        """An ASSOCIATION relationship"""
+        rel_name = args[1].value
+        self.const_store.use(args[0].value)
+        self.const_store.use(args[2].value)
+
+        def _gen_rel_elem_expr(enc: SMTEncoding, sorts: SMTSorts):
+            rel, rel_type = RefHandler.get_relationship(enc, rel_name)
+
+            assert rel_type == RefHandler.ASSOCIATION
+
+            return RefHandler.get_association_rel(
+                enc,
+                RefHandler.get_const(args[0].value, sorts),
+                rel,
+                RefHandler.get_const(args[2].value, sorts)
+            )
+        return _gen_rel_elem_expr
+
+    def rel_attr_value_expr(self, args):
+        """An ATTRIBUTE relationship with a rhs that is a value"""
+
+        rel_name = args[1].value
+
+        def _gen_rel_attr_value_expr(enc: SMTEncoding, sorts: SMTSorts):
+            elem = RefHandler.get_const(args[0].value, sorts)
+            rel, rel_type = RefHandler.get_relationship(enc, rel_name)
+            assert rel_type == RefHandler.ATTRIBUTE
+
+            rhs_value, rhs_value_type = args[3]
+            rhs_value = rhs_value(enc, sorts)
+            op = args[2].value
+
+            if rhs_value_type == RefHandler.INTEGER:
+
+                lhs_value = RefHandler.get_value("x", sorts)
+
+                return And(
+                    RefHandler.get_attribute_rel(enc,
+                                                 elem,
+                                                 rel,
+                                                 lhs_value
+                                                 ),
+                    self.compare_int(sorts, op, lhs_value, rhs_value)
+                )
+            elif rhs_value_type == RefHandler.STRING or rhs_value_type == RefHandler.BOOLEAN:
+                expr = RefHandler.get_attribute_rel(enc,
+                                                    elem,
+                                                    rel,
+                                                    rhs_value
+                                                    )
+                if op == "==":
+                    return expr
+                elif op == "!=":
+                    return Not(expr)
+                else:
+                    raise f'Invalid compare operator "{op}". It must be "==" or "!=".'
+
+        return _gen_rel_attr_value_expr
+
+    def rel_attr_elem_expr(self, args):
+        """An ATTRIBUTE relationship with a rhs that is another element"""
+
+        rel1_name = args[1].value
+        rel2_name = args[4].value
+        op = args[2].value
+
+        def _gen_rel_attr_elem_expr(enc: SMTEncoding, sorts: SMTSorts):
+            elem1 = RefHandler.get_const(args[0].value, sorts)
+            elem2 = RefHandler.get_const(args[3].value, sorts)
+            rel1, rel1_type = RefHandler.get_relationship(enc, rel1_name)
+            rel2, rel2_type = RefHandler.get_relationship(enc, rel2_name)
+
+            assert rel1_type == RefHandler.ATTRIBUTE
+            assert rel2_type == RefHandler.ATTRIBUTE
+
+            rhs_value = RefHandler.get_value("x", sorts)
+
+            expr = And(
+                RefHandler.get_attribute_rel(enc,
+                                             elem1,
+                                             rel1,
+                                             rhs_value
+                                             ),
+                RefHandler.get_attribute_rel(enc,
+                                             elem2,
+                                             rel2,
+                                             rhs_value
+                                             )
+            )
+            if op == "==":
+                return expr
+            elif op == "!=":
+                return Not(expr)
+            else:
+                rhs1_value = RefHandler.get_value("rhs1", sorts)
+                rhs2_value = RefHandler.get_value("rhs2", sorts)
+                expr = And(
+                    RefHandler.get_attribute_rel(enc,
+                                                 elem1,
+                                                 rel1,
+                                                 rhs1_value
+                                                 ),
+                    RefHandler.get_attribute_rel(enc,
+                                                 elem2,
+                                                 rel2,
+                                                 rhs2_value
+                                                 ),
+                    self.compare_int(sorts, op, rhs1_value, rhs2_value)
+                )
+                logging.warning(
+                    "Warning: Comparing attributes of two elements with {op} is experimental!\n",
+                    "Assumption: the attribute is an Integer."
+                )
+                return expr
+
+        return _gen_rel_attr_elem_expr
+
+    def _get_equality_sides(self, arg1, arg2):
+        # We track use of const in const_or_class
+        if arg1.type == "CONST" and arg2.type == "CONST":
+            return (
+                lambda _, sorts: RefHandler.get_const(arg1.value, sorts),
+                lambda _, sorts: RefHandler.get_const(arg2.value, sorts)
+            )
+
+        if arg1.type == "CLASS":
+            def arg1_ret(enc, _): return RefHandler.get_class(enc, arg1.value)
+        else:
+            def arg1_ret(enc, sorts): return RefHandler.get_element_class(
+                enc, RefHandler.get_const(arg1.value, sorts))
+
+        if arg2.type == "CLASS":
+            def arg2_ret(enc, _): return RefHandler.get_class(enc, arg2.value)
+        else:
+            def arg2_ret(enc, sorts): return RefHandler.get_element_class(
+                enc, RefHandler.get_const(arg2.value, sorts))
+
+        return (arg1_ret, arg2_ret)
+
+    def equality(self, args):
+        a, b = self._get_equality_sides(args[0], args[1])
+        return lambda enc, sorts: a(enc, sorts) == b(enc, sorts)
+
+    def inequality(self, args):
+        a, b = self._get_equality_sides(args[0], args[1])
+        return lambda enc, sorts: a(enc, sorts) != b(enc, sorts)
+
+    def const_or_class(self, args):
+        if args[0].type == "CONST":
+            self.const_store.use(args[0].value)
+        return args[0]
+
+    def compare_int(self, sorts: SMTSorts, op: str, a, b):
+        # To extract the `int` contained in the attr_data_sort,
+        # we need to call its `get_int` method on the `DatatypeRef`
+        get_int = sorts.attr_data_sort.get_int
+
+        a = get_int(a)
+        b = get_int(b)
+
+        if op == ">":
+            return a > b
+        if op == ">=":
+            return a >= b
+        if op == "<":
+            return a < b
+        if op == "<=":
+            return a <= b
+        if op == "==":
+            return a == b
+        if op == "!=":
+            return a != b
+        raise f"Invalid Compare Operator Symbol: {op}"
+
+    def value(self, args):
+        type = args[0].type
+        value = args[0].value
+
+        if type == "ESCAPED_STRING":
+            value = value.replace('"', '')
+            self.user_values_cache.add(value)
+            return lambda enc, sorts: RefHandler.get_str(value, enc, sorts), RefHandler.STRING
+        elif type == "NUMBER":
+            return lambda _, sorts: RefHandler.get_int(value, sorts), RefHandler.INTEGER
+        elif type == "BOOL":
+            return lambda _, sorts: RefHandler.get_bool(value, sorts), RefHandler.BOOLEAN
+        # elif type == "VALUE":
+        #     return lambda _, sorts: RefHandler.get_value(value, sorts), RefHandler.VALUE_REF
+
+    def error_desc(self, args):
+        def err_callback(
+            solver: Solver,
+            sorts: SMTSorts,
+            intermediate_model: IntermediateModel,
+            index: int,
+            requirement_desc: str
+        ) -> str:
+            err_msg = args[0].value.replace('"', '')
+            # Get list of free variables
+            consts_name = self.const_store.get_free_vars(index)
+            consts = RefHandler.get_consts(consts_name, sorts)
+            notes = []
+            try:
+                model = solver.model()
+                for const in consts:
+                    name = get_user_friendly_name(
+                        intermediate_model, model, const)
+                    err_msg = err_msg.replace(
+                        "{" + str(const) + "}", f"'{name}'")
+            except:
+                notes.append(
+                    "Model not found: it's not possible to show which element is causing the issue")
+
+            # tell the user which variables are not free
+            unused_free_vars = re.findall(r"{[^{}]*}", err_msg)
+            if unused_free_vars:
+                notes.append(
+                    "The following variables are not free and should be removed from the error description: " + " ".join(unused_free_vars))
+
+            return (requirement_desc, err_msg, notes)
+        return ("USER", err_callback)
diff --git a/mc_openapi/doml_mc/domlr_parser/utils.py b/mc_openapi/doml_mc/domlr_parser/utils.py
new file mode 100644
index 0000000000000000000000000000000000000000..b52a2ae01a01ce7472fb18276a0f4fb0b0c6ab57
--- /dev/null
+++ b/mc_openapi/doml_mc/domlr_parser/utils.py
@@ -0,0 +1,166 @@
+from difflib import get_close_matches
+
+from mc_openapi.doml_mc.domlr_parser.exceptions import \
+    RequirementMissingKeyException
+from mc_openapi.doml_mc.imc import SMTEncoding, SMTSorts
+from z3 import Const, DatatypeRef, ExprRef, FuncDeclRef, SortRef, Ints, And
+from doml_synthesis import State, AssocRel, AttrRel
+
+class StringValuesCache:
+    def __init__(self) -> None:
+        self.values: set[str] = set()
+
+    def add(self, value: str):
+        self.values.add(value)
+    
+    def get_list(self):
+        return list(self.values)
+
+class VarStore:
+    """This class provides a way to instance a Z3 variable only the first time
+       it's called, and subsequent uses of that variable simply retrieve it
+       from the store.
+    """
+
+    def __init__(self):
+        self.expressions: list[dict[str, bool]] = []
+        self.curr_vars: dict[str, bool] = dict()
+        self.curr_index: int = 0
+
+    def use(self, name: str):
+        self.curr_vars[name] = self.curr_vars.get(name, False)
+
+    def quantify(self, name: str):
+        self.curr_vars[name] = True
+    
+    def get_index_and_push(self):
+        self.expressions.append(self.curr_vars)
+        self.curr_vars = dict()
+
+        self.curr_index += 1
+        return self.curr_index - 1
+
+    def get_free_vars(self, index: int) -> list[ExprRef]:
+        vars = self.expressions[index]
+        if not vars: 
+            return []
+        free_vars = [key for key, val in vars.items() if not val]
+        return free_vars
+
+
+class RefHandler:
+    """A utility class that provides simplified ways to create Z3 Refs.
+    """
+
+    def get_consts(names: list[str], sorts: SMTSorts):
+        return [Const(name, sorts.element_sort) for name in names]
+
+    def get_const(name: str, sorts: SMTSorts):
+        return Const(name, sorts.element_sort)
+
+    def get_value(name: str, sorts: SMTSorts):
+        return Const(name, sorts.attr_data_sort)
+
+    def get_int(value: str, sorts: SMTSorts):
+        return sorts.attr_data_sort.int(int(value))
+
+    def get_bool(value: str, sorts: SMTSorts):
+        return sorts.attr_data_sort.bool(value == "!True")
+
+    def get_str(value: str, enc: SMTEncoding, sorts: SMTSorts):
+        return sorts.attr_data_sort.str(enc.str_symbols[value])
+
+    def get_element_class(enc: SMTEncoding, const: ExprRef) -> FuncDeclRef:
+        return enc.element_class_fun(const)
+
+    def get_class(enc: SMTEncoding, class_name: str) -> DatatypeRef:
+        class_name = _convert_rel_str(class_name)
+        _class = enc.classes.get(class_name, None)
+        if _class is not None:
+            return _class
+        else:
+            close_matches = get_close_matches(class_name, enc.classes.keys())
+            raise RequirementMissingKeyException("class", class_name, close_matches)
+
+    ASSOCIATION = 0
+    ATTRIBUTE = 1
+
+    INTEGER = 2
+    BOOLEAN = 3
+    STRING = 4
+
+    def get_relationship(enc: SMTEncoding, rel_name: str) -> tuple[DatatypeRef, int]:
+        rel_name = _convert_rel_str(rel_name)
+        rel = enc.associations.get(rel_name, None)
+        if rel is not None:
+            return rel, RefHandler.ASSOCIATION
+        else:
+            rel = enc.attributes.get(rel_name, None)
+            if rel is not None:
+                return rel, RefHandler.ATTRIBUTE
+            else:
+                close_matches = get_close_matches(rel_name, list(enc.associations.keys()) + list(enc.attributes.keys()))
+                raise RequirementMissingKeyException("relationship", rel_name, close_matches)
+
+    def get_association_rel(enc: SMTEncoding, a: ExprRef, rel: DatatypeRef, b: ExprRef) -> DatatypeRef:
+        return enc.association_rel(a, rel, b)
+
+    def get_attribute_rel(enc: SMTEncoding, a: ExprRef, rel: DatatypeRef, b: ExprRef) -> DatatypeRef:
+        return enc.attribute_rel(a, rel, b)
+
+class SynthesisRefHandler:
+    """A utility class that provides simplified ways to create Z3 Refs.
+    To be used when parsing requirements for synthesis
+    """
+
+    INTEGER = 2
+    BOOLEAN = 3
+    STRING = 4
+
+    def get_consts(names: list[str], state: State):
+        return [Const(name, state.sorts.Elem) for name in names]
+
+    def get_const(name: str, state: State):
+        return Const(name, state.sorts.Elem)
+
+    def get_bool(value: str):
+        return value == "!True"
+
+    def get_str(value: str, state: State):
+        return state.data.Strings[value]
+
+    def get_element_class(state: State, const: ExprRef) -> FuncDeclRef:
+        return state.rels.ElemClass(const)
+
+    def get_class(state: State, class_name: str) -> DatatypeRef:
+        class_name = _convert_rel_str(class_name)
+        _class = state.data.Classes.get(class_name, None)
+        if _class is not None:
+            return _class.ref
+        else:
+            close_matches = get_close_matches(class_name, state.data.Classes.keys())
+            raise RequirementMissingKeyException("class", class_name, close_matches)
+
+    def get_assoc(state: State, rel_name: str) -> AssocRel:
+        rel_name = _convert_rel_str(rel_name)
+        rel = state.data.Assocs.get(rel_name, None)
+        if rel is not None:
+            return rel
+        else: 
+            raise f"Association {rel_name} not present in the metamodel!"
+
+    def get_attr(state: State, rel_name: str) -> AttrRel:
+            rel_name = _convert_rel_str(rel_name)
+            rel = state.data.Attrs.get(rel_name, None)
+            if rel is not None:
+                return rel
+            else: 
+                raise f"Attribute {rel_name} not present in the metamodel!"
+
+def _convert_rel_str(rel: str) -> str:
+    tokens = rel.replace("abstract", "infrastructure").split(".") 
+    if len(tokens) == 2:
+        return tokens[0] + "_" + tokens[1]
+    if len(tokens) == 3:
+        return tokens[0] + "_" + tokens[1] + "::" + tokens[2]
+    raise f"Bad relationship name: {rel}"
diff --git a/mc_openapi/doml_mc/error_desc_helper.py b/mc_openapi/doml_mc/error_desc_helper.py
new file mode 100644
index 0000000000000000000000000000000000000000..abf13dd44346a26b4469b2840480ea8f603affa7
--- /dev/null
+++ b/mc_openapi/doml_mc/error_desc_helper.py
@@ -0,0 +1,15 @@
+from z3 import ExprRef, ModelRef
+from typing import Optional
+from mc_openapi.doml_mc.intermediate_model import IntermediateModel
+
+def get_user_friendly_name(
+    intermediate_model: IntermediateModel,
+    model: ModelRef,
+    const: ExprRef
+) -> Optional[str]:
+    z3_elem = model[const]
+    if z3_elem is not None:
+        im_elem = intermediate_model.get(str(z3_elem))
+        if im_elem is not None:
+            return im_elem.user_friendly_name
+    return None
diff --git a/mc_openapi/doml_mc/example.ipynb b/mc_openapi/doml_mc/example.ipynb
deleted file mode 100644
index adef80b5a80d287751bc399eea1f718386d55660..0000000000000000000000000000000000000000
--- a/mc_openapi/doml_mc/example.ipynb
+++ /dev/null
@@ -1,995 +0,0 @@
-{
- "cells": [
-  {
-   "cell_type": "code",
-   "execution_count": 1,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "from mc_openapi.doml_mc.intermediate_model.metamodel import parse_metamodel, parse_inverse_associations\n",
-    "import yaml\n",
-    "with open(\"../assets/doml_meta.yaml\") as mmf:\n",
-    "    mmdoc = yaml.load(mmf, yaml.Loader)\n",
-    "mm = parse_metamodel(mmdoc)\n",
-    "inv_assoc = parse_inverse_associations(mmdoc)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 2,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "import prettyprinter as pp\n",
-    "from prettyprinter.prettyprinter import IMPLICIT_MODULES\n",
-    "pp.install_extras(include=['dataclasses'])"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 3,
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "mc_openapi.doml_mc.intermediate_model.metamodel.DOMLClass(\n",
-      "    name='application_SoftwareComponent',\n",
-      "    superclass='application_ApplicationComponent',\n",
-      "    attributes={\n",
-      "        'isPersistent': mc_openapi.doml_mc.intermediate_model.metamodel.DOMLAttribute(\n",
-      "            name='isPersistent',\n",
-      "            type='Boolean',\n",
-      "            multiplicity=('1', '1'),\n",
-      "            default=False\n",
-      "        ),\n",
-      "        'licenseCost': mc_openapi.doml_mc.intermediate_model.metamodel.DOMLAttribute(\n",
-      "            name='licenseCost',\n",
-      "            type='String',\n",
-      "            multiplicity=('0', '1'),\n",
-      "            default=None\n",
-      "        ),\n",
-      "        'configFile': mc_openapi.doml_mc.intermediate_model.metamodel.DOMLAttribute(\n",
-      "            name='configFile',\n",
-      "            type='String',\n",
-      "            multiplicity=('0', '1'),\n",
-      "            default=None\n",
-      "        )\n",
-      "    },\n",
-      "    associations={\n",
-      "        'exposedInterfaces': mc_openapi.doml_mc.intermediate_model.metamodel.DOMLAssociation(\n",
-      "            name='exposedInterfaces',\n",
-      "            class_='application_SoftwareInterface',\n",
-      "            multiplicity=('0', '*')\n",
-      "        ),\n",
-      "        'consumedInterfaces': mc_openapi.doml_mc.intermediate_model.metamodel.DOMLAssociation(\n",
-      "            name='consumedInterfaces',\n",
-      "            class_='application_SoftwareInterface',\n",
-      "            multiplicity=('0', '*')\n",
-      "        )\n",
-      "    }\n",
-      ")\n"
-     ]
-    }
-   ],
-   "source": [
-    "IMPLICIT_MODULES.add('doml_mc.intermediate_model.metamodel')\n",
-    "pp.pprint(mm[\"application_SoftwareComponent\"])"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "### Load the DOML document here:"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 4,
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "{'source_code': DOMLElement(name='source_code', class_='commons_SProperty', attributes={'commons_Property::key': 'source_code', 'commons_SProperty::value': '/usr/share/nginx/html/index.html'}, associations={}), 'nginx': DOMLElement(name='nginx', class_='application_SoftwareComponent', attributes={'application_SoftwareComponent::isPersistent': False, 'commons_DOMLElement::name': 'nginx'}, associations={'commons_DOMLElement::annotations': {'source_code'}}), 'app': DOMLElement(name='app', class_='application_ApplicationLayer', attributes={'commons_DOMLElement::name': 'app'}, associations={'application_ApplicationLayer::components': {'nginx'}}), 'ssh_key': DOMLElement(name='ssh_key', class_='infrastructure_KeyPair', attributes={'infrastructure_KeyPair::algorithm': 'RSA', 'infrastructure_KeyPair::keyfile': '/home/user1/.ssh/openstack.key', 'infrastructure_KeyPair::bits': 4096, 'infrastructure_KeyPair::user': 'ubuntu', 'commons_DOMLElement::name': 'ssh_key'}, associations={}), 'out_all': DOMLElement(name='out_all', class_='infrastructure_Rule', attributes={'infrastructure_Rule::protocol': '-1', 'infrastructure_Rule::toPort': 0, 'infrastructure_Rule::fromPort': 0, 'commons_DOMLElement::name': 'out_all', 'infrastructure_Rule::kind': 'EGRESS'}, associations={}), 'http': DOMLElement(name='http', class_='infrastructure_Rule', attributes={'infrastructure_Rule::protocol': 'tcp', 'infrastructure_Rule::toPort': 80, 'infrastructure_Rule::fromPort': 80, 'commons_DOMLElement::name': 'http', 'infrastructure_Rule::kind': 'INGRESS'}, associations={}), 'https': DOMLElement(name='https', class_='infrastructure_Rule', attributes={'infrastructure_Rule::protocol': 'tcp', 'infrastructure_Rule::toPort': 443, 'infrastructure_Rule::fromPort': 443, 'commons_DOMLElement::name': 'https', 'infrastructure_Rule::kind': 'INGRESS'}, associations={}), 'ssh': DOMLElement(name='ssh', class_='infrastructure_Rule', attributes={'infrastructure_Rule::protocol': 'tcp', 'infrastructure_Rule::toPort': 22, 'infrastructure_Rule::fromPort': 22, 'commons_DOMLElement::name': 'ssh', 'infrastructure_Rule::kind': 'INGRESS'}, associations={}), 'net1': DOMLElement(name='net1', class_='infrastructure_VPC', attributes={'infrastructure_Network::address_lb': 268435456, 'infrastructure_Network::address_ub': 268435711, 'infrastructure_Network::protocol': 'tcp/ip', 'commons_DOMLElement::name': 'net1'}, associations={'infrastructure_Network::connectedIfaces': {'i1'}}), 'i1': DOMLElement(name='i1', class_='infrastructure_NetworkInterface', attributes={'infrastructure_NetworkInterface::endPoint': 268435457, 'commons_DOMLElement::name': 'i1'}, associations={'infrastructure_NetworkInterface::belongsTo': {'net1'}, 'infrastructure_NetworkInterface::associated': {'sg'}}), 'sg': DOMLElement(name='sg', class_='infrastructure_SecurityGroup', attributes={'commons_DOMLElement::name': 'sg'}, associations={'infrastructure_SecurityGroup::rules': {'https', 'ssh', 'http', 'out_all'}, 'infrastructure_ComputingGroup::groupedNodes': {'vm1'}, 'infrastructure_SecurityGroup::ifaces': {'i1'}}), 'vm1': DOMLElement(name='vm1', class_='infrastructure_VirtualMachine', attributes={'commons_DOMLElement::name': 'vm1'}, associations={'infrastructure_ComputingNode::credentials': {'ssh_key'}, 'infrastructure_ComputingNode::group': {'sg'}, 'infrastructure_VirtualMachine::generatedFrom': {'v_img'}, 'infrastructure_ComputingNode::ifaces': {'i1'}}), 'v_img': DOMLElement(name='v_img', class_='infrastructure_VMImage', attributes={'infrastructure_ComputingNodeGenerator::kind': 'SCRIPT', 'commons_DOMLElement::name': 'v_img'}, associations={'infrastructure_VMImage::generatedVMs': {'vm1'}}), 'ag': DOMLElement(name='ag', class_='infrastructure_AutoScalingGroup', attributes={'infrastructure_AutoScalingGroup::loadBalancer': 'DEFAULT', 'infrastructure_AutoScalingGroup::min': 1, 'commons_DOMLElement::name': 'ag', 'infrastructure_AutoScalingGroup::max': 1}, associations={'infrastructure_AutoScalingGroup::deploymentNetwork': {'net1'}, 'infrastructure_AutoScalingGroup::machineDefinition': {'vm1'}}), 'infra': DOMLElement(name='infra', class_='infrastructure_InfrastructureLayer', attributes={'commons_DOMLElement::name': 'infra'}, associations={'infrastructure_InfrastructureLayer::generators': {'v_img'}, 'infrastructure_InfrastructureLayer::networks': {'net1'}, 'infrastructure_InfrastructureLayer::credentials': {'ssh_key'}, 'infrastructure_InfrastructureLayer::secGroups': {'sg'}, 'infrastructure_InfrastructureLayer::nodes': {'ag'}}), 'vm_name': DOMLElement(name='vm_name', class_='commons_SProperty', attributes={'commons_Property::key': 'vm_name', 'commons_SProperty::value': 'nginx-host'}, associations={}), 'vm_flavor': DOMLElement(name='vm_flavor', class_='commons_SProperty', attributes={'commons_Property::key': 'vm_flavor', 'commons_SProperty::value': 'small'}, associations={}), 'vm_key_name': DOMLElement(name='vm_key_name', class_='commons_SProperty', attributes={'commons_Property::key': 'vm_key_name', 'commons_SProperty::value': 'user1'}, associations={}), 'concrete_vm': DOMLElement(name='concrete_vm', class_='concrete_VirtualMachine', attributes={'commons_DOMLElement::name': 'concrete_vm'}, associations={'commons_DOMLElement::annotations': {'vm_flavor', 'vm_name', 'vm_key_name'}, 'concrete_VirtualMachine::maps': {'vm1'}}), 'name': DOMLElement(name='name', class_='commons_SProperty', attributes={'commons_Property::key': 'name', 'commons_SProperty::value': 'ostack2'}, associations={}), 'concrete_net': DOMLElement(name='concrete_net', class_='concrete_Network', attributes={'commons_DOMLElement::name': 'concrete_net'}, associations={'commons_DOMLElement::annotations': {'name'}, 'concrete_Network::maps': {'net1'}}), 'concrete_vm_image': DOMLElement(name='concrete_vm_image', class_='concrete_VMImage', attributes={'commons_DOMLElement::name': 'concrete_vm_image'}, associations={'commons_DOMLElement::annotations': {'name'}, 'concrete_VMImage::maps': {'v_img'}}), 'openstack': DOMLElement(name='openstack', class_='concrete_RuntimeProvider', attributes={'commons_DOMLElement::name': 'openstack'}, associations={'concrete_RuntimeProvider::vms': {'concrete_vm'}, 'concrete_RuntimeProvider::networks': {'concrete_net'}, 'concrete_RuntimeProvider::vmImages': {'concrete_vm_image'}}), 'con_infra': DOMLElement(name='con_infra', class_='concrete_ConcreteInfrastructure', attributes={'commons_DOMLElement::name': 'con_infra'}, associations={'concrete_ConcreteInfrastructure::providers': {'openstack'}})}\n"
-     ]
-    },
-    {
-     "name": "stderr",
-     "output_type": "stream",
-     "text": [
-      "Attribute addressRanges of multiplicity > 1 not supported yet.\n",
-      "Attribute addressRanges of multiplicity > 1 not supported yet.\n",
-      "Attribute addressRanges of multiplicity > 1 not supported yet.\n",
-      "Attribute addressRanges of multiplicity > 1 not supported yet.\n"
-     ]
-    }
-   ],
-   "source": [
-    "from mc_openapi.doml_mc.xmi_parser.doml_model import parse_doml_model\n",
-    "doml_document_path = \"../../tests/doml/nginx-openstack_v2.domlx\"\n",
-    "# doml_document_path = \"../../tests/doml/nginx-openstack_v2_wrong.domlx\"\n",
-    "with open(doml_document_path, \"rb\") as xmif:\n",
-    "    doc = xmif.read()\n",
-    "\n",
-    "im = parse_doml_model(doc, mm)\n",
-    "print(im)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 5,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "from mc_openapi.doml_mc.xmi_parser.doml_model import parse_xmi_model\n",
-    "doml_xmi = parse_xmi_model(doc)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 6,
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "['abstract', 'allInstances', 'defaultValue', 'eAllAttributes', 'eAllOperations', 'eAllReferences', 'eAllStructuralFeatures', 'eAllSuperTypes', 'eAnnotations', 'eAttributes', 'eGenericSuperTypes', 'eOperations', 'ePackage', 'eReferences', 'eStructuralFeatures', 'eSuperTypes', 'eTypeParameters', 'eURIFragment', 'findEOperation', 'findEStructuralFeature', 'getEAnnotation', 'instanceClass', 'instanceClassName', 'instanceTypeName', 'interface', 'name', 'notifyChanged']\n",
-      "infrastructure\n",
-      "0\n",
-      "<EClass name=\"ConcreteInfrastructure\">\n"
-     ]
-    }
-   ],
-   "source": [
-    "print(dir(doml_xmi.eClass))\n",
-    "print(doml_xmi.infrastructure.eClass.ePackage.name)\n",
-    "print(doml_xmi.infrastructure.eClass.eAllReferences().pop().lower)\n",
-    "print(doml_xmi.activeInfrastructure.eClass)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 7,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "from mc_openapi.doml_mc.intermediate_model.doml_element import reciprocate_inverse_associations\n",
-    "reciprocate_inverse_associations(im, inv_assoc)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 8,
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "{\n",
-      "    'source_code': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n",
-      "        name='source_code',\n",
-      "        class_='commons_SProperty',\n",
-      "        attributes={\n",
-      "            'commons_Property::key': 'source_code',\n",
-      "            'commons_SProperty::value': '/usr/share/nginx/html/index.html'\n",
-      "        },\n",
-      "        associations={}\n",
-      "    ),\n",
-      "    'nginx': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n",
-      "        name='nginx',\n",
-      "        class_='application_SoftwareComponent',\n",
-      "        attributes={\n",
-      "            'application_SoftwareComponent::isPersistent': False,\n",
-      "            'commons_DOMLElement::name': 'nginx'\n",
-      "        },\n",
-      "        associations={'commons_DOMLElement::annotations': {'source_code'}}\n",
-      "    ),\n",
-      "    'app': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n",
-      "        name='app',\n",
-      "        class_='application_ApplicationLayer',\n",
-      "        attributes={'commons_DOMLElement::name': 'app'},\n",
-      "        associations={'application_ApplicationLayer::components': {'nginx'}}\n",
-      "    ),\n",
-      "    'ssh_key': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n",
-      "        name='ssh_key',\n",
-      "        class_='infrastructure_KeyPair',\n",
-      "        attributes={\n",
-      "            'infrastructure_KeyPair::algorithm': 'RSA',\n",
-      "            'infrastructure_KeyPair::keyfile': '/home/user1/.ssh/openstack.key',\n",
-      "            'infrastructure_KeyPair::bits': 4096,\n",
-      "            'infrastructure_KeyPair::user': 'ubuntu',\n",
-      "            'commons_DOMLElement::name': 'ssh_key'\n",
-      "        },\n",
-      "        associations={}\n",
-      "    ),\n",
-      "    'out_all': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n",
-      "        name='out_all',\n",
-      "        class_='infrastructure_Rule',\n",
-      "        attributes={\n",
-      "            'infrastructure_Rule::protocol': '-1',\n",
-      "            'infrastructure_Rule::toPort': 0,\n",
-      "            'infrastructure_Rule::fromPort': 0,\n",
-      "            'commons_DOMLElement::name': 'out_all',\n",
-      "            'infrastructure_Rule::kind': 'EGRESS'\n",
-      "        },\n",
-      "        associations={}\n",
-      "    ),\n",
-      "    'http': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n",
-      "        name='http',\n",
-      "        class_='infrastructure_Rule',\n",
-      "        attributes={\n",
-      "            'infrastructure_Rule::protocol': 'tcp',\n",
-      "            'infrastructure_Rule::toPort': 80,\n",
-      "            'infrastructure_Rule::fromPort': 80,\n",
-      "            'commons_DOMLElement::name': 'http',\n",
-      "            'infrastructure_Rule::kind': 'INGRESS'\n",
-      "        },\n",
-      "        associations={}\n",
-      "    ),\n",
-      "    'https': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n",
-      "        name='https',\n",
-      "        class_='infrastructure_Rule',\n",
-      "        attributes={\n",
-      "            'infrastructure_Rule::protocol': 'tcp',\n",
-      "            'infrastructure_Rule::toPort': 443,\n",
-      "            'infrastructure_Rule::fromPort': 443,\n",
-      "            'commons_DOMLElement::name': 'https',\n",
-      "            'infrastructure_Rule::kind': 'INGRESS'\n",
-      "        },\n",
-      "        associations={}\n",
-      "    ),\n",
-      "    'ssh': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n",
-      "        name='ssh',\n",
-      "        class_='infrastructure_Rule',\n",
-      "        attributes={\n",
-      "            'infrastructure_Rule::protocol': 'tcp',\n",
-      "            'infrastructure_Rule::toPort': 22,\n",
-      "            'infrastructure_Rule::fromPort': 22,\n",
-      "            'commons_DOMLElement::name': 'ssh',\n",
-      "            'infrastructure_Rule::kind': 'INGRESS'\n",
-      "        },\n",
-      "        associations={}\n",
-      "    ),\n",
-      "    'net1': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n",
-      "        name='net1',\n",
-      "        class_='infrastructure_VPC',\n",
-      "        attributes={\n",
-      "            'infrastructure_Network::address_lb': 268435456,\n",
-      "            'infrastructure_Network::address_ub': 268435711,\n",
-      "            'infrastructure_Network::protocol': 'tcp/ip',\n",
-      "            'commons_DOMLElement::name': 'net1'\n",
-      "        },\n",
-      "        associations={'infrastructure_Network::connectedIfaces': {'i1'}}\n",
-      "    ),\n",
-      "    'i1': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n",
-      "        name='i1',\n",
-      "        class_='infrastructure_NetworkInterface',\n",
-      "        attributes={\n",
-      "            'infrastructure_NetworkInterface::endPoint': 268435457,\n",
-      "            'commons_DOMLElement::name': 'i1'\n",
-      "        },\n",
-      "        associations={\n",
-      "            'infrastructure_NetworkInterface::belongsTo': {'net1'},\n",
-      "            'infrastructure_NetworkInterface::associated': {'sg'}\n",
-      "        }\n",
-      "    ),\n",
-      "    'sg': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n",
-      "        name='sg',\n",
-      "        class_='infrastructure_SecurityGroup',\n",
-      "        attributes={'commons_DOMLElement::name': 'sg'},\n",
-      "        associations={\n",
-      "            'infrastructure_SecurityGroup::rules': {\n",
-      "                'https',\n",
-      "                'ssh',\n",
-      "                'http',\n",
-      "                'out_all'\n",
-      "            },\n",
-      "            'infrastructure_ComputingGroup::groupedNodes': {'vm1'},\n",
-      "            'infrastructure_SecurityGroup::ifaces': {'i1'}\n",
-      "        }\n",
-      "    ),\n",
-      "    'vm1': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n",
-      "        name='vm1',\n",
-      "        class_='infrastructure_VirtualMachine',\n",
-      "        attributes={'commons_DOMLElement::name': 'vm1'},\n",
-      "        associations={\n",
-      "            'infrastructure_ComputingNode::credentials': {'ssh_key'},\n",
-      "            'infrastructure_ComputingNode::group': {'sg'},\n",
-      "            'infrastructure_VirtualMachine::generatedFrom': {'v_img'},\n",
-      "            'infrastructure_ComputingNode::ifaces': {'i1'}\n",
-      "        }\n",
-      "    ),\n",
-      "    'v_img': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n",
-      "        name='v_img',\n",
-      "        class_='infrastructure_VMImage',\n",
-      "        attributes={\n",
-      "            'infrastructure_ComputingNodeGenerator::kind': 'SCRIPT',\n",
-      "            'commons_DOMLElement::name': 'v_img'\n",
-      "        },\n",
-      "        associations={'infrastructure_VMImage::generatedVMs': {'vm1'}}\n",
-      "    ),\n",
-      "    'ag': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n",
-      "        name='ag',\n",
-      "        class_='infrastructure_AutoScalingGroup',\n",
-      "        attributes={\n",
-      "            'infrastructure_AutoScalingGroup::loadBalancer': 'DEFAULT',\n",
-      "            'infrastructure_AutoScalingGroup::min': 1,\n",
-      "            'commons_DOMLElement::name': 'ag',\n",
-      "            'infrastructure_AutoScalingGroup::max': 1\n",
-      "        },\n",
-      "        associations={\n",
-      "            'infrastructure_AutoScalingGroup::deploymentNetwork': {'net1'},\n",
-      "            'infrastructure_AutoScalingGroup::machineDefinition': {'vm1'}\n",
-      "        }\n",
-      "    ),\n",
-      "    'infra': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n",
-      "        name='infra',\n",
-      "        class_='infrastructure_InfrastructureLayer',\n",
-      "        attributes={'commons_DOMLElement::name': 'infra'},\n",
-      "        associations={\n",
-      "            'infrastructure_InfrastructureLayer::generators': {'v_img'},\n",
-      "            'infrastructure_InfrastructureLayer::networks': {'net1'},\n",
-      "            'infrastructure_InfrastructureLayer::credentials': {'ssh_key'},\n",
-      "            'infrastructure_InfrastructureLayer::secGroups': {'sg'},\n",
-      "            'infrastructure_InfrastructureLayer::nodes': {'ag'}\n",
-      "        }\n",
-      "    ),\n",
-      "    'vm_name': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n",
-      "        name='vm_name',\n",
-      "        class_='commons_SProperty',\n",
-      "        attributes={\n",
-      "            'commons_Property::key': 'vm_name',\n",
-      "            'commons_SProperty::value': 'nginx-host'\n",
-      "        },\n",
-      "        associations={}\n",
-      "    ),\n",
-      "    'vm_flavor': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n",
-      "        name='vm_flavor',\n",
-      "        class_='commons_SProperty',\n",
-      "        attributes={\n",
-      "            'commons_Property::key': 'vm_flavor',\n",
-      "            'commons_SProperty::value': 'small'\n",
-      "        },\n",
-      "        associations={}\n",
-      "    ),\n",
-      "    'vm_key_name': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n",
-      "        name='vm_key_name',\n",
-      "        class_='commons_SProperty',\n",
-      "        attributes={\n",
-      "            'commons_Property::key': 'vm_key_name',\n",
-      "            'commons_SProperty::value': 'user1'\n",
-      "        },\n",
-      "        associations={}\n",
-      "    ),\n",
-      "    'concrete_vm': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n",
-      "        name='concrete_vm',\n",
-      "        class_='concrete_VirtualMachine',\n",
-      "        attributes={'commons_DOMLElement::name': 'concrete_vm'},\n",
-      "        associations={\n",
-      "            'commons_DOMLElement::annotations': {\n",
-      "                'vm_flavor',\n",
-      "                'vm_name',\n",
-      "                'vm_key_name'\n",
-      "            },\n",
-      "            'concrete_VirtualMachine::maps': {'vm1'}\n",
-      "        }\n",
-      "    ),\n",
-      "    'name': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n",
-      "        name='name',\n",
-      "        class_='commons_SProperty',\n",
-      "        attributes={\n",
-      "            'commons_Property::key': 'name',\n",
-      "            'commons_SProperty::value': 'ostack2'\n",
-      "        },\n",
-      "        associations={}\n",
-      "    ),\n",
-      "    'concrete_net': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n",
-      "        name='concrete_net',\n",
-      "        class_='concrete_Network',\n",
-      "        attributes={'commons_DOMLElement::name': 'concrete_net'},\n",
-      "        associations={\n",
-      "            'commons_DOMLElement::annotations': {'name'},\n",
-      "            'concrete_Network::maps': {'net1'}\n",
-      "        }\n",
-      "    ),\n",
-      "    'concrete_vm_image': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n",
-      "        name='concrete_vm_image',\n",
-      "        class_='concrete_VMImage',\n",
-      "        attributes={'commons_DOMLElement::name': 'concrete_vm_image'},\n",
-      "        associations={\n",
-      "            'commons_DOMLElement::annotations': {'name'},\n",
-      "            'concrete_VMImage::maps': {'v_img'}\n",
-      "        }\n",
-      "    ),\n",
-      "    'openstack': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n",
-      "        name='openstack',\n",
-      "        class_='concrete_RuntimeProvider',\n",
-      "        attributes={'commons_DOMLElement::name': 'openstack'},\n",
-      "        associations={\n",
-      "            'concrete_RuntimeProvider::vms': {'concrete_vm'},\n",
-      "            'concrete_RuntimeProvider::networks': {'concrete_net'},\n",
-      "            'concrete_RuntimeProvider::vmImages': {'concrete_vm_image'}\n",
-      "        }\n",
-      "    ),\n",
-      "    'con_infra': mc_openapi.doml_mc.intermediate_model.doml_element.DOMLElement(\n",
-      "        name='con_infra',\n",
-      "        class_='concrete_ConcreteInfrastructure',\n",
-      "        attributes={'commons_DOMLElement::name': 'con_infra'},\n",
-      "        associations={\n",
-      "            'concrete_ConcreteInfrastructure::providers': {'openstack'}\n",
-      "        }\n",
-      "    )\n",
-      "}\n"
-     ]
-    }
-   ],
-   "source": [
-    "IMPLICIT_MODULES.add('doml_mc.intermediate_model.doml_element')\n",
-    "pp.pprint(im)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 9,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "unbound_elems_n = 0\n",
-    "unbound_elems = [f\"unbound{i}\" for i in range(unbound_elems_n)]"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 10,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "from z3 import Solver\n",
-    "\n",
-    "from mc_openapi.doml_mc.z3encoding.metamodel_encoding import (\n",
-    "    def_association_rel_and_assert_constraints,\n",
-    "    def_attribute_rel_and_assert_constraints,\n",
-    "    mk_association_sort_dict,\n",
-    "    mk_attribute_sort_dict,\n",
-    "    mk_class_sort_dict\n",
-    ")\n",
-    "from mc_openapi.doml_mc.z3encoding.im_encoding import (\n",
-    "    assert_im_associations_q,\n",
-    "    assert_im_attributes,\n",
-    "    def_elem_class_f_and_assert_classes,\n",
-    "    mk_elem_sort_dict,\n",
-    "    mk_stringsym_sort_dict\n",
-    ")\n",
-    "from mc_openapi.doml_mc.z3encoding.utils import mk_adata_sort\n",
-    "\n",
-    "solver = Solver()\n",
-    "\n",
-    "class_sort, class_ = mk_class_sort_dict(mm)\n",
-    "assoc_sort, assoc = mk_association_sort_dict(mm)\n",
-    "attr_sort, attr = mk_attribute_sort_dict(mm)\n",
-    "elem_sort, elem = mk_elem_sort_dict(im, unbound_elems)\n",
-    "ss_sort, ss = mk_stringsym_sort_dict(im, mm)\n",
-    "AData = mk_adata_sort(ss_sort)\n",
-    "elem_class_f = def_elem_class_f_and_assert_classes(\n",
-    "    im,\n",
-    "    solver,\n",
-    "    elem_sort,\n",
-    "    elem,\n",
-    "    class_sort,\n",
-    "    class_\n",
-    ")\n",
-    "attr_rel = def_attribute_rel_and_assert_constraints(\n",
-    "    mm,\n",
-    "    solver,\n",
-    "    attr_sort,\n",
-    "    attr,\n",
-    "    class_,\n",
-    "    elem_class_f,\n",
-    "    elem_sort,\n",
-    "    AData,\n",
-    "    ss\n",
-    ")\n",
-    "assert_im_attributes(\n",
-    "    attr_rel,\n",
-    "    solver,\n",
-    "    im,\n",
-    "    mm,\n",
-    "    elem,\n",
-    "    attr_sort,\n",
-    "    attr,\n",
-    "    AData,\n",
-    "    ss\n",
-    ")\n",
-    "assoc_rel = def_association_rel_and_assert_constraints(\n",
-    "    mm,\n",
-    "    solver,\n",
-    "    assoc_sort,\n",
-    "    assoc,\n",
-    "    class_,\n",
-    "    elem_class_f,\n",
-    "    elem_sort,\n",
-    "    inv_assoc\n",
-    ")\n",
-    "assert_im_associations_q(\n",
-    "    assoc_rel,\n",
-    "    solver,\n",
-    "    {k: v for k, v in im.items() if k not in unbound_elems},\n",
-    "    elem,\n",
-    "    assoc_sort,\n",
-    "    assoc,\n",
-    ")"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 11,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "# solver.push()"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "### Metamodel statistics"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 12,
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "Number of classes: 48\n",
-      "Number of tuples in the subclass relation: 125\n",
-      "Number of attributes: 46\n",
-      "Number of attribute assertions: 138\n",
-      "Number of associations: 54\n",
-      "Number of associations assertions: 168\n"
-     ]
-    }
-   ],
-   "source": [
-    "from mc_openapi.doml_mc.intermediate_model.metamodel import get_subclasses_dict\n",
-    "\n",
-    "print(\"Number of classes:\", len(mm))\n",
-    "print(\n",
-    "    \"Number of tuples in the subclass relation:\",\n",
-    "    sum(len(s) for s in get_subclasses_dict(mm).values())\n",
-    ")\n",
-    "n_attrs = sum(len(c.attributes) for c in mm.values())\n",
-    "print(\"Number of attributes:\", n_attrs)\n",
-    "print(\"Number of attribute assertions:\", 3 * n_attrs)\n",
-    "n_assocs = sum(len(c.associations) for c in mm.values())\n",
-    "print(\"Number of associations:\", n_assocs)\n",
-    "print(\"Number of associations assertions:\", 3 * n_assocs + len(inv_assoc))\n",
-    "\n"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {},
-   "source": [
-    "### DOML model statistics"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 13,
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "Number of elements: 24\n",
-      "Number of attributes (IM): 58\n",
-      "Number of associations (IM): 35\n",
-      "Number of string symbols: 40\n",
-      "Number of IM attribute assertions: 24\n",
-      "Number of IM association assertions: 576\n"
-     ]
-    }
-   ],
-   "source": [
-    "n_elems = len(im)\n",
-    "print(\"Number of elements:\", n_elems)\n",
-    "n_attrs_im = sum(len(e.attributes) for e in im.values())\n",
-    "print(\"Number of attributes (IM):\", n_attrs_im)\n",
-    "n_assocs_im = sum(len(a) for e in im.values() for a in e.associations.values())\n",
-    "print(\"Number of associations (IM):\", n_assocs_im)\n",
-    "print(\"Number of string symbols:\", len(ss))\n",
-    "print(\"Number of IM attribute assertions:\", n_elems)\n",
-    "print(\"Number of IM association assertions:\", n_elems ** 2)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 14,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/html": [
-       "<b>sat</b>"
-      ],
-      "text/plain": [
-       "sat"
-      ]
-     },
-     "execution_count": 14,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "solver.check()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 15,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/html": [
-       "[]"
-      ],
-      "text/plain": [
-       "[]"
-      ]
-     },
-     "execution_count": 15,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "solver.unsat_core()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 16,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "(:added-eqs               29920\n",
-       " :arith-make-feasible     8\n",
-       " :arith-max-columns       11\n",
-       " :binary-propagations     811\n",
-       " :conflicts               109\n",
-       " :datatype-accessor-ax    1114\n",
-       " :datatype-constructor-ax 11816\n",
-       " :datatype-splits         1944\n",
-       " :decisions               86083\n",
-       " :del-clause              42\n",
-       " :final-checks            8\n",
-       " :max-generation          4\n",
-       " :max-memory              30.88\n",
-       " :memory                  30.88\n",
-       " :mk-bool-var             4810\n",
-       " :mk-clause               1138\n",
-       " :num-allocs              58273624\n",
-       " :num-checks              1\n",
-       " :propagations            15765\n",
-       " :quant-instantiations    1321\n",
-       " :restarts                3\n",
-       " :rlimit-count            15307867\n",
-       " :time                    1.88)"
-      ]
-     },
-     "execution_count": 16,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "solver.statistics()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 17,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "from z3 import Consts, ForAll, Exists, Implies, And, Or"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 17,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "# All VMs have a network interface.\n",
-    "vm, iface = Consts(\n",
-    "    \"vm iface\", elem_sort\n",
-    ")\n",
-    "vmIfaceAssertion = ForAll(\n",
-    "    [vm],\n",
-    "    Implies(\n",
-    "        elem_class_f(vm) == class_[\"infrastructure_VirtualMachine\"],\n",
-    "        Exists(\n",
-    "            [iface],\n",
-    "            And(\n",
-    "                assoc_rel(vm, assoc[\"infrastructure_ComputingNode::ifaces\"], iface)\n",
-    "            )\n",
-    "        )\n",
-    "    )\n",
-    ")\n",
-    "solver.assert_and_track(vmIfaceAssertion, \"vm_iface\")"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 18,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "# nginx has a source code property\n",
-    "softwareComponent, prop = Consts(\"softwareComponent prop\", elem_sort)\n",
-    "nginxSourceCode = ForAll(\n",
-    "    [softwareComponent],\n",
-    "    Implies(\n",
-    "        And(\n",
-    "            elem_class_f(softwareComponent) == class_[\"application_SoftwareComponent\"],\n",
-    "            attr_rel(softwareComponent, attr[\"commons_DOMLElement::name\"], AData.ss(ss[\"nginx\"]))\n",
-    "        ),\n",
-    "        Exists(\n",
-    "            [prop],\n",
-    "            And(\n",
-    "                elem_class_f(prop) == class_[\"commons_SProperty\"],\n",
-    "                attr_rel(prop, attr[\"commons_Property::key\"], AData.ss(ss[\"source_code\"])),\n",
-    "                assoc_rel(softwareComponent, assoc[\"commons_DOMLElement::annotations\"], prop)\n",
-    "            )\n",
-    "        )\n",
-    "    )\n",
-    ")\n",
-    "solver.assert_and_track(nginxSourceCode, \"nginx_source_code\")"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 19,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/html": [
-       "<b>sat</b>"
-      ],
-      "text/plain": [
-       "sat"
-      ]
-     },
-     "execution_count": 19,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "solver.check()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 20,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "66.31"
-      ]
-     },
-     "execution_count": 20,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "solver.statistics().memory"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 21,
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "[attribute_st_types infrastructure_Rule::toPort = True,\n",
-      " associations sg out_all = True,\n",
-      " associations i1 http = True,\n",
-      " associations ag http = True,\n",
-      " associations vm_flavor con_infra = True,\n",
-      " associations openstack concrete_vm_image = True,\n",
-      " attribute_mult_ub commons_BProperty::value = True,\n",
-      " associations v_img name = True,\n",
-      " attribute_mult_lb infrastructure_Rule::kind = True,\n",
-      " associations vm1 name = True,\n",
-      " attribute_st_types commons_DOMLElement::name = True,\n",
-      " association_mult_ub concrete_FunctionAsAService::maps = True,\n",
-      " associations concrete_vm vm_key_name = True,\n",
-      " associations app openstack = True,\n",
-      " association_inverse infrastructure_Container::generatedFrom infrastructure_ContainerImage::generatedContainers = True,\n",
-      " associations app concrete_vm = True,\n",
-      " associations out_all v_img = True,\n",
-      " association_mult_ub infrastructure_Container::generatedFrom = True,\n",
-      " association_st_classes infrastructure_FunctionAsAService::ifaces = True,\n",
-      " associations net1 ssh = True,\n",
-      " associations con_infra con_infra = True,\n",
-      " associations https concrete_vm = True,\n",
-      " associations sg ssh = True,\n",
-      " associations vm_name v_img = True,\n",
-      " associations ssh_key openstack = True,\n",
-      " association_st_classes infrastructure_Storage::ifaces = True,\n",
-      " associations openstack vm_flavor = True,\n",
-      " associations nginx nginx = True,\n",
-      " attribute_st_types infrastructure_Rule::addressRanges = True,\n",
-      " associations vm_flavor v_img = True,\n",
-      " associations v_img ag = True,\n",
-      " association_st_classes concrete_ComputingGroup::maps = True,\n",
-      " attribute_mult_lb infrastructure_Rule::protocol = True,\n",
-      " associations vm1 ag = True,\n",
-      " associations ag vm_flavor = True,\n",
-      " attribute_mult_ub infrastructure_KeyPair::bits = True,\n",
-      " associations nginx openstack = True,\n",
-      " associations app sg = True,\n",
-      " association_mult_ub commons_Property::reference = True,\n",
-      " associations nginx infra = True,\n",
-      " associations concrete_net vm_key_name = True,\n",
-      " associations https concrete_vm_image = True,\n",
-      " associations v_img vm_name = True,\n",
-      " associations concrete_net openstack = True,\n",
-      " attribute_st_types commons_Property::key = True,\n",
-      " association_mult_ub commons_Deployment::source = True,\n",
-      " associations concrete_vm_image v_img = True,\n",
-      " associations source_code https = True,\n",
-      " associations vm_name vm_flavor = True,\n",
-      " elem_class concrete_vm concrete_VirtualMachine = True,\n",
-      " attribute_mult_ub application_SoftwareComponent::isPersistent = True,\n",
-      " associations https ssh = True,\n",
-      " associations https vm1 = True,\n",
-      " associations ag net1 = True,\n",
-      " associations http source_code = True,\n",
-      " association_mult_ub concrete_VirtualMachine::maps = True,\n",
-      " association_st_classes commons_Deployment::target = True,\n",
-      " associations net1 con_infra = True,\n",
-      " attribute_st_types concrete_ConcreteElement::configurationScript = True,\n",
-      " association_mult_ub infrastructure_VirtualMachine::generatedFrom = True,\n",
-      " associations http vm_key_name = True,\n",
-      " associations vm_name infra = True,\n",
-      " associations ag source_code = True,\n",
-      " associations vm_key_name net1 = True,\n",
-      " attribute_st_types infrastructure_ComputingNode::cost = True,\n",
-      " association_mult_ub infrastructure_NetworkInterface::belongsTo = True,\n",
-      " associations infra ssh = True,\n",
-      " associations out_all concrete_net = True,\n",
-      " associations sg source_code = True,\n",
-      " association_inverse infrastructure_ComputingGroup::groupedNodes infrastructure_ComputingNode::group = True,\n",
-      " associations concrete_vm_image infra = True,\n",
-      " associations source_code out_all = True,\n",
-      " associations ssh sg = True,\n",
-      " associations ssh name = True,\n",
-      " associations http ag = True,\n",
-      " associations out_all concrete_vm_image = True,\n",
-      " association_st_classes concrete_VMImage::maps = True,\n",
-      " associations vm1 openstack = True,\n",
-      " associations v_img source_code = True,\n",
-      " elem_class ssh_key infrastructure_KeyPair = True,\n",
-      " associations vm_flavor app = True,\n",
-      " associations concrete_vm net1 = True,\n",
-      " associations vm_name http = True,\n",
-      " associations app out_all = True,\n",
-      " associations vm_key_name name = True,\n",
-      " attribute_st_types infrastructure_KeyPair::keyfile = True,\n",
-      " associations v_img nginx = True,\n",
-      " associations v_img concrete_net = True,\n",
-      " attribute_st_types infrastructure_KeyPair::user = True,\n",
-      " associations http concrete_vm = True,\n",
-      " association_mult_ub commons_Deployment::target = True,\n",
-      " associations ssh app = True,\n",
-      " associations ssh vm_name = True,\n",
-      " associations source_code ssh_key = True,\n",
-      " associations vm1 ssh_key = True,\n",
-      " associations nginx vm_name = True,\n",
-      " associations http https = True,\n",
-      " attribute_values vm_key_name = True,\n",
-      " associations ssh_key concrete_net = True,\n",
-      " associations infra i1 = True,\n",
-      " associations https https = True,\n",
-      " attribute_st_types infrastructure_Rule::fromPort = True,\n",
-      " associations nginx vm_key_name = True,\n",
-      " associations app nginx = True,\n",
-      " associations v_img v_img = True,\n",
-      " associations sg http = True,\n",
-      " associations con_infra nginx = True,\n",
-      " associations con_infra https = True,\n",
-      " elem_class name commons_SProperty = True,\n",
-      " attribute_mult_ub infrastructure_AutoScalingGroup::max = True,\n",
-      " association_mult_lb concrete_ComputingGroup::maps = True,\n",
-      " attribute_mult_ub application_SoftwareComponent::configFile = True,\n",
-      " associations net1 ag = True,\n",
-      " association_mult_lb commons_Deployment::target = True,\n",
-      " attribute_values con_infra = True,\n",
-      " association_mult_ub concrete_ContainerImage::maps = True,\n",
-      " associations vm_flavor vm_name = True,\n",
-      " associations v_img concrete_vm = True,\n",
-      " associations concrete_vm ssh = True,\n",
-      " associations concrete_vm v_img = True,\n",
-      " attribute_st_types application_SoftwareComponent::configFile = True,\n",
-      " attribute_mult_ub infrastructure_AutoScalingGroup::loadBalancer = True,\n",
-      " associations vm1 v_img = True,\n",
-      " association_st_classes infrastructure_InfrastructureLayer::generators = True,\n",
-      " attribute_mult_ub infrastructure_ComputingNode::cost = True,\n",
-      " attribute_st_types application_SoftwareComponent::licenseCost = True,\n",
-      " associations ssh vm_key_name = True,\n",
-      " associations vm1 app = True,\n",
-      " associations concrete_vm_image name = True,\n",
-      " ...]\n"
-     ]
-    }
-   ],
-   "source": [
-    "m = solver.model()\n",
-    "print(m)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 22,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "from itertools import product\n",
-    "for (e1n, e1), a, (e2n, e2) in product(elem.items(), assoc.values(), elem.items()):\n",
-    "    if (e1n in unbound_elems or e2n in unbound_elems) and m.eval(assoc_rel(e1, a, e2)):\n",
-    "        print(e1, a, e2)"
-   ]
-  }
- ],
- "metadata": {
-  "interpreter": {
-   "hash": "a6678cf6b5907da3ee1c64f7f36cf1b3f0e5fe51f4038e28403f1c01345fc5bd"
-  },
-  "kernelspec": {
-   "display_name": "Python 3.9.9 64-bit",
-   "language": "python",
-   "name": "python3"
-  },
-  "language_info": {
-   "codemirror_mode": {
-    "name": "ipython",
-    "version": 3
-   },
-   "file_extension": ".py",
-   "mimetype": "text/x-python",
-   "name": "python",
-   "nbconvert_exporter": "python",
-   "pygments_lexer": "ipython3",
-   "version": "3.9.12"
-  },
-  "orig_nbformat": 4
- },
- "nbformat": 4,
- "nbformat_minor": 2
-}
diff --git a/mc_openapi/doml_mc/exceptions.py b/mc_openapi/doml_mc/exceptions.py
new file mode 100644
index 0000000000000000000000000000000000000000..a3284438af998cd6cc9a64f15561918db5694f44
--- /dev/null
+++ b/mc_openapi/doml_mc/exceptions.py
@@ -0,0 +1,24 @@
+class BadDOMLException(Exception):
+    def __init__(self, message: str = None, *args: object) -> None:
+        super().__init__(*args)
+        self.message = message or "The submitted DOML contains some kind of error."
+
+class UnsupportedDOMLVersionException(Exception):
+    def __init__(self, message: str = None, *args: object) -> None:
+        super().__init__(*args)
+        self.message = message or "The DOML version is not supported."
+
+class MissingInfrastructureLayerException(Exception):
+    def __init__(self, message: str = None, *args: object) -> None:
+        super().__init__(*args)
+        self.message = message or "Abstract infrastructure layer is missing from DOML."
+
+class NoActiveConcreteLayerException(Exception):
+    def __init__(self, message: str = None, *args: object) -> None:
+        super().__init__(*args)
+        self.message = message or "No active concrete infrastructure layer has been specified in DOML."
+
+class CommonRequirementException(Exception):
+    def __init__(self, message: str = None, *args: object) -> None:
+        super().__init__(*args)
+        self.message = message or "Couldn't get built-in requirements for this DOML version."
\ No newline at end of file
diff --git a/mc_openapi/doml_mc/imc.py b/mc_openapi/doml_mc/imc.py
index 8efd89bdfd1a3e75eeb9f3981e933c2086331e0e..f663d9084f9b867767d7d1d4cb7d46caa223cd39 100644
--- a/mc_openapi/doml_mc/imc.py
+++ b/mc_openapi/doml_mc/imc.py
@@ -1,25 +1,22 @@
 from collections.abc import Callable
 from dataclasses import dataclass
+from typing import Literal
 
-from z3 import (
-    Context, FuncDeclRef, Solver, ExprRef, SortRef, DatatypeSortRef
-)
+from z3 import (Context, DatatypeSortRef, ExprRef, FuncDeclRef, Solver,
+                SortRef, Z3Exception)
 
 from .intermediate_model.doml_element import IntermediateModel
-from .z3encoding.im_encoding import (
-    assert_im_associations_q, assert_im_attributes,
-    def_elem_class_f_and_assert_classes,
-    mk_elem_sort_dict, mk_stringsym_sort_dict
-)
-from .z3encoding.metamodel_encoding import (
-    def_association_rel,
-    def_attribute_rel,
-    mk_association_sort_dict,
-    mk_attribute_sort_dict, mk_class_sort_dict
-)
-from .z3encoding.types import Refs
-from .z3encoding.utils import mk_adata_sort
 from .mc_result import MCResult, MCResults
+from .z3encoding.im_encoding import (assert_im_associations,
+                                     assert_im_attributes,
+                                     def_elem_class_f_and_assert_classes, mk_attr_data_sort,
+                                     mk_elem_sort_dict, mk_stringsym_sort_dict)
+from .z3encoding.metamodel_encoding import (def_association_rel,
+                                            def_attribute_rel,
+                                            mk_association_sort_dict,
+                                            mk_attribute_sort_dict,
+                                            mk_class_sort_dict)
+from .z3encoding.types import Refs
 
 
 @dataclass
@@ -46,14 +43,16 @@ class SMTSorts:
 
 @dataclass
 class Requirement:
-    assert_callable: Callable[[SMTEncoding, SMTSorts], list[ExprRef]]
+    assert_callable: Callable[[SMTEncoding, SMTSorts], ExprRef]
     assert_name: str
     description: str
-    error_description: str
+    error_description: tuple[Literal["BUILTIN", "USER"],
+                             Callable[[Solver, SMTSorts, IntermediateModel], str]]
+    flipped: bool = False
 
 
 class RequirementStore:
-    def __init__(self, requirements: list[Requirement]):
+    def __init__(self, requirements: list[Requirement] = []):
         self.requirements = requirements
         pass
 
@@ -63,6 +62,9 @@ class RequirementStore:
     def get_one_requirement(self, index: int) -> Requirement:
         return self.get_all_requirements()[index]
 
+    def skip_requirements_by_id(self, requirement_ids: list[str]):
+        self.requirements = [r for r in self.requirements if not r.assert_name in requirement_ids]
+
     def __len__(self):
         return len(self.get_all_requirements())
 
@@ -72,75 +74,83 @@ class RequirementStore:
 
 class IntermediateModelChecker:
     def __init__(self, metamodel, inv_assoc, intermediate_model: IntermediateModel):
-        def instantiate_solver():
-            self.z3Context = Context()
-            self.solver = Solver(ctx=self.z3Context)
-
-            class_sort, class_ = mk_class_sort_dict(self.metamodel, self.z3Context)
-            assoc_sort, assoc = mk_association_sort_dict(self.metamodel, self.z3Context)
-            attr_sort, attr = mk_attribute_sort_dict(self.metamodel, self.z3Context)
-            elem_sort, elem = mk_elem_sort_dict(self.intermediate_model, self.z3Context)
-            ss_sort, ss = mk_stringsym_sort_dict(self.intermediate_model, self.metamodel, self.z3Context)
-            AData = mk_adata_sort(ss_sort, self.z3Context)
-            elem_class_f = def_elem_class_f_and_assert_classes(
-                self.intermediate_model,
-                self.solver,
-                elem_sort,
-                elem,
-                class_sort,
-                class_
-            )
-            attr_rel = def_attribute_rel(
-                attr_sort,
-                elem_sort,
-                AData
-            )
-            assert_im_attributes(
-                attr_rel,
-                self.solver,
-                self.intermediate_model,
-                self.metamodel,
-                elem,
-                attr_sort,
-                attr,
-                AData,
-                ss
-            )
-            assoc_rel = def_association_rel(
-                assoc_sort,
-                elem_sort
-            )
-            assert_im_associations_q(
-                assoc_rel,
-                self.solver,
-                {k: v for k, v in self.intermediate_model.items()},
-                elem,
-                assoc_sort,
-                assoc,
-            )
-            self.smt_encoding = SMTEncoding(
-                class_,
-                assoc,
-                attr,
-                elem,
-                ss,
-                elem_class_f,
-                attr_rel,
-                assoc_rel
-            )
-            self.smt_sorts = SMTSorts(
-                class_sort,
-                assoc_sort,
-                attr_sort,
-                elem_sort,
-                ss_sort,
-                AData
-            )
-
         self.metamodel = metamodel
         self.inv_assoc = inv_assoc
         self.intermediate_model = intermediate_model
-        instantiate_solver()
+        self.instantiate_solver()
+
+    def instantiate_solver(self, user_string_values=[]):
+        self.z3Context = Context()
+        self.solver = Solver(ctx=self.z3Context)
+
+        class_sort, class_ = mk_class_sort_dict(self.metamodel, self.z3Context)
+        assoc_sort, assoc = mk_association_sort_dict(
+            self.metamodel, self.z3Context)
+        attr_sort, attr = mk_attribute_sort_dict(
+            self.metamodel, self.z3Context)
+        elem_sort, elem = mk_elem_sort_dict(
+            self.intermediate_model, self.z3Context)
+        str_sort, str = mk_stringsym_sort_dict(
+            self.intermediate_model,
+            self.metamodel,
+            self.z3Context,
+            user_string_values
+        )
+        attr_data_sort = mk_attr_data_sort(str_sort, self.z3Context)
+        elem_class_f = def_elem_class_f_and_assert_classes(
+            self.intermediate_model,
+            self.solver,
+            elem_sort,
+            elem,
+            class_sort,
+            class_
+        )
+        attr_rel = def_attribute_rel(
+            attr_sort,
+            elem_sort,
+            attr_data_sort
+        )
+        assert_im_attributes(
+            attr_rel,
+            self.solver,
+            self.intermediate_model,
+            self.metamodel,
+            elem,
+            attr_sort,
+            attr,
+            attr_data_sort,
+            str
+        )
+        assoc_rel = def_association_rel(
+            assoc_sort,
+            elem_sort
+        )
+        assert_im_associations(
+            assoc_rel,
+            self.solver,
+            {k: v for k, v in self.intermediate_model.items()},
+            elem,
+            assoc_sort,
+            assoc,
+        )
+        self.smt_encoding = SMTEncoding(
+            class_,
+            assoc,
+            attr,
+            elem,
+            str,
+            elem_class_f,
+            attr_rel,
+            assoc_rel
+        )
+        self.smt_sorts = SMTSorts(
+            class_sort,
+            assoc_sort,
+            attr_sort,
+            elem_sort,
+            str_sort,
+            attr_data_sort
+        )
 
     def check_requirements(self, reqs: RequirementStore, timeout: int = 0) -> MCResults:
         self.solver.set(timeout=(timeout * 1000))
@@ -151,9 +161,25 @@ class IntermediateModelChecker:
             self.solver.assert_and_track(
                 req.assert_callable(self.smt_encoding, self.smt_sorts),
                 req.assert_name
-                )
+            )
             res = self.solver.check()
+            req_type, req_err_desc_fn = req.error_description
+            req_is_sat = MCResult.from_z3result(res, flipped=req.flipped)
+            req_id = req.assert_name
+            try:
+                req_time = self.solver.statistics().get_key_value("time")
+            except Z3Exception:
+                req_time = "???"
+
+            results.append((
+                req_is_sat,
+                req_type,
+                req_err_desc_fn(self.solver, self.smt_sorts, self.intermediate_model) if req_is_sat else "",
+                req_id,
+                req.description,
+                req_time
+            ))
             self.solver.pop()
-            results.append((MCResult.from_z3result(res, flipped=True), req.error_description))
 
+        # stats = self.solver.statistics()
         return MCResults(results)
diff --git a/mc_openapi/doml_mc/intermediate_model/__init__.py b/mc_openapi/doml_mc/intermediate_model/__init__.py
index 08c3bb217ef949826b63a77c3fb7e7839f02db0d..31b1c03caa88087d5951e85c4aa9458abc210cad 100644
--- a/mc_openapi/doml_mc/intermediate_model/__init__.py
+++ b/mc_openapi/doml_mc/intermediate_model/__init__.py
@@ -1,2 +1,2 @@
-from .metamodel import MetaModel  # noqa: F401
+from .metamodel import DOMLVersion, MetaModel  # noqa: F401
 from .doml_element import IntermediateModel, DOMLElement  # noqa: F401
diff --git a/mc_openapi/doml_mc/intermediate_model/doml_element.py b/mc_openapi/doml_mc/intermediate_model/doml_element.py
index be2447bb5484d40ec175977165df06a63a719a29..d5caa8e8d1bcdf5c05ca2e78dcda14fbaf815023 100644
--- a/mc_openapi/doml_mc/intermediate_model/doml_element.py
+++ b/mc_openapi/doml_mc/intermediate_model/doml_element.py
@@ -1,4 +1,4 @@
-from typing import Union
+from typing import Union, Optional
 from dataclasses import dataclass
 
 from .metamodel import (
@@ -21,6 +21,7 @@ class DOMLElement:
     # e.g., `"application_SoftwarePackage::isPersistent"`.
     attributes: Attributes
     associations: Associations
+    user_friendly_name: Optional[str]
 
 
 IntermediateModel = dict[str, "DOMLElement"]
diff --git a/mc_openapi/doml_mc/intermediate_model/metamodel.py b/mc_openapi/doml_mc/intermediate_model/metamodel.py
index 963f69570d1af65629f37fb841f45fb225b8f8cd..f1ab8f48b11e4514f7c7c0dca8ebd3d109c9fc33 100644
--- a/mc_openapi/doml_mc/intermediate_model/metamodel.py
+++ b/mc_openapi/doml_mc/intermediate_model/metamodel.py
@@ -1,9 +1,37 @@
+import importlib.resources as ilres
 from dataclasses import dataclass
-from typing import cast, Literal, Optional, Union
+from enum import Enum
+from typing import Literal, Optional, Union, cast
 
 import networkx as nx
+import yaml
+
+from ... import assets
+from ..utils import merge_dicts
+
+class DOMLVersion(Enum):
+    # V1_0 = "v1.0"
+    V2_0 = "v2.0"
+    V2_1 = "v2.1"
+    V2_2 = "v2.2"
+    V2_2_1 = "v2.2.1"
+    V2_3 = "v2.3"
+    V3_0 = "v3.0"
+    V3_1 = "v3.1"
+
+    def get(v: str):
+        """Retrieve DOML version from string.
+        Try to be less pedantic about versions
+        e.g.: 2.0 becomes V2_0"""
+        doml_ver = v.replace(".", "_").replace("v", "V")
+        if doml_ver[0] != "V":
+            doml_ver = "V" + doml_ver
+        return DOMLVersion[doml_ver]
+    
+    def has_DOMLR_support(v: "DOMLVersion"):
+        """DOMLR is available in v2.2 and later"""
+        return v != DOMLVersion.V2_0 and v != DOMLVersion.V2_1
 
-from .._utils import merge_dicts
 
 Multiplicity = tuple[Literal["0", "1"], Literal["1", "*"]]
 
@@ -40,6 +68,11 @@ class DOMLAssociation:
 
 
 MetaModel = dict[str, DOMLClass]
+InverseAssociation = list[tuple[str, str]]
+
+MetaModelDocs: dict[DOMLVersion, dict] = {}
+MetaModels: dict[DOMLVersion, MetaModel] = {}
+InverseAssociations: dict[DOMLVersion, InverseAssociation] = {}
 
 
 def parse_metamodel(mmdoc: dict) -> MetaModel:
@@ -136,6 +169,17 @@ def parse_inverse_associations(doc: dict) -> list[tuple[str, str]]:
     ]
 
 
+def init_metamodels():
+    global MetaModelDocs, MetaModels, InverseAssociations
+    for ver in DOMLVersion:
+        source = ilres.files(assets).joinpath(f"metamodels/doml_meta_{ver.value}.yaml")
+        
+        mmdoc = yaml.load(source.read_text()  , yaml.Loader)
+        MetaModelDocs[ver] = mmdoc
+        MetaModels[ver] = parse_metamodel(mmdoc)
+        InverseAssociations[ver] = parse_inverse_associations(mmdoc)
+
+
 def _find_association_class(
     mm: MetaModel,
     cname: str,
diff --git a/mc_openapi/doml_mc/main.py b/mc_openapi/doml_mc/main.py
new file mode 100644
index 0000000000000000000000000000000000000000..1d8c8934081bf4e78a17361fb74ac781334051a5
--- /dev/null
+++ b/mc_openapi/doml_mc/main.py
@@ -0,0 +1,176 @@
+import logging
+from typing import Optional
+
+import doml_synthesis as DOMLS
+from doml_synthesis import State, builtin_requirements
+
+from mc_openapi.doml_mc import ModelChecker
+from mc_openapi.doml_mc.common_reqs import CommonRequirements
+from mc_openapi.doml_mc.consistency_reqs import get_association_multiplicity_reqs, get_association_type_reqs, get_attribute_multiplicity_reqs, get_attribute_type_reqs, get_inverse_association_reqs
+from mc_openapi.doml_mc.csp_compatibility import \
+    CSPCompatibilityValidator as CSPCompatibility
+from mc_openapi.doml_mc.domlr_parser import (DOMLRTransformer, Parser,
+                                             SynthesisDOMLRTransformer)
+from mc_openapi.doml_mc.exceptions import CommonRequirementException
+from mc_openapi.doml_mc.imc import RequirementStore
+from mc_openapi.doml_mc.intermediate_model.metamodel import (DOMLVersion,
+                                                             MetaModelDocs)
+from mc_openapi.doml_mc.network_address_validator.validate import validate_network_address
+
+
+def init_model(domlx:bytes, doml_ver: DOMLVersion):
+    dmc = ModelChecker(domlx, doml_ver)
+    logging.info("Parsed DOMLX successfully.")
+    return dmc
+
+
+def verify_model(
+        dmc: ModelChecker,
+        external_domlr: Optional[str] = None,
+        threads: int = 2,
+        consistency_checks: bool = False, 
+        skip_builtin_checks: bool = False
+    ):
+    # DOMLR parser
+    domlr_parser = Parser(DOMLRTransformer)
+
+    # General req store
+    req_store = RequirementStore()
+
+    # Store of Requirements and unique string constants
+    user_req_store, user_req_str_consts = RequirementStore(), []
+
+    flags = {}
+
+    # Parse external DOMLR file
+    if external_domlr:
+        user_req_store, user_req_str_consts, flags = domlr_parser.parse(external_domlr)
+
+    # Parse internal DOMLR requirements
+    if DOMLVersion.has_DOMLR_support(dmc.doml_version):
+        func_reqs = dmc.domlr_requirements
+        for _, req_text in func_reqs:
+            doml_req_store, doml_req_str_consts, doml_req_flags = domlr_parser.parse(req_text)
+            user_req_store += doml_req_store
+            user_req_str_consts += doml_req_str_consts
+            flags |= doml_req_flags
+
+    # Remove duplicate tokens   
+    user_req_str_consts = list(set(user_req_str_consts))
+
+    # Built-in requirements
+    if not (flags.get('_ignore_builtin', False) or skip_builtin_checks):
+        try:
+            req_store += CommonRequirements[dmc.doml_version]
+            # Skip selected requirements
+            req_store.skip_requirements_by_id([k for k,v in flags.items() if not k.startswith("_") and v is False])
+        except:
+            logging.error('Failed to get Common Requirements. DOML Version is wrong?')
+            raise CommonRequirementException()
+
+    # Consistency requirements (disabled by default)
+    if flags.get('_check_consistency', False) or consistency_checks:
+        logging.warning("Consistency checks are outdated and may break at any time.")
+        req_store = req_store \
+            + get_attribute_type_reqs(dmc.metamodel) \
+            + get_attribute_multiplicity_reqs(dmc.metamodel) \
+            + get_association_type_reqs(dmc.metamodel) \
+            + get_association_multiplicity_reqs(dmc.metamodel) \
+            + get_inverse_association_reqs(dmc.inv_assoc)
+
+    # Add user requirements at the end
+    req_store += user_req_store
+
+    # Log all requirements to check
+    logging.debug("Checking following requirements: " + ", ".join([k.assert_name for k in req_store.get_all_requirements()]))
+    logging.debug("Flags: { " + ", ".join([f"{k}={v}" for k, v in flags.items()]) + " }")
+
+    # Check satisfiability
+    results = dmc.check_requirements(
+        req_store,
+        threads=threads, 
+        user_str_values=user_req_str_consts,
+        disable_multithreading=(threads == 1)
+    )
+
+    res = results.summarize()
+
+    res['doml_version'] = dmc.doml_version.name
+    res['result'] = res['result'].name
+    res['type'] = 'message'
+
+    # logging.info(res)
+
+    # Check CSP
+    if flags.get('_csp', False):
+        res['csp'] = verify_csp_compatibility(dmc)
+
+    # Validate network
+    res['net_validation'] = validate_network_address(dmc)
+
+    return res
+
+def synthesize_model(dmc: ModelChecker, external_domlr: str, max_tries: int):
+    logging.warn("Synthesis is experimental and might not be up-to-date with the latest DOML.")
+
+    synth_domlr_parser = Parser(SynthesisDOMLRTransformer)
+    mm = MetaModelDocs[dmc.doml_version]
+    im = {
+        k: { 
+            'id': v.id_,
+            'name': v.user_friendly_name,
+            'class': v.class_,
+            'assocs': v.associations,
+            'attrs': v.attributes
+        }
+        for k, v in  dmc.intermediate_model.items()
+    }
+
+    user_req_store, user_req_str_consts = [], []
+
+
+    if external_domlr:
+        user_req_store, user_req_str_consts = synth_domlr_parser.parse(external_domlr, for_synthesis=True)
+
+
+    # Parse internal DOMLR requirements
+    if DOMLVersion.has_DOMLR_support(dmc.doml_version):
+        func_reqs = dmc.domlr_requirements
+        for _, req_text in func_reqs:
+            doml_req_store, doml_req_str_consts, doml_req_flags = synth_domlr_parser.parse(req_text, for_synthesis=True)
+            user_req_store += doml_req_store
+            user_req_str_consts += doml_req_str_consts
+            flags |= doml_req_flags
+    
+    # Remove duplicated strings
+    user_req_str_consts = list(set(user_req_str_consts))
+
+    state = State()
+    # Parse MM and IM
+    state = DOMLS.init_data(
+        state, 
+        doml=im, 
+        metamodel=mm, 
+    )
+
+    reqs = user_req_store
+
+    reqs += builtin_requirements
+
+    state = DOMLS.solve(
+        state, 
+        requirements=reqs, 
+        strings=user_req_str_consts,
+        max_tries=max_tries
+    )
+    # Update state
+    state = DOMLS.save_results(state)
+    # Print output
+    state = DOMLS.check_synth_results(state)
+
+    
+def verify_csp_compatibility(dmc: ModelChecker):
+    res = CSPCompatibility.check(dmc.intermediate_model, dmc.doml_version)
+    res['type'] = 'message'
+    return res
+    
\ No newline at end of file
diff --git a/mc_openapi/doml_mc/mc.py b/mc_openapi/doml_mc/mc.py
index c2b2660409bdab80eae920cfe91f689b07b15652..315f186d8563d281aafd8027a13f8ec0823ee6bc 100644
--- a/mc_openapi/doml_mc/mc.py
+++ b/mc_openapi/doml_mc/mc.py
@@ -1,82 +1,70 @@
-from typing import Optional
-import importlib.resources as ilres
-import yaml
-from joblib import parallel_backend, Parallel, delayed
+import logging
 from multiprocessing import TimeoutError
+from typing import Optional
+
+from joblib import Parallel, delayed, parallel_backend
 
-from .. import assets
-from .intermediate_model.doml_element import (
-    IntermediateModel,
-    reciprocate_inverse_associations
-)
-from .intermediate_model.metamodel import (
-    MetaModel,
-    parse_inverse_associations,
-    parse_metamodel
-)
-from .xmi_parser.doml_model import parse_doml_model
-from .mc_result import MCResult, MCResults
-from .imc import RequirementStore, IntermediateModelChecker
 from .common_reqs import CommonRequirements
-from .consistency_reqs import (
-    get_attribute_type_reqs,
-    get_attribute_multiplicity_reqs,
-    get_association_type_reqs,
-    get_association_multiplicity_reqs,
-    get_inverse_association_reqs
-)
+from .consistency_reqs import (get_association_multiplicity_reqs,
+                               get_association_type_reqs,
+                               get_attribute_multiplicity_reqs,
+                               get_attribute_type_reqs,
+                               get_inverse_association_reqs)
+from .imc import IntermediateModelChecker, RequirementStore
+from .intermediate_model.metamodel import (DOMLVersion, InverseAssociations,
+                                           MetaModels)
+from .mc_result import MCResult, MCResults
+from .xmi_parser.doml_model import parse_doml_model
 
 
 class ModelChecker:
-    metamodel: Optional[MetaModel] = None
-    inv_assoc: Optional[list[tuple[str, str]]] = None
-
-    @staticmethod
-    def init_metamodel():
-        mmdoc = yaml.load(ilres.read_text(assets, "doml_meta.yaml"), yaml.Loader)
-        ModelChecker.metamodel = parse_metamodel(mmdoc)
-        ModelChecker.inv_assoc = parse_inverse_associations(mmdoc)
-
-    def __init__(self, xmi_model: bytes):
-        assert ModelChecker.metamodel and ModelChecker.inv_assoc
-        self.intermediate_model: IntermediateModel = parse_doml_model(xmi_model, ModelChecker.metamodel)
-        reciprocate_inverse_associations(self.intermediate_model, ModelChecker.inv_assoc)
-
-    def check_common_requirements(self, threads: int = 1, consistency_checks: bool = False, timeout: Optional[int] = None) -> MCResults:
-        assert ModelChecker.metamodel and ModelChecker.inv_assoc
-        req_store = CommonRequirements
-        if consistency_checks:
-            req_store = req_store \
-                + get_attribute_type_reqs(ModelChecker.metamodel) \
-                + get_attribute_multiplicity_reqs(ModelChecker.metamodel) \
-                + get_association_type_reqs(ModelChecker.metamodel) \
-                + get_association_multiplicity_reqs(ModelChecker.metamodel) \
-                + get_inverse_association_reqs(ModelChecker.inv_assoc)
+    def __init__(self, xmi_model: bytes, doml_version: Optional[DOMLVersion] = None):
+        self.intermediate_model, self.doml_version, self.domlr_requirements = parse_doml_model(
+            xmi_model, doml_version)
+        self.metamodel = MetaModels[self.doml_version]
+        self.inv_assoc = InverseAssociations[self.doml_version]
+        
+    def check_requirements(
+        self,
+        req_store: RequirementStore,
+        threads: int = 2,
+        user_str_values: list[str] = [],
+        timeout: Optional[int] = None,
+        disable_multithreading: bool = False
+    ) -> MCResults:
+        assert self.metamodel and self.inv_assoc
+ 
 
         def worker(rfrom: int, rto: int):
-            imc = IntermediateModelChecker(ModelChecker.metamodel, ModelChecker.inv_assoc, self.intermediate_model)
+            imc = IntermediateModelChecker(
+                self.metamodel, self.inv_assoc, self.intermediate_model)
             rs = RequirementStore(req_store.get_all_requirements()[rfrom:rto])
+            imc.instantiate_solver(user_str_values)
             return imc.check_requirements(rs)
 
-        if threads <= 1:
-            imc = IntermediateModelChecker(ModelChecker.metamodel, ModelChecker.inv_assoc, self.intermediate_model)
-            reqs = imc.check_requirements(req_store, timeout=(0 if timeout is None else timeout))
-            return reqs
-        else:
-            def split_reqs(n_reqs: int, n_split: int):
-                slice_size = n_reqs // n_split
-                rto = 0
-                while rto < n_reqs:
-                    rfrom = rto
-                    rto = min(rfrom + slice_size, n_reqs)
-                    yield rfrom, rto
+        def split_reqs(n_reqs: int, n_split: int):
+            slice_size = max(n_reqs // n_split, 1)
+
+            rto = 0
+            while rto < n_reqs:
+                rfrom = rto
+                rto = min(rfrom + slice_size, n_reqs)
+                yield rfrom, rto
+
+        try:
+            if disable_multithreading:
+                # Easier debug
+                results =[ worker(0, len(req_store) )]
+
+            else: 
+                with parallel_backend('loky', n_jobs=threads):
+                    results = Parallel(timeout=timeout)(delayed(worker)(
+                        rfrom, rto) for rfrom, rto in split_reqs(len(req_store), threads))            
+
+            ret = MCResults([])
+            for res in results:
+                ret.add_results(res)
 
-            try:
-                with parallel_backend('threading', n_jobs=threads):
-                    results = Parallel(timeout=timeout)(delayed(worker)(rfrom, rto) for rfrom, rto in split_reqs(len(req_store), threads))
-                ret = MCResults([])
-                for res in results:
-                    ret.add_results(res)
-                return ret
-            except TimeoutError:
-                return MCResults([(MCResult.dontknow, "")])
+            return ret
+        except TimeoutError:
+            return MCResults([(MCResult.dontknow, "")])
diff --git a/mc_openapi/doml_mc/mc_result.py b/mc_openapi/doml_mc/mc_result.py
index 78309c1d17958bdd972ce802ec46ac494ea30d5f..8693a421cd1377d942896f59265560382e230532 100644
--- a/mc_openapi/doml_mc/mc_result.py
+++ b/mc_openapi/doml_mc/mc_result.py
@@ -1,4 +1,6 @@
 from enum import Enum
+import logging
+from typing import Literal
 from z3 import CheckSatResult, sat, unsat, unknown
 
 
@@ -9,6 +11,10 @@ class MCResult(Enum):
 
     @staticmethod
     def from_z3result(z3res: CheckSatResult, flipped: bool = False) -> "MCResult":
+        """Returns an Enum which is either sat, unsat or dontknow.
+        If flipped is true, then the sat and unsat are swapped: it's useful when
+        we are evaluating an expression in negative form.
+        """
         if flipped:
             if z3res == sat:
                 return MCResult.unsat
@@ -25,27 +31,60 @@ class MCResult(Enum):
 
 
 class MCResults:
-    dontknow_msg = "Timed out: unable to check some requirements."
+    DONTKNOW_MSG = "Timed out: unable to check some requirements."
+    SATISFIED_MSG = "All requirements are satisfied."
 
-    def __init__(self, results: list[tuple[MCResult, str]]):
+    def __init__(self, results: list[tuple[MCResult, Literal["BUILTIN", "USER"], str, str, str]]):
+        """It receives a list of tuples (result, type, error message, id, desc, time)"""
         self.results = results
 
-    def summarize(self) -> tuple[MCResult, str]:
-        some_unsat = any(res == MCResult.unsat for res, _ in self.results)
-        some_dontknow = any(res == MCResult.dontknow for res, _ in self.results)
+    def summarize(self) -> dict[str, any]:
+        some_unsat = any(res == MCResult.unsat for res, _, _, _, _, _ in self.results)
+        some_dontknow = any(res == MCResult.dontknow for res, _, _, _, _, _ in self.results)
+
+        all_reqs = [
+                        {
+                            "id": id,
+                            "type": type,
+                            "message": msg,
+                            "result": res.name,
+                            "description": desc,
+                            "time": time
+                        }
+                        for res, type, msg, id, desc, time in self.results
+                    ]
+
 
         if some_unsat:
-            err_msg = " ".join(msg for res, msg in self.results if res == MCResult.unsat)
+            builtin_err_msgs = [
+                (id, msg, time) for res, type, msg, id, _, time in self.results if res == MCResult.unsat and type == "BUILTIN"]
+            user_err_msgs = [
+                (id, msg, time) for res, type, msg, id, _, time in self.results if res == MCResult.unsat and type == "USER"]
+
+            # Print to text (instead of HTML)
+            builtin_err_msg = "\n".join([f"[{id}][{time}s] {msg}" for id, msg, time in builtin_err_msgs])
+            user_err_msg = "\n".join([f"[{id}][{time}s] {msg}" for id, msg, time  in user_err_msgs])
+
+            err_msg = ""
+            if builtin_err_msgs:
+                err_msg += '[Built-in]\n' + builtin_err_msg
+            if user_err_msgs:
+                err_msg += '\n[User]\n' + user_err_msg
             if some_dontknow:
-                err_msg = err_msg + MCResults.dontknow_msg
-            return MCResult.unsat, err_msg
+                err_msg += '\n' + MCResults.DONTKNOW_MSG
+            
+            return {
+                'result': MCResult.unsat,
+                'builtin': builtin_err_msgs,
+                'user': user_err_msgs,
+                'dontknow': some_dontknow,
+                'description': err_msg,
+                'all_reqs': all_reqs
+            }
         elif some_dontknow:
-            return MCResult.dontknow, MCResults.dontknow_msg
+            return {'result': MCResult.dontknow, 'description': MCResults.DONTKNOW_MSG }
         else:
-            return MCResult.sat, "All requirements satisfied."
-
-    def add_result(self, result: tuple[MCResult, str]):
-        self.results.append(result)
+            return {'result': MCResult.sat, 'description': MCResults.SATISFIED_MSG, 'all_reqs': all_reqs }
 
     def add_results(self, results: "MCResults"):
         self.results.extend(results.results)
diff --git a/mc_openapi/doml_mc/network_address_validator/__init__.py b/mc_openapi/doml_mc/network_address_validator/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..b64d68b57bb369f04c53eba9a9e436a6fdb7cd1d
--- /dev/null
+++ b/mc_openapi/doml_mc/network_address_validator/__init__.py
@@ -0,0 +1 @@
+from .validate import validate_network_address
\ No newline at end of file
diff --git a/mc_openapi/doml_mc/network_address_validator/validate.py b/mc_openapi/doml_mc/network_address_validator/validate.py
new file mode 100644
index 0000000000000000000000000000000000000000..5cbcdc6dd54a482a895db72e1f57a790b3e58755
--- /dev/null
+++ b/mc_openapi/doml_mc/network_address_validator/validate.py
@@ -0,0 +1,275 @@
+import logging
+from mc_openapi.doml_mc.intermediate_model import DOMLElement
+from mc_openapi.doml_mc.mc import ModelChecker
+from ipaddress import IPv4Address, IPv4Network
+
+
+BASE_ADDR = '0.0.0.0'
+
+
+CONCRETE_NETWORK = 'concrete_Network'
+# associations
+ASSOC_SUBNETS = 'infrastructure_Network::subnets'
+ASSOC_CONCRETE_SUBNETS = 'concrete_Network::subnets'
+ASSOC_CONCRETE_MAPS = 'concrete_Network::maps'
+ASSOC_GATEWAYS = 'infrastructure_Network::gateways'
+ASSOC_NETIFACE = 'infrastructure_Network::connectedIfaces'
+
+# attributes
+ATTR_NET_CIDR = 'infrastructure_Network::cidr'
+ATTR_GATEWAY_ADDRESS = 'infrastructure_InternetGateway::address'
+ATTR_NETIFACE_ADDRESS = 'infrastructure_NetworkInterface::endPoint'
+ATTR_PROTOCOL = 'infrastructure_Network::protocol'
+ATTR_CONCRETE_PROTOCOL = 'concrete_Network::protocol'
+ATTR_CONCRETE_ADDRESS_RANGE = 'concrete_Network::addressRange'
+
+def validate_network_address(imc: ModelChecker):
+    """
+    HOW IT WORKS:
+
+    * Infrastructure Layer
+        - [n] Network.protocol
+        - [e] InternetGateway.address
+        - [e] NetworkInterface.endPoint
+    * Concrete Layer
+        - [n] Network.protocol
+        - [n] Network.addressRange
+        - [n] Subnet.addressRange
+
+    before MC
+    validate network
+    generate report
+    attach report to HTML output
+    """
+    im = imc.intermediate_model
+
+    # warnings: list[str] = []
+    warnings: list[str] = []
+
+    ## Helpers ##
+    def get_attr(elem: DOMLElement, attr_id: str):
+        if elem := elem.attributes.get(attr_id):
+            return elem[0]
+        return None
+        
+    def get_assocs(elem: DOMLElement, assoc_id: str):
+        return elem.associations.get(assoc_id, [])
+
+    def get_elem(elem: DOMLElement, assoc_id: str):
+        assocs = list(get_assocs(elem, assoc_id))
+        if len(assocs) >= 1:
+            return im.get(assocs[0])
+        return None
+
+    def validate_net(cnet: DOMLElement, parent_net: DOMLElement | None = None):
+        
+        if (parent_net):
+            check_proper_subnet(cnet, parent_net)
+            
+        if inet := get_elem(cnet, ASSOC_CONCRETE_MAPS):
+            check_infr_and_conc_protocol_match(inet, cnet)
+            check_cidr_and_address_range(inet, cnet)
+            check_gateway_belongs_to_network(inet, cnet)
+            check_iface_belongs_to_network(inet, cnet)
+
+        debug =  f"{cnet.user_friendly_name} [concrete]\n"
+        debug += f"\tprotocol={get_attr(cnet, ATTR_CONCRETE_PROTOCOL)}\n"
+        debug += f"\taddress_range={get_attr(cnet, ATTR_CONCRETE_ADDRESS_RANGE)}\n"
+        debug += f"\tsubnets=\t{get_assocs(cnet, ASSOC_CONCRETE_SUBNETS)}\n"
+        if inet:
+            debug += f"{inet.user_friendly_name} [infrastructure]\n"
+            debug += f"\tprotocol={get_attr(inet, ATTR_PROTOCOL)}\n"
+            debug += f"\tcidr={get_attr(inet, ATTR_NET_CIDR)}\n"
+            debug += f"\tsubnets=\t{get_assocs(inet, ASSOC_SUBNETS)}\n"
+            debug += f"\tifaces=\t{get_assocs(inet, ASSOC_NETIFACE)}\n"
+            debug += f"\tgateways=\t{get_assocs(inet, ASSOC_GATEWAYS)}\n"
+        debug += "\n"
+        # print(debug)
+
+        csubnet_ids = get_assocs(cnet, ASSOC_CONCRETE_SUBNETS)
+        for csubnet_id in csubnet_ids:
+            if csubnet := im.get(csubnet_id):
+
+                validate_net(csubnet, cnet)
+
+    ## Checks ##
+    def check_infr_and_conc_protocol_match(inet: DOMLElement, cnet: DOMLElement):
+        """Checks if the protocol of an infrastructure network matches the respective protocol of its concrete counterpart."""
+        iprot = get_attr(inet, ATTR_PROTOCOL)
+        cprot = get_attr(cnet, ATTR_CONCRETE_PROTOCOL)
+        if iprot and cprot and iprot != cprot:
+            warnings.append(f"Protocol of infrastructure network '{inet.user_friendly_name}' must match protocol of concrete network '{cnet.user_friendly_name}'.")
+
+    def check_cidr_and_address_range(inet: DOMLElement, cnet: DOMLElement, warnings=warnings):
+        """Checks if the addressRange of a concrete network respects the CIDR specified in the infrastructure layer."""
+        cidr = get_attr(inet, ATTR_NET_CIDR)
+        addr_range = get_attr(cnet, ATTR_CONCRETE_ADDRESS_RANGE)
+        if cidr and addr_range:
+            try:
+                addr_range = IPv4Network(addr_range)
+                if addr_range.prefixlen != cidr:
+                    warnings.append(f"CIDR ({cidr}) of infrastructure network '{inet.user_friendly_name}' does not match the address range of concrete network '{cnet.user_friendly_name}'.")
+            except:
+                warnings.append(f"Failed to parse concrete network '{cnet.user_friendly_name}' address range as an IPv4Network.")
+            
+    def check_proper_subnet(cnet: DOMLElement, parent_net: DOMLElement):
+        """Checks if a subnet address range respects the parent net."""
+        addr_range = get_attr(cnet, ATTR_CONCRETE_ADDRESS_RANGE)
+        parent_addr_range = get_attr(parent_net, ATTR_CONCRETE_ADDRESS_RANGE)
+        if addr_range and parent_addr_range:
+            try: 
+                addr_range = IPv4Network(addr_range)
+                parent_addr_range = IPv4Network(parent_addr_range)
+
+                if not addr_range.subnet_of(parent_addr_range):
+                    warnings.append(f"Subnet '{cnet.user_friendly_name}' is not a proper subnet of '{parent_net.user_friendly_name}'.")
+            except:
+                warnings.append(f"Failed to parse concrete network '{cnet.user_friendly_name}' or '{parent_net.user_friendly_name}' address range as an IPv4Network.")
+
+    def check_gateway_belongs_to_network(inet: DOMLElement, cnet: DOMLElement):
+        """Checks if the address of the gateways of a network belongs to that network address range."""
+        addr_range = get_attr(cnet, ATTR_CONCRETE_ADDRESS_RANGE)
+        gateway_ids = get_assocs(inet, ASSOC_GATEWAYS)
+
+        if addr_range and gateway_ids:
+            for gateway_id in gateway_ids:
+                if gateway := im.get(gateway_id):
+                    addr_gateway = get_attr(gateway, ATTR_GATEWAY_ADDRESS)
+                    if addr_gateway:
+                        try:
+                            addr_range = IPv4Network(addr_range)
+                            addr_gateway = IPv4Address(addr_gateway)
+                            if addr_gateway not in addr_range:
+                                warnings.append(f"Gateway '{gateway.user_friendly_name}' does not belong to network '{cnet.user_friendly_name}'.")
+                        except:
+                            warnings.append(f"Failed to parse concrete network {cnet.user_friendly_name} address range or its gateway address.")
+
+    def check_iface_belongs_to_network(inet: DOMLElement, cnet: DOMLElement):
+        """Checks if the address of the network interfaces of a network belongs to that network address range."""
+        addr_range = get_attr(cnet, ATTR_CONCRETE_ADDRESS_RANGE)
+        iface_ids = get_assocs(inet, ASSOC_NETIFACE)
+
+        if addr_range and iface_ids:
+            for iface_id in iface_ids:
+                if iface := im.get(iface_id):
+                    addr_iface = get_attr(iface, ATTR_NETIFACE_ADDRESS)
+                    if addr_iface:
+                        try:
+                            addr_range = IPv4Network(addr_range)
+                            addr_iface = IPv4Address(addr_iface)
+                            if addr_iface not in addr_range:
+                                warnings.append(f"Network Interface '{addr_iface.user_friendly_name}' does not belong to network '{cnet.user_friendly_name}'.")
+                        except Exception as e:
+                            print(e)
+                            warnings.append(f"Failed to parse concrete network {cnet.user_friendly_name} address range or its associated network interface '{iface.user_friendly_name}' address.")
+
+
+
+
+    concrete_networks = [e for e in im.values() if e.class_ == CONCRETE_NETWORK]
+
+    # print('-'*20)
+    # print('[DEBUG] Network Validation')
+
+    for cnet in concrete_networks:
+        validate_net(cnet)
+               
+    # print('-'*20)
+    # print(warnings)
+    # print('-'*20)
+
+    # networks = [e for e in im.values() if e.class_ == 'concrete_Network']
+    # subnets = [e for e in im.values() if e.class_ == 'infrastructure_Subnet']
+    # ifaces = [e for e in im.values() if e.class_ == 'infrastructure_NetworkInterface']
+
+
+    # def visit_subnet(net: DOMLElement, acc: list):
+    #     """Recursively navigate subnets to populate the `acc` list with all the subnet in a network."""
+    #     for subnet in get_assocs(net, ASSOC_SUBNETS):
+    #         subnet = im[subnet]
+    #         subnet_addr = fix_invalid_address(get_attr(subnet, ATTR_NET_ADDRESS), net, warnings)
+    #         acc.append((subnet, IPv4Network(subnet_addr)))
+    #         visit_subnet(subnet, acc)
+
+    # def fix_invalid_address(address: any, net: DOMLElement, warning: list):
+    #     # TODO: Use a match statement or use regexps once syntax for CIDR/Address is clear
+    #     if isinstance(address, str) and address.startswith('/'):
+    #         warning.append(("Network", f"Net '{net.user_friendly_name}' has an incomplete address: '{address}'. '0.0.0.0' has been temporarily assigned."))
+    #         return f"{BASE_ADDR}{address}"
+
+    #     return address
+
+
+    # for network in networks:
+
+    #     warning = []
+
+    #     # Tuple(elem, cidr)
+    #     subnets: list[tuple[DOMLElement, IPv4Network]] = []
+    #     # Tuple(elem, address)
+    #     addresses: list[tuple[DOMLElement, IPv4Address]] = []
+
+    #     # Add subnets (Networks)
+    #     visit_subnet(network, subnets)
+
+    #     # pprint("SUBNETS:")
+    #     # pprint(subnets)
+
+    #     # Add addresses (gateways, ifaces)
+    #     for gateway in get_assocs(network, ASSOC_GATEWAYS):
+    #         gateway = im[gateway]
+    #         if gateway_address := get_attr(gateway, ATTR_GATEWAY_ADDRESS):
+    #             addresses.append((gateway, IPv4Address(gateway_address)))
+
+    #     for iface in ifaces:
+    #         if owner_id := get_assocs(iface, ASSOC_IFACE_NET):
+    #             owner = im[list(owner_id)[0]]
+    #             if owner.id_ in [s.id_ for (s, _) in subnets] + [network.id_]:
+    #                 if ((iface_address := get_attr(iface, ATTR_NETIFACE_ADDRESS))
+    #                 and (owner_address := get_attr(owner, ATTR_NET_ADDRESS))):
+    #                     owner_address = fix_invalid_address(owner_address, owner, warning)
+    #                     iface_address = IPv4Address(iface_address)
+    #                     owner_address = IPv4Network(owner_address)
+    #                     # TODO: Remove?
+    #                     logging.info(f"{iface.user_friendly_name} ({iface_address}) belongs to {owner.user_friendly_name} ({owner_address})? {iface_address in owner_address.hosts()}")
+
+    #                     addresses.append((iface, iface_address))
+    #             else:
+    #                 logging.info(f"NetworkInterface '{iface.user_friendly_name}' does not belong to net '{owner.user_friendly_name}'.")
+    #                 warning.append((
+    #                     "Address", f"NetworkInterface '{iface.user_friendly_name}' does not belong to net '{owner.user_friendly_name}'."
+    #                 ))
+
+    #     # Validate Network and Subnets
+    #     net_addr = fix_invalid_address(get_attr(network, ATTR_NET_ADDRESS), network, warning)
+    #     # prepend 0.0.0.0 if starts with / i guess, print a warning
+    #     print(f"{net_addr}\t{network.user_friendly_name}")
+
+    #     net = IPv4Network(net_addr)
+
+    #     if len(subnets) > 0:
+    #         for (obj, sn) in subnets:
+    #             logging.info(f"{sn}\t{obj.user_friendly_name} belongs? {sn.subnet_of(net)}")
+    #             if not sn.subnet_of(net):
+    #                 warning.append((
+    #                     "Subnet", f"Subnet {obj.user_friendly_name} ({sn}) does not belong to net '{network.user_friendly_name}' ({net_addr})."
+    #                 ))
+    #     else:
+    #         print("No subnets found!")
+
+    #     # Validate addresses (again)
+    #     for (obj, addr) in addresses:
+    #         if addr not in net.hosts():
+    #             warning.append((
+    #                 "Address", f"'{obj.user_friendly_name}' [{obj.class_}] ({addr}) does not belong to net '{network.user_friendly_name}' ({net_addr})."
+    #             ))
+    #         logging.info(f"NetworkInterface '{obj.user_friendly_name}' ({addr}) belong to net '{network.user_friendly_name}' ({net_addr})? {addr in net.hosts()}")
+
+    #     warnings.append((network.user_friendly_name, list(set(warning))))
+
+    return warnings
+        
+    
+
+  
+
diff --git a/mc_openapi/doml_mc/_utils.py b/mc_openapi/doml_mc/utils.py
similarity index 86%
rename from mc_openapi/doml_mc/_utils.py
rename to mc_openapi/doml_mc/utils.py
index 458c453bc55b6d4975d1cb4c61bd836f206177f6..ac0a3c7e1688c4ec5ece0f1a9c8b6968754b8a10 100644
--- a/mc_openapi/doml_mc/_utils.py
+++ b/mc_openapi/doml_mc/utils.py
@@ -1,10 +1,11 @@
 from typing import TypeVar
 from collections.abc import Iterable
 
-
 _K = TypeVar("_K")
 _V = TypeVar("_V")
 
-
 def merge_dicts(it: Iterable[dict[_K, _V]]) -> dict[_K, _V]:
     return dict(kv for d in it for kv in d.items())
+
+def Iff(a, b):
+    return a == b
diff --git a/mc_openapi/doml_mc/xmi_parser/__init__.py b/mc_openapi/doml_mc/xmi_parser/__init__.py
index 381f99a5015e215f99c790d736aaf19381518b65..bd8687bbfaa74eaf679c6de2bae1bcd0c9dc1932 100644
--- a/mc_openapi/doml_mc/xmi_parser/__init__.py
+++ b/mc_openapi/doml_mc/xmi_parser/__init__.py
@@ -1,3 +1 @@
-from .doml_model import parse_doml_model, init_doml_rset  # noqa: F401
-
-init_doml_rset()
+from .doml_model import parse_doml_model  # noqa: F401
diff --git a/mc_openapi/bytes_uri.py b/mc_openapi/doml_mc/xmi_parser/bytes_uri.py
similarity index 100%
rename from mc_openapi/bytes_uri.py
rename to mc_openapi/doml_mc/xmi_parser/bytes_uri.py
diff --git a/mc_openapi/doml_mc/xmi_parser/doml_model.py b/mc_openapi/doml_mc/xmi_parser/doml_model.py
index ccee10de3c1e746dec2ed9b8d24652b13354d323..05a13d33823bd9e0135706380a7708b5d76e6eef 100644
--- a/mc_openapi/doml_mc/xmi_parser/doml_model.py
+++ b/mc_openapi/doml_mc/xmi_parser/doml_model.py
@@ -1,68 +1,126 @@
 import copy
 import importlib.resources as ilres
-from ipaddress import ip_address, ip_network
+import logging
+import sys
+from typing import Optional, Tuple
 
-from mc_openapi import assets
-from mc_openapi.bytes_uri import BytesURI
+from lxml import etree
 from pyecore.ecore import EObject
 from pyecore.resources import ResourceSet
 
-from ..intermediate_model.doml_element import Attributes, IntermediateModel
-from ..intermediate_model.metamodel import MetaModel
-from .ecore import ELayerParser, SpecialParser
+from mc_openapi import assets
+from mc_openapi.doml_mc.exceptions import BadDOMLException, MissingInfrastructureLayerException, NoActiveConcreteLayerException, UnsupportedDOMLVersionException
 
+from ..intermediate_model.doml_element import (
+    IntermediateModel, reciprocate_inverse_associations)
+from ..intermediate_model.metamodel import (DOMLVersion, InverseAssociations,
+                                            MetaModels)
+from .bytes_uri import BytesURI
+from .ecore import ELayerParser
+from .special_parsers import SpecialParsers
 
-doml_rset = None
-def init_doml_rset():  # noqa: E302
-    global doml_rset
-    rset = ResourceSet()
-    resource = rset.get_resource(BytesURI(
-        "doml", bytes=ilres.read_binary(assets, "doml.ecore")
-    ))
-    doml_metamodel = resource.contents[0]
+doml_rsets = {}
+def init_doml_rsets():  # noqa: E302
+    global doml_rsets
+    for ver in DOMLVersion:
+        rset = ResourceSet()
+        source = ilres.files(assets).joinpath(f"metamodels/doml_{ver.value}.ecore")
+        resource = rset.get_resource(BytesURI(
+            "doml", bytes=source.read_bytes()
+        ))
+        doml_metamodel = resource.contents[0]
 
-    rset.metamodel_registry[doml_metamodel.nsURI] = doml_metamodel
-    for subp in doml_metamodel.eSubpackages:
-        rset.metamodel_registry[subp.nsURI] = subp
+        rset.metamodel_registry[doml_metamodel.nsURI] = doml_metamodel
+        # .ecore file is loaded in the rset as a metamodel
+        for subp in doml_metamodel.eSubpackages:
+            rset.metamodel_registry[subp.nsURI] = subp
 
-    doml_rset = rset
+        doml_rsets[ver] = rset
 
 
-def get_rset():
-    assert doml_rset is not None
-    return copy.copy(doml_rset)
+def get_rset(doml_version: DOMLVersion) -> ResourceSet:
+    return copy.copy(doml_rsets[doml_version])
 
 
-def parse_xmi_model(raw_model: bytes) -> EObject:
-    rset = get_rset()
+def parse_xmi_model(raw_model: bytes, doml_version: DOMLVersion) -> EObject:
+    rset = get_rset(doml_version)
     doml_uri = BytesURI("user_doml", bytes=raw_model)
     resource = rset.create_resource(doml_uri)
     resource.load()
     return resource.contents[0]
 
-
-def parse_doml_model(raw_model: bytes, mm: MetaModel) -> IntermediateModel:
-    def parse_network_address_range(arange: str) -> Attributes:
-        ipnet = ip_network(arange)
-        return {"address_lb": [int(ipnet[0])], "address_ub": [int(ipnet[-1])]}
-
-    def parse_iface_address(addrport: str) -> Attributes:
-        addr, _, port = addrport.rpartition(":")
-        if addr == "":
-            addr = port
-        return {"endPoint": [int(ip_address(addr))]}
-
-    model = parse_xmi_model(raw_model)
-
-    sp = SpecialParser(mm, {
-        ("infrastructure_Network", "addressRange"): parse_network_address_range,
-        ("infrastructure_NetworkInterface", "endPoint"): parse_iface_address,
-        ("commons_FProperty", "value"): lambda fval: {"value": [str(fval)]},
-    })
-    elp = ELayerParser(mm, sp)
-    elp.parse_elayer(model.application)
-    elp.parse_elayer(model.infrastructure)
-    elp.parse_elayer(model.activeConfiguration)
-    im = elp.parse_elayer(model.activeInfrastructure)
-
-    return im
+DOMLRRawRequirements = list[tuple[str, str]]
+
+def parse_doml_model(raw_model: bytes, doml_version: Optional[DOMLVersion]) -> Tuple[IntermediateModel, DOMLVersion, Optional[DOMLRRawRequirements]]:    
+    # if doml_version is None:
+    #     doml_version = infer_domlx_version(raw_model)
+
+    # Try every DOML version until one works!
+    if doml_version is None:
+
+        doml_versions = [x for x in DOMLVersion]
+        # Use the most recent DOML version first
+        doml_versions.reverse() 
+
+        def get_model(raw_model, doml_version):
+            try:
+                dv = doml_versions.pop(0)
+                doml_version = dv
+                parsed_xmi_model = parse_xmi_model(raw_model, dv)
+                # Try to extract the user-specified version from the DOML
+                try:
+                    model_version = parsed_xmi_model.version
+                    if model_version:
+                        try:
+                            dv = DOMLVersion.get(model_version)
+                            return parse_xmi_model(raw_model, dv), dv
+                        except:
+                            MSG_ERR_INVALID_DOML_VERSION = f"DOML requires version \"{model_version}\", but could not parse it with that version. Is the version valid?"
+                            logging.error(MSG_ERR_INVALID_DOML_VERSION)
+                            raise UnsupportedDOMLVersionException(MSG_ERR_INVALID_DOML_VERSION)
+                except:
+                    pass
+                # DOML version is not specified, proceed as usual 
+                return parsed_xmi_model, dv
+            except Exception as e:
+                logging.info(f"Couldn't parse with DOML {dv.value}. Trying another version...")
+                if len(doml_versions) == 0:
+                    MSG_ERR_NO_DOML_VERSIONS = "No other compatible DOML versions found!"
+                    logging.error(MSG_ERR_NO_DOML_VERSIONS)
+                    raise UnsupportedDOMLVersionException(MSG_ERR_NO_DOML_VERSIONS)
+                else:
+                    return get_model(raw_model, doml_version)
+
+        model, doml_version = get_model(raw_model, doml_version)
+    else: # if user specifies DOML version, respect that choice!
+        try:
+            model = parse_xmi_model(raw_model, doml_version)
+        except:
+            raise BadDOMLException("Parsing of DOML failed. Perhaps you are using the wrong DOML version or IDE?")
+
+    logging.info(f"Model '{model.name}' parsed as DOML {doml_version.value}")
+
+    elp = ELayerParser(MetaModels[doml_version], SpecialParsers[doml_version])
+    if model.application:
+        elp.parse_elayer(model.application)
+    if model.infrastructure:
+        elp.parse_elayer(model.infrastructure)
+    else:
+        raise MissingInfrastructureLayerException()
+    if model.activeConfiguration:
+        elp.parse_elayer(model.activeConfiguration)
+    if model.activeInfrastructure:
+        im = elp.parse_elayer(model.activeInfrastructure)
+    else:
+        raise NoActiveConcreteLayerException()
+
+    reciprocate_inverse_associations(im, InverseAssociations[doml_version])
+
+    # If there are DOMLR requirements
+    try:
+        domlr = model.functionalRequirements.items
+        domlr = [(req.name, req.description.replace("```", "")) for req in domlr]
+        logging.info("Found DOMLR requirements in DOML model.")
+    except Exception:
+        domlr = None
+    return im, doml_version, domlr
diff --git a/mc_openapi/doml_mc/xmi_parser/ecore.py b/mc_openapi/doml_mc/xmi_parser/ecore.py
index 022290ada8381df89d77cf8f4ff558a8f38086f6..69f858d914c75aa7fefdc684d27a6b23a060adf8 100644
--- a/mc_openapi/doml_mc/xmi_parser/ecore.py
+++ b/mc_openapi/doml_mc/xmi_parser/ecore.py
@@ -1,5 +1,6 @@
+import logging
 import sys
-from typing import Callable
+from typing import Callable, Optional
 
 from pyecore.ecore import EEnumLiteral, EObject, EOrderedSet, EClass
 
@@ -74,7 +75,7 @@ class ELayerParser:
                     elif isinstance(val, EOrderedSet):
                         raw_attrs[eAttr.name] = [str(v) if isinstance(v, EEnumLiteral) else v for v in val]
                     else:
-                        print("Attribute", eAttr.name, "has value", val, "of unexpected type.", file=sys.stderr)
+                        logging.error(f"Attribute {eAttr.name} has value {val} of unexpected type.")
         attrs = parse_attributes(raw_attrs, mm_class, self.mm)
 
         # Get all references and process them
@@ -89,14 +90,13 @@ class ELayerParser:
         assocs = parse_associations(raw_assocs, mm_class, self.mm)
 
         self.im[name] = DOMLElement(
-            id_=name, class_=mm_class, attributes=attrs, associations=assocs
+            id_=name, class_=mm_class, attributes=attrs, associations=assocs,
+            user_friendly_name=ELayerParser.get_user_friendly_name(doc)
         )
         return name
 
-    def getUniqueName(self):
-        name = f"__generated_name__{self.nextUniqueId}"
-        self.nextUniqueId += 1
-        return name
-
     def mangle_eclass_name(eClass: EClass) -> str:
         return eClass.ePackage.name + "_" + eClass.name
+
+    def get_user_friendly_name(doc: EObject) -> Optional[str]:
+        return getattr(doc, "name", None)
diff --git a/mc_openapi/doml_mc/xmi_parser/special_parsers.py b/mc_openapi/doml_mc/xmi_parser/special_parsers.py
new file mode 100644
index 0000000000000000000000000000000000000000..6509d13e4f6c9a4c6410a60e13072029fbd14820
--- /dev/null
+++ b/mc_openapi/doml_mc/xmi_parser/special_parsers.py
@@ -0,0 +1,97 @@
+from ipaddress import ip_address, ip_network
+
+from .ecore import SpecialParser
+from ..intermediate_model.metamodel import DOMLVersion, MetaModels
+from ..intermediate_model.doml_element import Attributes
+
+
+SpecialParsers: dict[DOMLVersion, SpecialParser] = {}
+
+
+def parse_network_address_range(arange: str) -> Attributes:
+    ipnet = ip_network(arange)
+    return {"address_lb": [int(ipnet[0])], "address_ub": [int(ipnet[-1])]}
+
+
+def parse_iface_address(addrport: str) -> Attributes:
+    addr, _, port = addrport.rpartition(":")
+    if addr == "":
+        addr = port
+        if addr == "":
+            raise Exception(f"Interface address with value '{addrport}' is not valid. It should be 'x.x.x.x/cidr'.")
+    return {"endPoint": [int(ip_address(addr))]}
+
+
+def parse_memory_mb(mem: str) -> Attributes:
+    return {"memory_mb":  [int(mem)], "memory_kb": [int(mem * 1024)]}
+
+
+def parse_fproperty(fval: str) -> Attributes:
+    return {"value": [str(fval)]}
+
+
+def parse_cidr(arange: str) -> Attributes:
+    attrs: Attributes = {"addressRange": [arange]}
+    if arange[0] == "/":
+        try:
+            attrs["cidr"] = [int(arange[1:])]
+        except (ValueError, IndexError):
+            pass
+    return attrs
+
+
+def init_special_parsers():
+    global SpecialParsers
+    assert len(MetaModels) > 0
+
+    attribute_parsers = {
+        # DOMLVersion.1_0: {
+        #     ("infrastructure_Network", "addressRange"): parse_network_address_range,
+        #     ("infrastructure_NetworkInterface", "endPoint"): parse_iface_address,
+        #     ("commons_FProperty", "value"): parse_fproperty,
+        # },
+        DOMLVersion.V2_0: {
+            ("infrastructure_Network", "addressRange"): parse_network_address_range,
+            ("infrastructure_NetworkInterface", "endPoint"): parse_iface_address,
+            ("infrastructure_ComputingNode", "memory_mb"): parse_memory_mb,
+            ("commons_FProperty", "value"): parse_fproperty,
+        },
+        DOMLVersion.V2_1: {
+            ("infrastructure_Network", "addressRange"): parse_cidr,
+            ("infrastructure_NetworkInterface", "endPoint"): parse_iface_address,
+            ("infrastructure_ComputingNode", "memory_mb"): parse_memory_mb,
+            ("commons_FProperty", "value"): parse_fproperty,
+        },
+        DOMLVersion.V2_2: {
+            ("infrastructure_Network", "addressRange"): parse_cidr,
+            ("infrastructure_NetworkInterface", "endPoint"): parse_iface_address,
+            ("infrastructure_ComputingNode", "memory_mb"): parse_memory_mb,
+            ("commons_FProperty", "value"): parse_fproperty,
+        },
+        DOMLVersion.V2_2_1: {
+            ("infrastructure_Network", "addressRange"): parse_cidr,
+            ("infrastructure_NetworkInterface", "endPoint"): parse_iface_address,
+            ("infrastructure_ComputingNode", "memory_mb"): parse_memory_mb,
+            ("commons_FProperty", "value"): parse_fproperty,
+        },
+        DOMLVersion.V2_3: {
+            ("infrastructure_Network", "addressRange"): parse_cidr,
+            ("infrastructure_NetworkInterface", "endPoint"): parse_iface_address,
+            ("infrastructure_ComputingNode", "memory_mb"): parse_memory_mb,
+            ("commons_FProperty", "value"): parse_fproperty,
+        },
+        DOMLVersion.V3_0: {
+            ("infrastructure_Network", "addressRange"): parse_cidr,
+            ("infrastructure_NetworkInterface", "endPoint"): parse_iface_address,
+            ("infrastructure_ComputingNode", "memory_mb"): parse_memory_mb,
+            ("commons_FProperty", "value"): parse_fproperty,
+        },
+        DOMLVersion.V3_1: {
+            ("infrastructure_Network", "addressRange"): parse_cidr,
+            ("infrastructure_NetworkInterface", "endPoint"): parse_iface_address,
+            ("infrastructure_ComputingNode", "memory_mb"): parse_memory_mb,
+            ("commons_FProperty", "value"): parse_fproperty,
+        }
+    }
+    for ver in DOMLVersion:
+        SpecialParsers[ver] = SpecialParser(MetaModels[ver], attribute_parsers[ver])
diff --git a/mc_openapi/doml_mc/z3encoding/im_encoding.py b/mc_openapi/doml_mc/z3encoding/im_encoding.py
index 31948d9eb04de6e6300ab5ccac03a59c53b35968..533ca401735a8368d913977c4994def3c2437577 100644
--- a/mc_openapi/doml_mc/z3encoding/im_encoding.py
+++ b/mc_openapi/doml_mc/z3encoding/im_encoding.py
@@ -1,31 +1,16 @@
-from typing import Union
 from itertools import product
+from typing import Union
+
+from z3 import (And, BoolSort, Const, Context, Datatype, DatatypeRef,
+                DatatypeSortRef, ForAll, FuncDeclRef, Function, IntSort, Not,
+                Or, Solver, EnumSort)
 
-from z3 import (
-    And,
-    Const,
-    Context,
-    DatatypeRef,
-    DatatypeSortRef,
-    ForAll,
-    FuncDeclRef,
-    Function,
-    Not,
-    Or,
-    Solver,
-)
+from mc_openapi.doml_mc.z3encoding.metamodel_encoding import mk_enum_sort_dict
 
 from ..intermediate_model import IntermediateModel, MetaModel
 from ..intermediate_model.metamodel import get_mangled_attribute_defaults
-
 from .types import Refs, SortAndRefs
-from .utils import (
-    assert_relation_tuples,
-    Iff,
-    mk_enum_sort_dict,
-    mk_stringsym_sort_from_strings,
-)
-
+from ..utils import Iff
 
 def mk_elem_sort_dict(
     im: IntermediateModel,
@@ -61,41 +46,42 @@ def assert_im_attributes(
     solver: Solver,
     im: IntermediateModel,
     mm: MetaModel,
-    elem: Refs,
-    attr_sort: DatatypeSortRef,
-    attr: Refs,
-    AData: DatatypeSortRef,
-    ss: Refs,
+    elems: Refs,
+    attr_sort: DatatypeSortRef, # Relationship sort
+    attrs: Refs, # Relationship data
+    attr_data_sort: DatatypeSortRef, # Value sort
+    strings: Refs,
+    allow_placeholders: bool = False
 ) -> None:
     """
     ### Effects
     This procedure is effectful on `solver`.
     """
 
-    def encode_adata(v: Union[str, int, bool]) -> DatatypeRef:
+    def encode_attr_data(v: Union[str, int, bool]) -> DatatypeRef:
         if type(v) is str:
-            return AData.ss(ss[v])  # type: ignore
+            return attr_data_sort.str(strings[v])  # type: ignore
         elif type(v) is int:
-            return AData.int(v)  # type: ignore
+            return attr_data_sort.int(v)  # type: ignore
         else:  # type(v) is bool
-            return AData.bool(v)  # type: ignore
+            return attr_data_sort.bool(v)  # type: ignore
 
     a = Const("a", attr_sort)
-    d = Const("d", AData)
+    d = Const("d", attr_data_sort)
     for esn, im_es in im.items():
-        mangled_attrs = get_mangled_attribute_defaults(mm, im_es.class_) | im_es.attributes
-        if mangled_attrs:
+        attr_data = get_mangled_attribute_defaults(mm, im_es.class_) | im_es.attributes
+        if attr_data:
             assn = ForAll(
                 [a, d],
                 Iff(
-                    attr_rel(elem[esn], a, d),
+                    attr_rel(elems[esn], a, d),
                     Or(
                         *(
                             And(
-                                a == attr[aname],
-                                d == encode_adata(avalue),
+                                a == attrs[aname],
+                                d == encode_attr_data(avalue)
                             )
-                            for aname, avalues in mangled_attrs.items()
+                            for aname, avalues in attr_data.items()
                             for avalue in avalues
                         )
                     ),
@@ -104,43 +90,14 @@ def assert_im_attributes(
         else:
             assn = ForAll(
                 [a, d],
-                Not(attr_rel(elem[esn], a, d))
+                Not(attr_rel(elems[esn], a, d))
             )
         solver.assert_and_track(assn, f"attribute_values {esn}")
 
-
 def assert_im_associations(
     assoc_rel: FuncDeclRef,
     solver: Solver,
-    im: IntermediateModel,
-    mm: MetaModel,
-    elem: Refs,
-    assoc: Refs,
-) -> None:
-    """
-    ### Effects
-    This procedure is effectful on `solver`.
-    """
-    elem_names = set(im.keys())
-    assoc_mangled_names = {
-        f"{cname}::{aname}"
-        for cname, c in mm.items()
-        for aname in c.associations
-    }
-    rel_tpls = [
-        [esn, amn, etn]
-        for esn, amn, etn in product(
-            elem_names, assoc_mangled_names, elem_names
-        )
-        if etn in im[esn].associations.get(amn, set())
-    ]
-    assert_relation_tuples(assoc_rel, solver, rel_tpls, elem, assoc, elem)
-
-
-def assert_im_associations_q(
-    assoc_rel: FuncDeclRef,
-    solver: Solver,
-    im: IntermediateModel,
+    im: IntermediateModel, # Contains only bounded elements
     elem: Refs,
     assoc_sort: DatatypeSortRef,
     assoc: Refs,
@@ -150,29 +107,30 @@ def assert_im_associations_q(
     This procedure is effectful on `solver`.
     """
 
-    a = Const("a", assoc_sort)
-    for (esn, im_es), etn in product(im.items(), im):
+    assoc_ref = Const("a", assoc_sort)
+    for (elem_1_k, elem_1_v), elem_2_k in product(im.items(), im):
         assn = ForAll(
-            [a],
+            [assoc_ref],
             Iff(
-                assoc_rel(elem[esn], a, elem[etn]),
+                assoc_rel(elem[elem_1_k], assoc_ref, elem[elem_2_k]),
                 Or(
                     *(
-                        a == assoc[amn]
-                        for amn, etns in im_es.associations.items()
-                        if etn in etns
+                        assoc_ref == assoc[elem_1_assoc_k]
+                        for elem_1_assoc_k, elem_1_assoc_elems_k in elem_1_v.associations.items()
+                        if elem_2_k in elem_1_assoc_elems_k
                     ),
                     solver.ctx
                 ),
             ),
         )
-        solver.assert_and_track(assn, f"associations {esn} {etn}")
+        solver.assert_and_track(assn, f"associations {elem_1_k} {elem_2_k}")
 
 
 def mk_stringsym_sort_dict(
     im: IntermediateModel,
     mm: MetaModel,
-    z3ctx: Context
+    z3ctx: Context,
+    additional_strings: list[str] = []
 ) -> SortAndRefs:
     strings = (
         {
@@ -191,5 +149,36 @@ def mk_stringsym_sort_dict(
             if isinstance(v, str)
         }
         | {"SCRIPT", "IMAGE"}  # GeneratorKind values
+        | {"INGRESS", "EGRESS"} # TODO: Check if this fix is required
+        # It solves a KeyError when MC is run on openstack_template.domlx
+        | {
+            v
+            for v in additional_strings
+        }
     )
     return mk_stringsym_sort_from_strings(list(strings), z3ctx=z3ctx)
+
+def mk_attr_data_sort(
+    str_sort: DatatypeSortRef,
+    z3ctx: Context
+) -> DatatypeSortRef:
+    attr_data = Datatype("AttributeData", ctx=z3ctx)
+    attr_data.declare("placeholder")
+    attr_data.declare("int", ("get_int", IntSort(ctx=z3ctx)))
+    attr_data.declare("bool", ("get_bool", BoolSort(ctx=z3ctx)))
+    attr_data.declare("str", ("get_str", str_sort)) # str_sort is the one returned by the function above
+    return attr_data.create()
+
+def mk_stringsym_sort_from_strings(
+    strings: list[str],
+    z3ctx: Context
+) -> SortAndRefs:
+    str_list = [f"str_{i}_{symbolize(s)}" for i, s in enumerate(strings)]
+    string_sort, str_refs_dict = mk_enum_sort_dict("string", str_list, z3ctx=z3ctx)
+    string_sort_dict = {
+        s: str_refs_dict[str] for s, str in zip(strings, str_list)
+    }
+    return string_sort, string_sort_dict
+
+def symbolize(s: str) -> str:
+    return "".join([c.lower() if c.isalnum() else "_" for c in s[:16]])
diff --git a/mc_openapi/doml_mc/z3encoding/metamodel_encoding.py b/mc_openapi/doml_mc/z3encoding/metamodel_encoding.py
index 22c48484de3709b6526aa77c44d80da3aea07700..97af7a3b7860a171b652c6d724428cc035b651ae 100644
--- a/mc_openapi/doml_mc/z3encoding/metamodel_encoding.py
+++ b/mc_openapi/doml_mc/z3encoding/metamodel_encoding.py
@@ -4,12 +4,11 @@ from z3 import (
     DatatypeSortRef,
     FuncDeclRef,
     Function,
+    EnumSort
 )
 from ..intermediate_model import MetaModel
 
 from .types import SortAndRefs
-from .utils import mk_enum_sort_dict
-
 
 def mk_class_sort_dict(mm: MetaModel, z3ctx: Context) -> SortAndRefs:
     return mk_enum_sort_dict("Class", list(mm), z3ctx)
@@ -38,13 +37,18 @@ def mk_association_sort_dict(
     ]
     return mk_enum_sort_dict("Association", assocs, z3ctx)
 
+def mk_enum_sort_dict(name: str, values: list[str], z3ctx: Context) -> SortAndRefs:
+    """Makes a Z3 sort and a dict indexing sort values by their name"""
+
+    sort, datatype_refs = EnumSort(name, values, ctx=z3ctx)
+    return sort, dict(zip(values, datatype_refs))
 
 def def_attribute_rel(
     attr_sort: DatatypeSortRef,
     elem_sort: DatatypeSortRef,
-    AData: DatatypeSortRef
+    attr_data_sort: DatatypeSortRef
 ) -> FuncDeclRef:
-    return Function("attribute", elem_sort, attr_sort, AData, BoolSort(ctx=elem_sort.ctx))
+    return Function("attribute", elem_sort, attr_sort, attr_data_sort, BoolSort(ctx=elem_sort.ctx))
 
 
 def def_association_rel(
diff --git a/mc_openapi/doml_mc/z3encoding/utils.py b/mc_openapi/doml_mc/z3encoding/utils.py
deleted file mode 100644
index 04730494fc3687311d439f9bc06f1f73e16a9fc2..0000000000000000000000000000000000000000
--- a/mc_openapi/doml_mc/z3encoding/utils.py
+++ /dev/null
@@ -1,150 +0,0 @@
-from typing import cast
-from collections.abc import Sequence
-from itertools import product
-
-from z3 import (
-    BoolSort,
-    BoolVal,
-    Context,
-    Datatype,
-    DatatypeSortRef,
-    ExprRef,
-    EnumSort,
-    FuncDeclRef,
-    IntSort,
-    Solver,
-)
-
-from .types import Refs, SortAndRefs
-
-
-def mk_enum_sort_dict(name: str, values: list[str], z3ctx: Context) -> SortAndRefs:
-    """Makes a Z3 sort and a dict indexing sort values by their name"""
-
-    sort, dtrefs = EnumSort(name, values, ctx=z3ctx)
-    return sort, dict(zip(values, dtrefs))
-
-
-def assert_relation_tuples(
-    rel: FuncDeclRef,
-    solver: Solver,
-    rel_tpls: list[list[str]],
-    *sig_dicts: Refs,
-) -> None:
-    """
-    ### Parameters
-     - `rel` is a Z3 function with return type Bool representing a relation;
-     - `solver` is the Z3 solver on which to assert;
-     - `rel_tpls` is a list of lists of names of symbols which are related in
-       `rel`;
-     - `sig_dicts` are the domains of `rel`.
-
-    ### Effects
-    This procedure is effectful on `solver`.
-    """
-
-    # Length of tuples must me homogeneous and equal to the number of given
-    # domains.
-    if lengths := [len(tpl) for tpl in rel_tpls]:
-        assert min(lengths) == max(lengths)
-        assert lengths[0] == len(sig_dicts)
-
-    sym_tpls = [
-        cast(
-            list[ExprRef],
-            [dom[sym_name] for sym_name, dom in zip(doms_tpl, sig_dicts)],
-        )
-        + [BoolVal(doms_tpl in rel_tpls, ctx=solver.ctx)]
-        for doms_tpl in map(list, product(*sig_dicts))
-    ]
-
-    assert_function_tuples_raw(rel, solver, sym_tpls)
-
-
-def assert_function_tuples(
-    f: FuncDeclRef,
-    solver: Solver,
-    f_tpls: list[list[str]],
-    *sig_dicts: Refs,
-) -> None:
-    """
-    ### Parameters
-     - `f` is a Z3 function;
-     - `solver` is the Z3 solver on which to assert;
-     - `f_tpls` is a list of tuples of Z3 symbols. The first elements in each
-       tuple are the inputs of `f`, and the last element is its output;
-     - `sig_dicts` are the domains of `f`, the last one being its codomain.
-
-    ### Effects
-    This procedure is effectful on `solver`.
-    """
-
-    # Length of tuples must me homogeneous and equal to the number of given
-    # domains.
-    if lengths := [len(tpl) for tpl in f_tpls]:
-        assert min(lengths) == max(lengths)
-        assert lengths[0] == len(sig_dicts)
-
-    sym_tpls = [
-        [dom[sym_name] for sym_name, dom in zip(f_tpl, sig_dicts)]
-        for f_tpl in f_tpls
-    ]
-
-    assert_function_tuples_raw(f, solver, sym_tpls)
-
-
-def assert_function_tuples_raw(
-    f: FuncDeclRef,
-    solver: Solver,
-    f_tpls: Sequence[Sequence[ExprRef]],
-) -> None:
-    """
-    ### Parameters
-     - `f` is a Z3 function;
-     - `solver` is the Z3 solver on which to assert;
-     - `f_tpls` is a list of tuples of Z3 references or otherwise accepted
-       values. The first elements in each tuple are the inputs of `f`, and the
-       last element is its output;
-
-    ### Effects
-    This procedure is effectful on `solver`.
-    """
-    # Length of tuples must me homogeneous.
-    if lengths := [len(tpl) for tpl in f_tpls]:
-        assert min(lengths) == max(lengths)
-
-    for *xs, y in f_tpls:
-        solver.assert_and_track(
-            f(*xs) == y,
-            f"{f.name()} " + " ".join(str(x) for x in xs) + f" {y}",
-        )
-
-
-def mk_stringsym_sort_from_strings(
-    strings: list[str],
-    z3ctx: Context
-) -> SortAndRefs:
-    def symbolize(s: str) -> str:
-        return "".join([c.lower() if c.isalnum() else "_" for c in s[:16]])
-
-    ss_list = [f"ss_{i}_{symbolize(s)}" for i, s in enumerate(strings)]
-    stringsym_sort, ss_refs_dict = mk_enum_sort_dict("StringSym", ss_list, z3ctx=z3ctx)
-    stringsym_sort_dict = {
-        s: ss_refs_dict[ss] for s, ss in zip(strings, ss_list)
-    }
-    return stringsym_sort, stringsym_sort_dict
-
-
-def mk_adata_sort(
-    ss_sort: DatatypeSortRef,
-    z3ctx: Context
-) -> DatatypeSortRef:
-    AData = Datatype("AttributeData", ctx=z3ctx)
-    AData.declare("int", ("get_int", IntSort(ctx=z3ctx)))
-    AData.declare("bool", ("get_bool", BoolSort(ctx=z3ctx)))
-    AData.declare("ss", ("get_ss", ss_sort))
-    return AData.create()
-
-
-def Iff(a, b):
-    return a == b
diff --git a/mc_openapi/handlers.py b/mc_openapi/handlers.py
deleted file mode 100644
index a362235e9d516e991b035d09761b521da846eb5c..0000000000000000000000000000000000000000
--- a/mc_openapi/handlers.py
+++ /dev/null
@@ -1,26 +0,0 @@
-import datetime
-from .doml_mc import ModelChecker, MCResult
-
-
-def make_error(user_msg, debug_msg=None):
-    result = {"message": user_msg, "timestamp": datetime.datetime.now()}
-    if debug_msg is not None:
-        result["debug_message"] = debug_msg
-    return result
-
-
-def post(body, requirement=None):
-    doml_xmi = body
-    try:
-        dmc = ModelChecker(doml_xmi)
-        results = dmc.check_common_requirements(threads=2, consistency_checks=False, timeout=50)
-        res, msg = results.summarize()
-
-        if res == MCResult.sat:
-            return {"result": "sat"}
-        else:
-            return {"result": res.name,
-                    "description": msg}
-
-    except Exception as e:
-        return make_error("Supplied with malformed DOML XMI model.", debug_msg=str(e)), 400
diff --git a/mc_openapi/notebooks/csp_compatibility.ipynb b/mc_openapi/notebooks/csp_compatibility.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..7ff29d6570a90c67a3f22f42597bb601b038c597
--- /dev/null
+++ b/mc_openapi/notebooks/csp_compatibility.ipynb
@@ -0,0 +1,624 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 20,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import pandas as pd\n",
+    "import requests\n",
+    "from pprint import pprint\n",
+    "from itertools import groupby"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 22,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "{'AMAZ': [{'availability': '98',\n",
+      "           'class': 'Virtual Machine',\n",
+      "           'cost/currency': '4.53',\n",
+      "           'frequency per core': '1500',\n",
+      "           'instance storage': '40',\n",
+      "           'legal level/accreditations': None,\n",
+      "           'memory': '0.5',\n",
+      "           'name': 't2.nano',\n",
+      "           'optimized for': 'GEPU',\n",
+      "           'provider': 'AMAZ',\n",
+      "           'public ip': 'IPV4',\n",
+      "           'region': '00EU',\n",
+      "           'response time: virtual machine performance': '3',\n",
+      "           'underpinning technology': None,\n",
+      "           'virtual cpu cores': '1',\n",
+      "           'zone': 'IEEU'},\n",
+      "          {'availability': '98.2',\n",
+      "           'class': 'Virtual Machine',\n",
+      "           'cost/currency': '39.75',\n",
+      "           'frequency per core': '1500',\n",
+      "           'instance storage': '60',\n",
+      "           'legal level/accreditations': None,\n",
+      "           'memory': '4',\n",
+      "           'name': 't2.medium',\n",
+      "           'optimized for': 'GEPU',\n",
+      "           'provider': 'AMAZ',\n",
+      "           'public ip': 'IPV4',\n",
+      "           'region': '00NA',\n",
+      "           'response time: virtual machine performance': '2',\n",
+      "           'underpinning technology': None,\n",
+      "           'virtual cpu cores': '2',\n",
+      "           'zone': 'USNA'},\n",
+      "          {'availability': '99.8',\n",
+      "           'class': 'Virtual Machine',\n",
+      "           'cost/currency': '640',\n",
+      "           'frequency per core': '1500',\n",
+      "           'instance storage': '120',\n",
+      "           'legal level/accreditations': None,\n",
+      "           'memory': '64',\n",
+      "           'name': 'm4.4xlarge',\n",
+      "           'optimized for': 'GEPU',\n",
+      "           'provider': 'AMAZ',\n",
+      "           'public ip': None,\n",
+      "           'region': '00EU',\n",
+      "           'response time: virtual machine performance': '2',\n",
+      "           'underpinning technology': None,\n",
+      "           'virtual cpu cores': '16',\n",
+      "           'zone': 'SPEU'},\n",
+      "          {'availability': '99.2',\n",
+      "           'class': 'Virtual Machine',\n",
+      "           'cost/currency': '323',\n",
+      "           'frequency per core': '1500',\n",
+      "           'instance storage': '100',\n",
+      "           'legal level/accreditations': None,\n",
+      "           'memory': '32',\n",
+      "           'name': 'm5.2xlarge',\n",
+      "           'optimized for': 'GEPU',\n",
+      "           'provider': 'AMAZ',\n",
+      "           'public ip': None,\n",
+      "           'region': '00NA',\n",
+      "           'response time: virtual machine performance': '3',\n",
+      "           'underpinning technology': None,\n",
+      "           'virtual cpu cores': '8',\n",
+      "           'zone': 'USNA'},\n",
+      "          {'availability': '99.4',\n",
+      "           'class': 'Virtual Machine',\n",
+      "           'cost/currency': '268',\n",
+      "           'frequency per core': '1500',\n",
+      "           'instance storage': '80',\n",
+      "           'legal level/accreditations': None,\n",
+      "           'memory': '16',\n",
+      "           'name': 'c5.2xlarge',\n",
+      "           'optimized for': 'COOP',\n",
+      "           'provider': 'AMAZ',\n",
+      "           'public ip': 'IPV4',\n",
+      "           'region': '00NA',\n",
+      "           'response time: virtual machine performance': '5',\n",
+      "           'underpinning technology': None,\n",
+      "           'virtual cpu cores': '8',\n",
+      "           'zone': 'CANA'},\n",
+      "          {'availability': '99.8',\n",
+      "           'class': 'Virtual Machine',\n",
+      "           'cost/currency': '1304',\n",
+      "           'frequency per core': '1500',\n",
+      "           'instance storage': '200',\n",
+      "           'legal level/accreditations': None,\n",
+      "           'memory': '60',\n",
+      "           'name': 'c4.8xlarge',\n",
+      "           'optimized for': 'COOP',\n",
+      "           'provider': 'AMAZ',\n",
+      "           'public ip': 'IPV4',\n",
+      "           'region': '00EU',\n",
+      "           'response time: virtual machine performance': '2',\n",
+      "           'underpinning technology': None,\n",
+      "           'virtual cpu cores': '36',\n",
+      "           'zone': 'IEEU'},\n",
+      "          {'availability': '99.8',\n",
+      "           'class': 'Virtual Machine',\n",
+      "           'cost/currency': '2209',\n",
+      "           'frequency per core': '1500',\n",
+      "           'instance storage': '220',\n",
+      "           'legal level/accreditations': None,\n",
+      "           'memory': '244',\n",
+      "           'name': 'g3.8xlarge',\n",
+      "           'optimized for': 'GPUI',\n",
+      "           'provider': 'AMAZ',\n",
+      "           'public ip': 'IPV4',\n",
+      "           'region': '00NA',\n",
+      "           'response time: virtual machine performance': '2',\n",
+      "           'underpinning technology': None,\n",
+      "           'virtual cpu cores': '32',\n",
+      "           'zone': 'USNA'},\n",
+      "          {'availability': '99.9',\n",
+      "           'class': 'Virtual Machine',\n",
+      "           'cost/currency': '5600',\n",
+      "           'frequency per core': '1500',\n",
+      "           'instance storage': '250',\n",
+      "           'legal level/accreditations': None,\n",
+      "           'memory': '488',\n",
+      "           'name': 'p2.8xlarge',\n",
+      "           'optimized for': 'GPUI',\n",
+      "           'provider': 'AMAZ',\n",
+      "           'public ip': 'IPV4',\n",
+      "           'region': '00EU',\n",
+      "           'response time: virtual machine performance': '2',\n",
+      "           'underpinning technology': None,\n",
+      "           'virtual cpu cores': '32',\n",
+      "           'zone': 'UKEU'},\n",
+      "          {'availability': '98.5',\n",
+      "           'class': 'Virtual Machine',\n",
+      "           'cost/currency': '214',\n",
+      "           'frequency per core': '1500',\n",
+      "           'instance storage': '70',\n",
+      "           'legal level/accreditations': None,\n",
+      "           'memory': '30.5',\n",
+      "           'name': 'r4.xlarge',\n",
+      "           'optimized for': 'MEOP',\n",
+      "           'provider': 'AMAZ',\n",
+      "           'public ip': 'IPV4',\n",
+      "           'region': '00NA',\n",
+      "           'response time: virtual machine performance': '2',\n",
+      "           'underpinning technology': None,\n",
+      "           'virtual cpu cores': '4',\n",
+      "           'zone': 'USNA'},\n",
+      "          {'availability': '99',\n",
+      "           'class': 'Virtual Machine',\n",
+      "           'cost/currency': '3376',\n",
+      "           'frequency per core': '1500',\n",
+      "           'instance storage': '80',\n",
+      "           'legal level/accreditations': None,\n",
+      "           'memory': '488',\n",
+      "           'name': 'x1e.4xlarge',\n",
+      "           'optimized for': 'MEOP',\n",
+      "           'provider': 'AMAZ',\n",
+      "           'public ip': 'IPV4',\n",
+      "           'region': '00EU',\n",
+      "           'response time: virtual machine performance': '2',\n",
+      "           'underpinning technology': None,\n",
+      "           'virtual cpu cores': '16',\n",
+      "           'zone': 'DEEU'},\n",
+      "          {'availability': '98',\n",
+      "           'class': 'Virtual Machine',\n",
+      "           'cost/currency': '200',\n",
+      "           'frequency per core': None,\n",
+      "           'instance storage': '410',\n",
+      "           'legal level/accreditations': None,\n",
+      "           'memory': '3.7',\n",
+      "           'name': 'm1.medium',\n",
+      "           'optimized for': None,\n",
+      "           'provider': 'AMAZ',\n",
+      "           'public ip': 'IPV4',\n",
+      "           'region': '00NA',\n",
+      "           'response time: virtual machine performance': '100',\n",
+      "           'underpinning technology': None,\n",
+      "           'virtual cpu cores': '1',\n",
+      "           'zone': 'USNA'}],\n",
+      " 'ARSY': [{'availability': '99.5',\n",
+      "           'class': 'Virtual Machine',\n",
+      "           'cost/currency': '15',\n",
+      "           'frequency per core': '1500',\n",
+      "           'instance storage': '40',\n",
+      "           'legal level/accreditations': None,\n",
+      "           'memory': '1',\n",
+      "           'name': 'C1_Spain',\n",
+      "           'optimized for': None,\n",
+      "           'provider': 'ARSY',\n",
+      "           'public ip': None,\n",
+      "           'region': '00EU',\n",
+      "           'response time: virtual machine performance': '5',\n",
+      "           'underpinning technology': 'VmWare',\n",
+      "           'virtual cpu cores': '1',\n",
+      "           'zone': 'SPEU'},\n",
+      "          {'availability': '99.5',\n",
+      "           'class': 'Virtual Machine',\n",
+      "           'cost/currency': '15',\n",
+      "           'frequency per core': '1500',\n",
+      "           'instance storage': '40',\n",
+      "           'legal level/accreditations': None,\n",
+      "           'memory': '1',\n",
+      "           'name': 'C1_USA',\n",
+      "           'optimized for': None,\n",
+      "           'provider': 'ARSY',\n",
+      "           'public ip': None,\n",
+      "           'region': '00NA',\n",
+      "           'response time: virtual machine performance': '5',\n",
+      "           'underpinning technology': 'VmWare',\n",
+      "           'virtual cpu cores': '1',\n",
+      "           'zone': 'USNA'},\n",
+      "          {'availability': '99.6',\n",
+      "           'class': 'Virtual Machine',\n",
+      "           'cost/currency': '40',\n",
+      "           'frequency per core': '1500',\n",
+      "           'instance storage': '60',\n",
+      "           'legal level/accreditations': None,\n",
+      "           'memory': '4',\n",
+      "           'name': 'C2_Europe',\n",
+      "           'optimized for': None,\n",
+      "           'provider': 'ARSY',\n",
+      "           'public ip': None,\n",
+      "           'region': '00EU',\n",
+      "           'response time: virtual machine performance': '3',\n",
+      "           'underpinning technology': 'VmWare',\n",
+      "           'virtual cpu cores': '2',\n",
+      "           'zone': 'DEEU'},\n",
+      "          {'availability': '99.6',\n",
+      "           'class': 'Virtual Machine',\n",
+      "           'cost/currency': '40',\n",
+      "           'frequency per core': '1500',\n",
+      "           'instance storage': '60',\n",
+      "           'legal level/accreditations': None,\n",
+      "           'memory': '4',\n",
+      "           'name': 'C2_UnitedKingdom',\n",
+      "           'optimized for': None,\n",
+      "           'provider': 'ARSY',\n",
+      "           'public ip': None,\n",
+      "           'region': '00EU',\n",
+      "           'response time: virtual machine performance': '3',\n",
+      "           'underpinning technology': 'VmWare',\n",
+      "           'virtual cpu cores': '2',\n",
+      "           'zone': 'UKEU'},\n",
+      "          {'availability': '99.8',\n",
+      "           'class': 'Virtual Machine',\n",
+      "           'cost/currency': '80',\n",
+      "           'frequency per core': '1500',\n",
+      "           'instance storage': '100',\n",
+      "           'legal level/accreditations': None,\n",
+      "           'memory': '8',\n",
+      "           'name': 'C4_Europe',\n",
+      "           'optimized for': None,\n",
+      "           'provider': 'ARSY',\n",
+      "           'public ip': 'IPV4',\n",
+      "           'region': '00EU',\n",
+      "           'response time: virtual machine performance': '2',\n",
+      "           'underpinning technology': 'VmWare',\n",
+      "           'virtual cpu cores': '4',\n",
+      "           'zone': None},\n",
+      "          {'availability': '99.8',\n",
+      "           'class': 'Virtual Machine',\n",
+      "           'cost/currency': '80',\n",
+      "           'frequency per core': '1500',\n",
+      "           'instance storage': '100',\n",
+      "           'legal level/accreditations': None,\n",
+      "           'memory': '8',\n",
+      "           'name': 'C4_USA',\n",
+      "           'optimized for': None,\n",
+      "           'provider': 'ARSY',\n",
+      "           'public ip': None,\n",
+      "           'region': '00NA',\n",
+      "           'response time: virtual machine performance': '3',\n",
+      "           'underpinning technology': 'VmWare',\n",
+      "           'virtual cpu cores': '4',\n",
+      "           'zone': 'USNA'},\n",
+      "          {'availability': '99.9',\n",
+      "           'class': 'Virtual Machine',\n",
+      "           'cost/currency': '150',\n",
+      "           'frequency per core': '1500',\n",
+      "           'instance storage': '200',\n",
+      "           'legal level/accreditations': None,\n",
+      "           'memory': '16',\n",
+      "           'name': 'C8_Germany',\n",
+      "           'optimized for': None,\n",
+      "           'provider': 'ARSY',\n",
+      "           'public ip': 'IPV4',\n",
+      "           'region': '00EU',\n",
+      "           'response time: virtual machine performance': '2',\n",
+      "           'underpinning technology': 'VmWare',\n",
+      "           'virtual cpu cores': '8',\n",
+      "           'zone': 'DEEU'},\n",
+      "          {'availability': '99.8',\n",
+      "           'class': 'Virtual Machine',\n",
+      "           'cost/currency': '150',\n",
+      "           'frequency per core': '1500',\n",
+      "           'instance storage': '200',\n",
+      "           'legal level/accreditations': None,\n",
+      "           'memory': '16',\n",
+      "           'name': 'C8_Spain',\n",
+      "           'optimized for': None,\n",
+      "           'provider': 'ARSY',\n",
+      "           'public ip': 'IPV4',\n",
+      "           'region': '00EU',\n",
+      "           'response time: virtual machine performance': '2',\n",
+      "           'underpinning technology': 'VmWare',\n",
+      "           'virtual cpu cores': '8',\n",
+      "           'zone': 'SPEU'},\n",
+      "          {'availability': '98.5',\n",
+      "           'class': 'Virtual Machine',\n",
+      "           'cost/currency': '77',\n",
+      "           'frequency per core': '1500',\n",
+      "           'instance storage': '100',\n",
+      "           'legal level/accreditations': None,\n",
+      "           'memory': '8',\n",
+      "           'name': 'm5.large',\n",
+      "           'optimized for': 'GEPU',\n",
+      "           'provider': 'ARSY',\n",
+      "           'public ip': 'IPV4',\n",
+      "           'region': '00NA',\n",
+      "           'response time: virtual machine performance': '1',\n",
+      "           'underpinning technology': None,\n",
+      "           'virtual cpu cores': '2',\n",
+      "           'zone': 'CANA'}],\n",
+      " 'AZUR': [{'availability': '95',\n",
+      "           'class': 'Virtual Machine',\n",
+      "           'cost/currency': '93.60',\n",
+      "           'frequency per core': '1500',\n",
+      "           'instance storage': '20',\n",
+      "           'legal level/accreditations': None,\n",
+      "           'memory': '4',\n",
+      "           'name': 'A2v2',\n",
+      "           'optimized for': None,\n",
+      "           'provider': 'AZUR',\n",
+      "           'public ip': 'IPV4',\n",
+      "           'region': '00EU',\n",
+      "           'response time: virtual machine performance': '5',\n",
+      "           'underpinning technology': None,\n",
+      "           'virtual cpu cores': '2',\n",
+      "           'zone': 'IEEU'},\n",
+      "          {'availability': '95',\n",
+      "           'class': 'Virtual Machine',\n",
+      "           'cost/currency': '67',\n",
+      "           'frequency per core': '1500',\n",
+      "           'instance storage': '20',\n",
+      "           'legal level/accreditations': None,\n",
+      "           'memory': '4',\n",
+      "           'name': 'A2v2_USA',\n",
+      "           'optimized for': None,\n",
+      "           'provider': 'AZUR',\n",
+      "           'public ip': 'IPV4',\n",
+      "           'region': '00NA',\n",
+      "           'response time: virtual machine performance': '5',\n",
+      "           'underpinning technology': None,\n",
+      "           'virtual cpu cores': '2',\n",
+      "           'zone': 'USNA'},\n",
+      "          {'availability': '98',\n",
+      "           'class': 'Virtual Machine',\n",
+      "           'cost/currency': '242',\n",
+      "           'frequency per core': '1500',\n",
+      "           'instance storage': '64',\n",
+      "           'legal level/accreditations': None,\n",
+      "           'memory': '32',\n",
+      "           'name': 'B8_USA',\n",
+      "           'optimized for': None,\n",
+      "           'provider': 'AZUR',\n",
+      "           'public ip': 'IPV4',\n",
+      "           'region': '00NA',\n",
+      "           'response time: virtual machine performance': '2',\n",
+      "           'underpinning technology': None,\n",
+      "           'virtual cpu cores': '8',\n",
+      "           'zone': None},\n",
+      "          {'availability': '98',\n",
+      "           'class': 'Virtual Machine',\n",
+      "           'cost/currency': '170',\n",
+      "           'frequency per core': '1500',\n",
+      "           'instance storage': '64',\n",
+      "           'legal level/accreditations': None,\n",
+      "           'memory': '32',\n",
+      "           'name': 'B8_Germany',\n",
+      "           'optimized for': None,\n",
+      "           'provider': 'AZUR',\n",
+      "           'public ip': None,\n",
+      "           'region': '00EU',\n",
+      "           'response time: virtual machine performance': '2',\n",
+      "           'underpinning technology': None,\n",
+      "           'virtual cpu cores': '8',\n",
+      "           'zone': 'DEEU'},\n",
+      "          {'availability': '96',\n",
+      "           'class': 'Virtual Machine',\n",
+      "           'cost/currency': '193',\n",
+      "           'frequency per core': '1500',\n",
+      "           'instance storage': '120',\n",
+      "           'legal level/accreditations': None,\n",
+      "           'memory': '7',\n",
+      "           'name': 'A3_France',\n",
+      "           'optimized for': None,\n",
+      "           'provider': 'AZUR',\n",
+      "           'public ip': 'IPV4',\n",
+      "           'region': '00EU',\n",
+      "           'response time: virtual machine performance': '3',\n",
+      "           'underpinning technology': None,\n",
+      "           'virtual cpu cores': '4',\n",
+      "           'zone': 'FREU'},\n",
+      "          {'availability': '98',\n",
+      "           'class': 'Virtual Machine',\n",
+      "           'cost/currency': '541',\n",
+      "           'frequency per core': '1500',\n",
+      "           'instance storage': '112',\n",
+      "           'legal level/accreditations': None,\n",
+      "           'memory': '56',\n",
+      "           'name': 'DS13v2',\n",
+      "           'optimized for': None,\n",
+      "           'provider': 'AZUR',\n",
+      "           'public ip': None,\n",
+      "           'region': '00EU',\n",
+      "           'response time: virtual machine performance': '3',\n",
+      "           'underpinning technology': None,\n",
+      "           'virtual cpu cores': '8',\n",
+      "           'zone': None}],\n",
+      " 'CLSI': [{'availability': '98',\n",
+      "           'class': 'Virtual Machine',\n",
+      "           'cost/currency': '186',\n",
+      "           'frequency per core': '5200',\n",
+      "           'instance storage': '256',\n",
+      "           'legal level/accreditations': None,\n",
+      "           'memory': '4',\n",
+      "           'name': 'VM_1_CS',\n",
+      "           'optimized for': None,\n",
+      "           'provider': 'CLSI',\n",
+      "           'public ip': 'IPV4',\n",
+      "           'region': '00EU',\n",
+      "           'response time: virtual machine performance': '100',\n",
+      "           'underpinning technology': None,\n",
+      "           'virtual cpu cores': '2',\n",
+      "           'zone': 'ZUEU'}],\n",
+      " 'GOOG': [{'availability': '96',\n",
+      "           'class': 'Virtual Machine',\n",
+      "           'cost/currency': '500',\n",
+      "           'frequency per core': '1500',\n",
+      "           'instance storage': '300',\n",
+      "           'legal level/accreditations': None,\n",
+      "           'memory': '60',\n",
+      "           'name': 'n1-standard-16',\n",
+      "           'optimized for': None,\n",
+      "           'provider': 'GOOG',\n",
+      "           'public ip': 'IPV4',\n",
+      "           'region': '00EU',\n",
+      "           'response time: virtual machine performance': '4',\n",
+      "           'underpinning technology': None,\n",
+      "           'virtual cpu cores': '16',\n",
+      "           'zone': 'DEEU'},\n",
+      "          {'availability': '98',\n",
+      "           'class': 'Virtual Machine',\n",
+      "           'cost/currency': '552',\n",
+      "           'frequency per core': '1500',\n",
+      "           'instance storage': '300',\n",
+      "           'legal level/accreditations': None,\n",
+      "           'memory': '104',\n",
+      "           'name': 'n1-highmem-16',\n",
+      "           'optimized for': 'MEOP',\n",
+      "           'provider': 'GOOG',\n",
+      "           'public ip': None,\n",
+      "           'region': '00NA',\n",
+      "           'response time: virtual machine performance': '4',\n",
+      "           'underpinning technology': None,\n",
+      "           'virtual cpu cores': '16',\n",
+      "           'zone': 'USNA'}],\n",
+      " 'OPEN': [{'availability': '98',\n",
+      "           'class': 'Virtual Machine',\n",
+      "           'cost/currency': '10',\n",
+      "           'frequency per core': '1500',\n",
+      "           'instance storage': '1',\n",
+      "           'legal level/accreditations': None,\n",
+      "           'memory': '512',\n",
+      "           'name': 'm1.tiny',\n",
+      "           'optimized for': None,\n",
+      "           'provider': 'OPEN',\n",
+      "           'public ip': 'IPV4',\n",
+      "           'region': '00EU',\n",
+      "           'response time: virtual machine performance': '10',\n",
+      "           'underpinning technology': None,\n",
+      "           'virtual cpu cores': '1',\n",
+      "           'zone': 'SPEU'},\n",
+      "          {'availability': '99',\n",
+      "           'class': 'Virtual Machine',\n",
+      "           'cost/currency': '20',\n",
+      "           'frequency per core': '1500',\n",
+      "           'instance storage': '20',\n",
+      "           'legal level/accreditations': None,\n",
+      "           'memory': '2',\n",
+      "           'name': 'm1.small',\n",
+      "           'optimized for': None,\n",
+      "           'provider': 'OPEN',\n",
+      "           'public ip': None,\n",
+      "           'region': '00EU',\n",
+      "           'response time: virtual machine performance': '5',\n",
+      "           'underpinning technology': None,\n",
+      "           'virtual cpu cores': '1',\n",
+      "           'zone': 'SPEU'},\n",
+      "          {'availability': '99.5',\n",
+      "           'class': 'Virtual Machine',\n",
+      "           'cost/currency': '40',\n",
+      "           'frequency per core': '1500',\n",
+      "           'instance storage': '40',\n",
+      "           'legal level/accreditations': None,\n",
+      "           'memory': '4',\n",
+      "           'name': 'm1.medium',\n",
+      "           'optimized for': None,\n",
+      "           'provider': 'OPEN',\n",
+      "           'public ip': None,\n",
+      "           'region': '00EU',\n",
+      "           'response time: virtual machine performance': '4',\n",
+      "           'underpinning technology': None,\n",
+      "           'virtual cpu cores': '2',\n",
+      "           'zone': 'SPEU'},\n",
+      "          {'availability': '99.6',\n",
+      "           'class': 'Virtual Machine',\n",
+      "           'cost/currency': '80',\n",
+      "           'frequency per core': '1500',\n",
+      "           'instance storage': '80',\n",
+      "           'legal level/accreditations': None,\n",
+      "           'memory': '8',\n",
+      "           'name': 'm1.large',\n",
+      "           'optimized for': None,\n",
+      "           'provider': 'OPEN',\n",
+      "           'public ip': None,\n",
+      "           'region': '00EU',\n",
+      "           'response time: virtual machine performance': '3',\n",
+      "           'underpinning technology': None,\n",
+      "           'virtual cpu cores': '4',\n",
+      "           'zone': 'SPEU'},\n",
+      "          {'availability': '99.8',\n",
+      "           'class': 'Virtual Machine',\n",
+      "           'cost/currency': '160',\n",
+      "           'frequency per core': '1500',\n",
+      "           'instance storage': '160',\n",
+      "           'legal level/accreditations': None,\n",
+      "           'memory': '16',\n",
+      "           'name': 'm1.xlarge',\n",
+      "           'optimized for': None,\n",
+      "           'provider': 'OPEN',\n",
+      "           'public ip': None,\n",
+      "           'region': '00EU',\n",
+      "           'response time: virtual machine performance': '2',\n",
+      "           'underpinning technology': None,\n",
+      "           'virtual cpu cores': '8',\n",
+      "           'zone': 'SPEU'}]}\n"
+     ]
+    }
+   ],
+   "source": [
+    "IEC_API = 'https://iec.ci.piacere.digital.tecnalia.dev/services/iecbackend/api/root-services/catalogue'\n",
+    "all_json = requests.get(IEC_API).json()\n",
+    "\n",
+    "all_json = [\n",
+    "    {\n",
+    "        'name': x['serviceName'],\n",
+    "        'class': x['serviceClass']['serviceClassName'],\n",
+    "        'props': x['serviceAttributeValues']\n",
+    "    }\n",
+    "    for x in all_json\n",
+    "]\n",
+    "\n",
+    "vms = [vm for vm in all_json if vm['class'] == 'Virtual Machine']\n",
+    "stos = [vm for vm in all_json if vm['class'] == 'Storage']\n",
+    "dbs = [vm for vm in all_json if vm['class'] == 'Database']\n",
+    "\n",
+    "def flatten_properties(el):\n",
+    "    for p in el['props']:\n",
+    "        el[p['serviceAttributeType']['name'].lower()] = p['serviceAttributeValue'] or None\n",
+    "    el.pop('props', None)\n",
+    "    return el\n",
+    "\n",
+    "vms = [flatten_properties(vm) for vm in vms]\n",
+    "\n",
+    "vms ={ k: list(v) for k, v in groupby(sorted(vms, key=lambda vm: vm['provider']), lambda vm: vm['provider'])}\n",
+    "\n",
+    "pprint(vms)"
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": ".venv",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.11.2"
+  },
+  "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/mc_openapi/notebooks/dict_reference.ipynb b/mc_openapi/notebooks/dict_reference.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..7307d91f12c97fa324e54f9ef42888f49b86d824
--- /dev/null
+++ b/mc_openapi/notebooks/dict_reference.ipynb
@@ -0,0 +1,251 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from pprint import pprint\n",
+    "\n",
+    "from mc_openapi.doml_mc import ModelChecker, DOMLVersion\n",
+    "\n",
+    "doml_document_path = \"../../tests/doml/v2.0/nginx-openstack_v2.0.domlx\"\n",
+    "# doml_document_path = \"../../tests/doml/nginx-openstack_v2.0_wrong_vm_iface.domlx\"\n",
+    "# doml_document_path = \"../../tests/doml/faas.domlx\"\n",
+    "with open(doml_document_path, \"rb\") as xmif:\n",
+    "    doc = xmif.read()\n",
+    "\n",
+    "model_checker = ModelChecker(doc, DOMLVersion.V2_0)\n",
+    "meta_model = model_checker.metamodel\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {},
+   "outputs": [
+    {
+     "ename": "SyntaxError",
+     "evalue": "f-string: unmatched '(' (2134446349.py, line 2)",
+     "output_type": "error",
+     "traceback": [
+      "\u001b[0;36m  Cell \u001b[0;32mIn [13], line 2\u001b[0;36m\u001b[0m\n\u001b[0;31m    f\"{cname.replace(\"_\", \".\")}.{aname}\"\u001b[0m\n\u001b[0m                      ^\u001b[0m\n\u001b[0;31mSyntaxError\u001b[0m\u001b[0;31m:\u001b[0m f-string: unmatched '('\n"
+     ]
+    }
+   ],
+   "source": [
+    "atts = [\n",
+    "    f\"{cname}::{aname}\"\n",
+    "    for cname, c in meta_model.items()\n",
+    "    for aname in c.attributes\n",
+    "]\n",
+    "\n",
+    "pprint(atts)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "['commons_DOMLElement.annotations',\n",
+      " 'commons_Property.reference',\n",
+      " 'commons_Configuration.deployments',\n",
+      " 'commons_Deployment.component',\n",
+      " 'commons_Deployment.node',\n",
+      " 'application_ApplicationLayer.components',\n",
+      " 'application_SoftwareComponent.exposedInterfaces',\n",
+      " 'application_SoftwareComponent.consumedInterfaces',\n",
+      " 'application_SaaS.exposedInterfaces',\n",
+      " 'infrastructure_InfrastructureLayer.nodes',\n",
+      " 'infrastructure_InfrastructureLayer.generators',\n",
+      " 'infrastructure_InfrastructureLayer.storages',\n",
+      " 'infrastructure_InfrastructureLayer.faas',\n",
+      " 'infrastructure_InfrastructureLayer.credentials',\n",
+      " 'infrastructure_InfrastructureLayer.groups',\n",
+      " 'infrastructure_InfrastructureLayer.securityGroups',\n",
+      " 'infrastructure_InfrastructureLayer.networks',\n",
+      " 'infrastructure_ComputingNode.ifaces',\n",
+      " 'infrastructure_ComputingNode.location',\n",
+      " 'infrastructure_ComputingNode.credentials',\n",
+      " 'infrastructure_ComputingNode.group',\n",
+      " 'infrastructure_VirtualMachine.generatedFrom',\n",
+      " 'infrastructure_Container.generatedFrom',\n",
+      " 'infrastructure_Container.hosts',\n",
+      " 'infrastructure_VMImage.generatedVMs',\n",
+      " 'infrastructure_ContainerImage.generatedContainers',\n",
+      " 'infrastructure_AutoScalingGroup.machineDefinition',\n",
+      " 'infrastructure_AutoScalingGroup.deploymentNetwork',\n",
+      " 'infrastructure_AutoScalingGroup.securityGroup',\n",
+      " 'infrastructure_Storage.ifaces',\n",
+      " 'infrastructure_FunctionAsAService.ifaces',\n",
+      " 'infrastructure_Network.connectedIfaces',\n",
+      " 'infrastructure_Network.igws',\n",
+      " 'infrastructure_Network.subnets',\n",
+      " 'infrastructure_Subnet.connectedTo',\n",
+      " 'infrastructure_NetworkInterface.belongsTo',\n",
+      " 'infrastructure_NetworkInterface.associated',\n",
+      " 'infrastructure_ComputingGroup.groupedNodes',\n",
+      " 'infrastructure_SecurityGroup.rules',\n",
+      " 'infrastructure_SecurityGroup.ifaces',\n",
+      " 'infrastructure_SwarmRole.nodes',\n",
+      " 'infrastructure_Swarm.roles',\n",
+      " 'concrete_ConcreteInfrastructure.providers',\n",
+      " 'concrete_RuntimeProvider.vms',\n",
+      " 'concrete_RuntimeProvider.vmImages',\n",
+      " 'concrete_RuntimeProvider.containerImages',\n",
+      " 'concrete_RuntimeProvider.networks',\n",
+      " 'concrete_RuntimeProvider.storages',\n",
+      " 'concrete_RuntimeProvider.faas',\n",
+      " 'concrete_RuntimeProvider.group',\n",
+      " 'concrete_VirtualMachine.maps',\n",
+      " 'concrete_VMImage.maps',\n",
+      " 'concrete_ContainerImage.maps',\n",
+      " 'concrete_Network.maps',\n",
+      " 'concrete_Storage.maps',\n",
+      " 'concrete_FunctionAsAService.maps',\n",
+      " 'concrete_ComputingGroup.maps']\n"
+     ]
+    }
+   ],
+   "source": [
+    "assocs = [\n",
+    "    f\"{cname}::{aname}\"\n",
+    "    for cname, c in meta_model.items()\n",
+    "    for aname in c.associations\n",
+    "]\n",
+    "\n",
+    "pprint(assocs)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [
+    {
+     "ename": "NameError",
+     "evalue": "name 'mm' is not defined",
+     "output_type": "error",
+     "traceback": [
+      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
+      "\u001b[0;31mNameError\u001b[0m                                 Traceback (most recent call last)",
+      "Cell \u001b[0;32mIn [10], line 2\u001b[0m\n\u001b[1;32m      1\u001b[0m strings \u001b[39m=\u001b[39m [v\n\u001b[0;32m----> 2\u001b[0m             \u001b[39mfor\u001b[39;00m c \u001b[39min\u001b[39;00m mm\u001b[39m.\u001b[39mvalues()\n\u001b[1;32m      3\u001b[0m             \u001b[39mfor\u001b[39;00m a \u001b[39min\u001b[39;00m c\u001b[39m.\u001b[39mattributes\u001b[39m.\u001b[39mvalues()\n\u001b[1;32m      4\u001b[0m             \u001b[39mif\u001b[39;00m a\u001b[39m.\u001b[39mdefault \u001b[39mis\u001b[39;00m \u001b[39mnot\u001b[39;00m \u001b[39mNone\u001b[39;00m\n\u001b[1;32m      5\u001b[0m             \u001b[39mfor\u001b[39;00m v \u001b[39min\u001b[39;00m a\u001b[39m.\u001b[39mdefault\n\u001b[1;32m      6\u001b[0m             \u001b[39mif\u001b[39;00m \u001b[39misinstance\u001b[39m(v, \u001b[39mstr\u001b[39m)]\n\u001b[1;32m      8\u001b[0m pprint(strings)\n",
+      "\u001b[0;31mNameError\u001b[0m: name 'mm' is not defined"
+     ]
+    }
+   ],
+   "source": [
+    "strings = [v\n",
+    "            for c in mm.values()\n",
+    "            for a in c.attributes.values()\n",
+    "            if a.default is not None\n",
+    "            for v in a.default\n",
+    "            if isinstance(v, str)]\n",
+    "\n",
+    "pprint(strings)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "['commons_DOMLElement',\n",
+      " 'commons_Property',\n",
+      " 'commons_IProperty',\n",
+      " 'commons_SProperty',\n",
+      " 'commons_FProperty',\n",
+      " 'commons_BProperty',\n",
+      " 'commons_Configuration',\n",
+      " 'commons_Deployment',\n",
+      " 'application_ApplicationLayer',\n",
+      " 'application_ApplicationComponent',\n",
+      " 'application_SoftwareComponent',\n",
+      " 'application_SaaS',\n",
+      " 'application_SoftwareInterface',\n",
+      " 'application_DBMS',\n",
+      " 'application_SaaSDBMS',\n",
+      " 'infrastructure_InfrastructureLayer',\n",
+      " 'infrastructure_InfrastructureElement',\n",
+      " 'infrastructure_ComputingNode',\n",
+      " 'infrastructure_PhysicalComputingNode',\n",
+      " 'infrastructure_VirtualMachine',\n",
+      " 'infrastructure_Location',\n",
+      " 'infrastructure_Container',\n",
+      " 'infrastructure_ComputingNodeGenerator',\n",
+      " 'infrastructure_VMImage',\n",
+      " 'infrastructure_ContainerImage',\n",
+      " 'infrastructure_AutoScalingGroup',\n",
+      " 'infrastructure_Storage',\n",
+      " 'infrastructure_FunctionAsAService',\n",
+      " 'infrastructure_Network',\n",
+      " 'infrastructure_Subnet',\n",
+      " 'infrastructure_NetworkInterface',\n",
+      " 'infrastructure_InternetGateway',\n",
+      " 'infrastructure_ComputingGroup',\n",
+      " 'infrastructure_SecurityGroup',\n",
+      " 'infrastructure_Rule',\n",
+      " 'infrastructure_Credentials',\n",
+      " 'infrastructure_KeyPair',\n",
+      " 'infrastructure_UserPass',\n",
+      " 'infrastructure_SwarmRole',\n",
+      " 'infrastructure_Swarm',\n",
+      " 'infrastructure_ExtInfrastructureElement',\n",
+      " 'concrete_ConcreteInfrastructure',\n",
+      " 'concrete_ConcreteElement',\n",
+      " 'concrete_RuntimeProvider',\n",
+      " 'concrete_VirtualMachine',\n",
+      " 'concrete_VMImage',\n",
+      " 'concrete_ContainerImage',\n",
+      " 'concrete_Network',\n",
+      " 'concrete_Storage',\n",
+      " 'concrete_FunctionAsAService',\n",
+      " 'concrete_ComputingGroup']\n"
+     ]
+    }
+   ],
+   "source": [
+    "keys = list(meta_model.keys())\n",
+    "\n",
+    "pprint(keys)"
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3.11.0 ('.venv': poetry)",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.11.0"
+  },
+  "orig_nbformat": 4,
+  "vscode": {
+   "interpreter": {
+    "hash": "d98256633358fe1daa4009223d54520a3e2548801398a173545d5698bb289e16"
+   }
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/mc_openapi/doml_mc/example_faas.ipynb b/mc_openapi/notebooks/example_faas.ipynb
similarity index 87%
rename from mc_openapi/doml_mc/example_faas.ipynb
rename to mc_openapi/notebooks/example_faas.ipynb
index 00f4e0b2e9fb16ed9ec811a36a33ed6837967329..b377059a68a10a6b6c3adbaeb424bfd59e37f9f8 100644
--- a/mc_openapi/doml_mc/example_faas.ipynb
+++ b/mc_openapi/notebooks/example_faas.ipynb
@@ -8,7 +8,7 @@
    "source": [
     "from mc_openapi.doml_mc.intermediate_model.metamodel import parse_metamodel, parse_inverse_associations\n",
     "import yaml\n",
-    "with open(\"../assets/doml_meta.yaml\") as mmf:\n",
+    "with open(\"../assets/doml_meta_v2.0.yaml\") as mmf:\n",
     "    mmdoc = yaml.load(mmf, yaml.Loader)\n",
     "mm = parse_metamodel(mmdoc)\n",
     "inv_assoc = parse_inverse_associations(mmdoc)"
@@ -49,23 +49,13 @@
    "outputs": [],
    "source": [
     "from mc_openapi.doml_mc.xmi_parser.doml_model import parse_doml_model\n",
-    "doml_document_path = \"../../tests/doml/faas.domlx\"\n",
-    "# doml_document_path = \"../../tests/doml/nginx-openstack_v2_wrong.domlx\"\n",
+    "from mc_openapi.doml_mc import DOMLVersion\n",
+    "doml_document_path = \"../../tests/doml/v2.0/faas.domlx\"\n",
     "with open(doml_document_path, \"rb\") as xmif:\n",
     "    doc = xmif.read()\n",
     "\n",
-    "im = parse_doml_model(doc, mm)\n",
-    "print(im)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "from mc_openapi.doml_mc.intermediate_model.doml_element import reciprocate_inverse_associations\n",
-    "reciprocate_inverse_associations(im, inv_assoc)"
+    "im, _ = parse_doml_model(doc, DOMLVersion.V2_0)\n",
+    "# print(im)"
    ]
   },
   {
@@ -75,7 +65,7 @@
    "outputs": [],
    "source": [
     "IMPLICIT_MODULES.add('doml_mc.intermediate_model.doml_element')\n",
-    "pp.pprint(im)"
+    "# pp.pprint(im)"
    ]
   },
   {
@@ -98,9 +88,7 @@
     "\n",
     "from mc_openapi.doml_mc.z3encoding.metamodel_encoding import (\n",
     "    def_association_rel,\n",
-    "    assert_association_rel_constraints,\n",
     "    def_attribute_rel,\n",
-    "    assert_attribute_rel_constraints,\n",
     "    mk_association_sort_dict,\n",
     "    mk_attribute_sort_dict,\n",
     "    mk_class_sort_dict\n",
@@ -116,12 +104,12 @@
     "\n",
     "solver = Solver()\n",
     "\n",
-    "class_sort, class_ = mk_class_sort_dict(mm)\n",
-    "assoc_sort, assoc = mk_association_sort_dict(mm)\n",
-    "attr_sort, attr = mk_attribute_sort_dict(mm)\n",
-    "elem_sort, elem = mk_elem_sort_dict(im, unbound_elems)\n",
-    "ss_sort, ss = mk_stringsym_sort_dict(im, mm)\n",
-    "AData = mk_adata_sort(ss_sort)\n",
+    "class_sort, class_ = mk_class_sort_dict(mm, solver.ctx)\n",
+    "assoc_sort, assoc = mk_association_sort_dict(mm, solver.ctx)\n",
+    "attr_sort, attr = mk_attribute_sort_dict(mm, solver.ctx)\n",
+    "elem_sort, elem = mk_elem_sort_dict(im, solver.ctx, unbound_elems)\n",
+    "str_sort, str = mk_stringsym_sort_dict(im, mm, solver.ctx)\n",
+    "AData = mk_adata_sort(str_sort, solver.ctx)\n",
     "elem_class_f = def_elem_class_f_and_assert_classes(\n",
     "    im,\n",
     "    solver,\n",
@@ -144,7 +132,7 @@
     "    attr_sort,\n",
     "    attr,\n",
     "    AData,\n",
-    "    ss\n",
+    "    str\n",
     ")\n",
     "assoc_rel = def_association_rel(\n",
     "    assoc_sort,\n",
@@ -166,36 +154,7 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "assert_attribute_rel_constraints(\n",
-    "    mm,\n",
-    "    solver,\n",
-    "    attr_rel,\n",
-    "    attr,\n",
-    "    class_,\n",
-    "    elem_class_f,\n",
-    "    elem_sort,\n",
-    "    AData,\n",
-    "    ss\n",
-    ")\n",
-    "assert_association_rel_constraints(\n",
-    "    mm,\n",
-    "    solver,\n",
-    "    assoc_rel,\n",
-    "    assoc,\n",
-    "    class_,\n",
-    "    elem_class_f,\n",
-    "    elem_sort,\n",
-    "    inv_assoc\n",
-    ")"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "# solver.push()"
+    "solver.push()"
    ]
   },
   {
@@ -246,7 +205,7 @@
     "print(\"Number of attributes (IM):\", n_attrs_im)\n",
     "n_assocs_im = sum(len(a) for e in im.values() for a in e.associations.values())\n",
     "print(\"Number of associations (IM):\", n_assocs_im)\n",
-    "print(\"Number of string symbols:\", len(ss))\n",
+    "print(\"Number of string symbols:\", len(str))\n",
     "print(\"Number of IM attribute assertions:\", n_elems)\n",
     "print(\"Number of IM association assertions:\", n_elems ** 2)"
    ]
@@ -266,16 +225,7 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "# solver.unsat_core()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "# solver.statistics()"
+    "solver.unsat_core()"
    ]
   },
   {
@@ -293,7 +243,7 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "# All VMs have a network interface.\n",
+    "# 1. All VMs have a network interface.\n",
     "vm, iface = Consts(\"vm iface\", elem_sort)\n",
     "vmIfaceAssertion = ForAll(\n",
     "    [vm],\n",
@@ -314,7 +264,7 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "# All software packages can see the interfaces they need through a common network.\n",
+    "# 2. All software packages can see the interfaces they need through a common network.\n",
     "asc_consumer, asc_exposer, siface, net, net_iface, cn, vm, deployment, dc = Consts(\n",
     "    \"asc_consumer asc_exposer siface net net_iface cn vm deployment dc\", elem_sort\n",
     ")\n",
@@ -383,20 +333,20 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "# SoftwareComponents have a source_code property\n",
+    "# 3. SoftwareComponents have a source_code property\n",
     "softwareComponent, prop = Consts(\"softwareComponent prop\", elem_sort)\n",
     "nginxSourceCode = ForAll(\n",
     "    [softwareComponent],\n",
     "    Implies(\n",
     "        And(\n",
     "            elem_class_f(softwareComponent) == class_[\"application_SoftwareComponent\"],\n",
-    "            # attr_rel(softwareComponent, attr[\"commons_DOMLElement::name\"], AData.ss(ss[\"web\"]))\n",
+    "            # attr_rel(softwareComponent, attr[\"commons_DOMLElement::name\"], ADatastr(str[\"web\"]))\n",
     "        ),\n",
     "        Exists(\n",
     "            [prop],\n",
     "            And(\n",
     "                elem_class_f(prop) == class_[\"commons_SProperty\"],\n",
-    "                attr_rel(prop, attr[\"commons_Property::key\"], AData.ss(ss[\"source_code\"])),\n",
+    "                attr_rel(prop, attr[\"commons_Property::key\"], ADatastr(str[\"source_code\"])),\n",
     "                assoc_rel(softwareComponent, assoc[\"commons_DOMLElement::annotations\"], prop)\n",
     "            )\n",
     "        )\n",
@@ -411,7 +361,7 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "# There are no duplicated interfaces\n",
+    "# 4. There are no duplicated interfaces\n",
     "def any_iface(elem, iface):\n",
     "    ifaces_assocs = [\n",
     "        \"infrastructure_ComputingNode::ifaces\",\n",
@@ -438,7 +388,7 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "# All SoftwareComponents have been deployed somewhere\n",
+    "# 5. All SoftwareComponents have been deployed somewhere\n",
     "sc, deployment, ielem = Consts(\"sc deployment ielem\", elem_sort)\n",
     "assn = ForAll(\n",
     "    [sc],\n",
@@ -462,7 +412,7 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "# All abstract infrastructure elements are mapped to an element in the active concretization\n",
+    "# 6. All abstract infrastructure elements are mapped to an element in the active concretization\n",
     "def checkOneClass(ielem, concr, provider, celem, ielemClass, providerAssoc, celemAssoc):\n",
     "    return Implies(\n",
     "                elem_class_f(ielem) == class_[ielemClass],\n",
@@ -521,12 +471,12 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "# The \"web\" component has access to the Internet through https\n",
+    "# 7. The \"web\" component has access to the Internet through https\n",
     "web, deployment, ielem1, ielem2, iface, sg, rule = Consts(\"web deployment ielem1 ielem2 iface sg rule\", elem_sort)\n",
     "assn = ForAll(\n",
     "    [web],\n",
     "    Implies(\n",
-    "        attr_rel(web, attr[\"commons_DOMLElement::name\"], AData.ss(ss[\"web\"])),\n",
+    "        attr_rel(web, attr[\"commons_DOMLElement::name\"], ADatastr(str[\"web\"])),\n",
     "        Exists(  # web is deployed on a container hosting a VM with an interface in network n\n",
     "            [deployment, ielem1, ielem2, iface, rule],\n",
     "            And(\n",
@@ -538,7 +488,7 @@
     "                assoc_rel(sg, assoc[\"infrastructure_SecurityGroup::rules\"], rule),\n",
     "                attr_rel(rule, attr[\"infrastructure_Rule::fromPort\"], AData.int(443)),\n",
     "                attr_rel(rule, attr[\"infrastructure_Rule::toPort\"], AData.int(443)),\n",
-    "                attr_rel(rule, attr[\"infrastructure_Rule::kind\"], AData.ss(ss[\"INGRESS\"]))\n",
+    "                attr_rel(rule, attr[\"infrastructure_Rule::kind\"], ADatastr(str[\"INGRESS\"]))\n",
     "            ),\n",
     "        )\n",
     "    )\n",
@@ -597,13 +547,10 @@
   }
  ],
  "metadata": {
-  "interpreter": {
-   "hash": "a6678cf6b5907da3ee1c64f7f36cf1b3f0e5fe51f4038e28403f1c01345fc5bd"
-  },
   "kernelspec": {
-   "display_name": "mc_openapi",
+   "display_name": "Python 3.10.4 ('mc-openapi-dl7Bx6Lh-py3.10')",
    "language": "python",
-   "name": "mc_openapi"
+   "name": "python3"
   },
   "language_info": {
    "codemirror_mode": {
@@ -615,9 +562,14 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.9.13"
+   "version": "3.10.6"
   },
-  "orig_nbformat": 4
+  "orig_nbformat": 4,
+  "vscode": {
+   "interpreter": {
+    "hash": "ad63ed7e22c54016fdab5faefd8d83d59c3e39bc25e97a3e7b72bed4daaf83ed"
+   }
+  }
  },
  "nbformat": 4,
  "nbformat_minor": 2
diff --git a/mc_openapi/notebooks/example_nginx.ipynb b/mc_openapi/notebooks/example_nginx.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..5d6213826f7166dc742f389feb62068f5d34c11d
--- /dev/null
+++ b/mc_openapi/notebooks/example_nginx.ipynb
@@ -0,0 +1,411 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from mc_openapi.doml_mc.intermediate_model.metamodel import parse_metamodel, parse_inverse_associations\n",
+    "import yaml\n",
+    "with open(\"../assets/doml_meta_v2.0.yaml\") as mmf:\n",
+    "    mmdoc = yaml.load(mmf, yaml.Loader)\n",
+    "mm = parse_metamodel(mmdoc)\n",
+    "inv_assoc = parse_inverse_associations(mmdoc)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import prettyprinter as pp\n",
+    "from prettyprinter.prettyprinter import IMPLICIT_MODULES\n",
+    "pp.install_extras(include=['dataclasses'])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "IMPLICIT_MODULES.add('doml_mc.intermediate_model.metamodel')\n",
+    "pp.pprint(mm[\"application_SoftwareComponent\"])"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Load the DOML document here:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from mc_openapi.doml_mc.xmi_parser.doml_model import parse_doml_model\n",
+    "from mc_openapi.doml_mc import DOMLVersion\n",
+    "doml_document_path = \"../../tests/doml/v2.0/nginx-openstack_v2.0.domlx\"\n",
+    "# doml_document_path = \"../../tests/doml/v2.0/nginx-openstack_v2.0_wrong_vm_iface.domlx\"\n",
+    "with open(doml_document_path, \"rb\") as xmif:\n",
+    "    doc = xmif.read()\n",
+    "\n",
+    "im, _ = parse_doml_model(doc, DOMLVersion.V2_0)\n",
+    "print(im)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from mc_openapi.doml_mc.xmi_parser.doml_model import parse_xmi_model\n",
+    "doml_xmi = parse_xmi_model(doc, DOMLVersion.V2_0)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "print(dir(doml_xmi.eClass))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "IMPLICIT_MODULES.add('doml_mc.intermediate_model.doml_element')\n",
+    "pp.pprint(im)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "unbound_elems_n = 0\n",
+    "unbound_elems = [f\"unbound{i}\" for i in range(unbound_elems_n)]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from z3 import Solver\n",
+    "\n",
+    "from mc_openapi.doml_mc.z3encoding.metamodel_encoding import (\n",
+    "    def_association_rel,\n",
+    "    def_attribute_rel,\n",
+    "    mk_association_sort_dict,\n",
+    "    mk_attribute_sort_dict,\n",
+    "    mk_class_sort_dict\n",
+    ")\n",
+    "from mc_openapi.doml_mc.z3encoding.im_encoding import (\n",
+    "    assert_im_associations_q,\n",
+    "    assert_im_attributes,\n",
+    "    def_elem_class_f_and_assert_classes,\n",
+    "    mk_elem_sort_dict,\n",
+    "    mk_stringsym_sort_dict\n",
+    ")\n",
+    "from mc_openapi.doml_mc.z3encoding.utils import mk_adata_sort\n",
+    "\n",
+    "solver = Solver()\n",
+    "\n",
+    "class_sort, class_ = mk_class_sort_dict(mm, solver.ctx)\n",
+    "assoc_sort, assoc = mk_association_sort_dict(mm, solver.ctx)\n",
+    "attr_sort, attr = mk_attribute_sort_dict(mm, solver.ctx)\n",
+    "elem_sort, elem = mk_elem_sort_dict(im, solver.ctx, unbound_elems)\n",
+    "str_sort, str = mk_stringsym_sort_dict(im, mm, solver.ctx)\n",
+    "AData = mk_adata_sort(str_sort, solver.ctx)\n",
+    "elem_class_f = def_elem_class_f_and_assert_classes(\n",
+    "    im,\n",
+    "    solver,\n",
+    "    elem_sort,\n",
+    "    elem,\n",
+    "    class_sort,\n",
+    "    class_\n",
+    ")\n",
+    "attr_rel = def_attribute_rel(\n",
+    "    attr_sort,\n",
+    "    elem_sort,\n",
+    "    AData\n",
+    ")\n",
+    "assert_im_attributes(\n",
+    "    attr_rel,\n",
+    "    solver,\n",
+    "    im,\n",
+    "    mm,\n",
+    "    elem,\n",
+    "    attr_sort,\n",
+    "    attr,\n",
+    "    AData,\n",
+    "    str\n",
+    ")\n",
+    "assoc_rel = def_association_rel(\n",
+    "    assoc_sort,\n",
+    "    elem_sort\n",
+    ")\n",
+    "assert_im_associations_q(\n",
+    "    assoc_rel,\n",
+    "    solver,\n",
+    "    {k: v for k, v in im.items() if k not in unbound_elems},\n",
+    "    elem,\n",
+    "    assoc_sort,\n",
+    "    assoc,\n",
+    ")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# solver.push()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Metamodel statistics"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from mc_openapi.doml_mc.intermediate_model.metamodel import get_subclasses_dict\n",
+    "\n",
+    "print(\"Number of classes:\", len(mm))\n",
+    "print(\n",
+    "    \"Number of tuples in the subclass relation:\",\n",
+    "    sum(len(s) for s in get_subclasses_dict(mm).values())\n",
+    ")\n",
+    "n_attrs = sum(len(c.attributes) for c in mm.values())\n",
+    "print(\"Number of attributes:\", n_attrs)\n",
+    "print(\"Number of attribute assertions:\", 3 * n_attrs)\n",
+    "n_assocs = sum(len(c.associations) for c in mm.values())\n",
+    "print(\"Number of associations:\", n_assocs)\n",
+    "print(\"Number of associations assertions:\", 3 * n_assocs + len(inv_assoc))\n",
+    "\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### DOML model statistics"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "n_elems = len(im)\n",
+    "print(\"Number of elements:\", n_elems)\n",
+    "n_attrs_im = sum(len(e.attributes) for e in im.values())\n",
+    "print(\"Number of attributes (IM):\", n_attrs_im)\n",
+    "n_assocs_im = sum(len(a) for e in im.values() for a in e.associations.values())\n",
+    "print(\"Number of associations (IM):\", n_assocs_im)\n",
+    "print(\"Number of string symbols:\", len(str))\n",
+    "print(\"Number of IM attribute assertions:\", n_elems)\n",
+    "print(\"Number of IM association assertions:\", n_elems ** 2)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "solver.check()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "solver.unsat_core()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "solver.statistics()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from z3 import Consts, ForAll, Exists, Implies, And, Or, Not"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# All VMs have a network interface.\n",
+    "vm, iface = Consts(\n",
+    "    \"vm iface\", elem_sort\n",
+    ")\n",
+    "vmIfaceAssertion = ForAll(\n",
+    "    [vm],\n",
+    "    Implies(\n",
+    "        elem_class_f(vm) == class_[\"infrastructure_VirtualMachine\"],\n",
+    "        Exists(\n",
+    "            [iface],\n",
+    "            And(\n",
+    "                assoc_rel(vm, assoc[\"infrastructure_ComputingNode::ifaces\"], iface)\n",
+    "            )\n",
+    "        )\n",
+    "    )\n",
+    ")\n",
+    "solver.assert_and_track(vmIfaceAssertion, \"vm_iface\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Some VM has no network interface. \n",
+    "vm, iface = Consts(\"vm iface\", elem_sort)\n",
+    "vmIfaceNegAssertion = And(\n",
+    "    elem_class_f(vm) == class_[\"infrastructure_VirtualMachine\"],\n",
+    "    Not(\n",
+    "        Exists(\n",
+    "            [iface],\n",
+    "            assoc_rel(vm, assoc[\"infrastructure_ComputingNode::ifaces\"], iface)\n",
+    "        )\n",
+    "    )\n",
+    ")\n",
+    "solver.assert_and_track(vmIfaceNegAssertion, \"vm_iface_neg\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# nginx has a source code property\n",
+    "softwareComponent, prop = Consts(\"softwareComponent prop\", elem_sort)\n",
+    "nginxSourceCode = ForAll(\n",
+    "    [softwareComponent],\n",
+    "    Implies(\n",
+    "        And(\n",
+    "            elem_class_f(softwareComponent) == class_[\"application_SoftwareComponent\"],\n",
+    "            attr_rel(softwareComponent, attr[\"commons_DOMLElement::name\"], ADatastr(str[\"nginx\"]))\n",
+    "        ),\n",
+    "        Exists(\n",
+    "            [prop],\n",
+    "            And(\n",
+    "                elem_class_f(prop) == class_[\"commons_SProperty\"],\n",
+    "                attr_rel(prop, attr[\"commons_Property::key\"], ADatastr(str[\"source_code\"])),\n",
+    "                assoc_rel(softwareComponent, assoc[\"commons_DOMLElement::annotations\"], prop)\n",
+    "            )\n",
+    "        )\n",
+    "    )\n",
+    ")\n",
+    "solver.assert_and_track(nginxSourceCode, \"nginx_source_code\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "solver.check()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "solver.statistics().memory"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "model = solver.model()\n",
+    "# print(model)\n",
+    "print(model[vm])"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from itertools import product\n",
+    "for (e1n, e1), a, (e2n, e2) in product(elem.items(), assoc.values(), elem.items()):\n",
+    "    if (e1n in unbound_elems or e2n in unbound_elems) and m.eval(assoc_rel(e1, a, e2)):\n",
+    "        print(e1, a, e2)"
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3.10.4 ('mc-openapi-dl7Bx6Lh-py3.10')",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.10.6"
+  },
+  "orig_nbformat": 4,
+  "vscode": {
+   "interpreter": {
+    "hash": "ad63ed7e22c54016fdab5faefd8d83d59c3e39bc25e97a3e7b72bed4daaf83ed"
+   }
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/mc_openapi/notebooks/find_missing_requirement.ipynb b/mc_openapi/notebooks/find_missing_requirement.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..8229d3b7ffdee975f835a143300012e2767a126c
--- /dev/null
+++ b/mc_openapi/notebooks/find_missing_requirement.ipynb
@@ -0,0 +1,500 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Finding Missing Requirements\n",
+    "\n",
+    "In this notebook, I try to put together an iterative way to:\n",
+    "1. Add *unbound variables* until the requirement is satisfied\n",
+    "2. Get the *relationships* of the unbound variables\n",
+    "3. Filter these relationships by adding one at a time as a negated constraint\n",
+    "   and check again the model.\n",
+    "4. When we find the one that makes the model unsat, it means we've found the right one.\n",
+    "\n",
+    "#### Goals\n",
+    "- Make the search of finding the correct relationship as fast as possible:\n",
+    "  usually relationships are quite a lot, and we need to iterate them at least a\n",
+    "  couple of times. We can add progressively only the relationships that remain\n",
+    "  after each pass, always one at a time and checking the model again."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 32,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from mc_openapi.doml_mc.intermediate_model.metamodel import parse_metamodel, parse_inverse_associations\n",
+    "from mc_openapi.doml_mc.xmi_parser.doml_model import parse_doml_model\n",
+    "from mc_openapi.doml_mc.xmi_parser.doml_model import parse_xmi_model\n",
+    "from mc_openapi.doml_mc import DOMLVersion\n",
+    "from z3 import Solver, Model, DatatypeSortRef, FuncDeclRef, Consts, Const, ForAll, Exists, Implies, And, Or, Not, Bools, sat, unsat\n",
+    "import yaml\n",
+    "\n",
+    "from mc_openapi.doml_mc.z3encoding.metamodel_encoding import (\n",
+    "    def_association_rel,\n",
+    "    def_attribute_rel,\n",
+    "    mk_association_sort_dict,\n",
+    "    mk_attribute_sort_dict,\n",
+    "    mk_class_sort_dict\n",
+    ")\n",
+    "from mc_openapi.doml_mc.z3encoding.im_encoding import (\n",
+    "    assert_im_associations,\n",
+    "    assert_im_attributes,\n",
+    "    def_elem_class_f_and_assert_classes,\n",
+    "    mk_elem_sort_dict,\n",
+    "    mk_stringsym_sort_dict,\n",
+    "    mk_attr_data_sort\n",
+    ")\n",
+    "from mc_openapi.doml_mc.z3encoding.types import Refs\n",
+    "\n",
+    "from itertools import product\n",
+    "from operator import itemgetter"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 33,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "with open(\"../assets/doml_meta_v2.0.yaml\") as mmf:\n",
+    "    mmdoc = yaml.load(mmf, yaml.Loader)\n",
+    "mm = parse_metamodel(mmdoc)\n",
+    "inv_assoc = parse_inverse_associations(mmdoc)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "**You can change here the input DOML file**"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 34,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# doml_document_path = \"../../tests/doml/nginx-openstack_v2.0.domlx\"\n",
+    "doml_document_path = \"../../tests/doml/v2.0/nginx-openstack_v2.0_wrong_vm_iface.domlx\"\n",
+    "# doml_document_path = \"../../tests/doml/nginx-openstack_v2.0_wrong_iface_uniq.domlx\"\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 35,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "with open(doml_document_path, \"rb\") as xmif:\n",
+    "    doc = xmif.read()\n",
+    "\n",
+    "im, _ = parse_doml_model(doc, DOMLVersion.V2_0)\n",
+    "doml_xmi = parse_xmi_model(doc, DOMLVersion.V2_0)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "We need to initialize each time the Solver context before iterating,\n",
+    "since an unbound variable is an element, and elements are an EnumSort,\n",
+    "and EnumSorts cannot be modified and depend on the solver context.\n",
+    "\n",
+    "The following code is stuff that is already present in the `IntermediateModelChecker`."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 36,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from typing import Dict\n",
+    "\n",
+    "Context = Dict"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 37,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def initialize_solver(\n",
+    "    unbound_elems_quantity: int = 0,\n",
+    "    requirements: list = []\n",
+    ") -> Context:\n",
+    "    ctx = dict()\n",
+    "    \n",
+    "    ctx[\"solver\"] = Solver()\n",
+    "\n",
+    "    ctx[\"class_sort\"], ctx[\"class_\"] = mk_class_sort_dict(mm, ctx[\"solver\"].ctx)\n",
+    "    ctx[\"assoc_sort\"], ctx[\"assoc\"] = mk_association_sort_dict(mm, ctx[\"solver\"].ctx)\n",
+    "    ctx[\"attr_sort\"], ctx[\"attr\"] = mk_attribute_sort_dict(mm, ctx[\"solver\"].ctx)\n",
+    "    ctx[\"str_sort\"], ctx[\"str\"] = mk_stringsym_sort_dict(im, mm, ctx[\"solver\"].ctx)\n",
+    "    ctx[\"attr_data_sort\"] = mk_attr_data_sort(ctx[\"str_sort\"], ctx[\"solver\"].ctx)\n",
+    "\n",
+    "    ctx[\"unbound_elems\"] = [f\"unbound{i}\" for i in range(unbound_elems_quantity)]\n",
+    "    ctx[\"elem_sort\"], ctx[\"elem\"] = mk_elem_sort_dict(im, ctx[\"solver\"].ctx, ctx[\"unbound_elems\"])\n",
+    "\n",
+    "    ctx[\"elem_class_f\"] = def_elem_class_f_and_assert_classes(\n",
+    "        im,\n",
+    "        ctx[\"solver\"],\n",
+    "        ctx[\"elem_sort\"],\n",
+    "        ctx[\"elem\"],\n",
+    "        ctx[\"class_sort\"],\n",
+    "        ctx[\"class_\"]\n",
+    "    )\n",
+    "    # attr_rel :: (elem_sort, attr_sort, attr_data_sort) -> BoolRef\n",
+    "    ctx[\"attr_rel\"] = def_attribute_rel(\n",
+    "        ctx[\"attr_sort\"],\n",
+    "        ctx[\"elem_sort\"],\n",
+    "        ctx[\"attr_data_sort\"]\n",
+    "    )\n",
+    "    assert_im_attributes(\n",
+    "        ctx[\"attr_rel\"],\n",
+    "        ctx[\"solver\"],\n",
+    "        im,\n",
+    "        mm,\n",
+    "        ctx[\"elem\"],\n",
+    "        ctx[\"attr_sort\"],\n",
+    "        ctx[\"attr\"],\n",
+    "        ctx[\"attr_data_sort\"],\n",
+    "        ctx[\"str\"]\n",
+    "    )\n",
+    "\n",
+    "    # assoc_rel :: (elem_sort, assoc_sort, elem_sort) -> BoolRef\n",
+    "    ctx[\"assoc_rel\"] = def_association_rel(\n",
+    "        ctx[\"assoc_sort\"],\n",
+    "        ctx[\"elem_sort\"]\n",
+    "    )\n",
+    "    assert_im_associations(\n",
+    "        ctx[\"assoc_rel\"],\n",
+    "        ctx[\"solver\"],\n",
+    "        {k: v for k, v in im.items() if k not in ctx[\"unbound_elems\"]},\n",
+    "        ctx[\"elem\"],\n",
+    "        ctx[\"assoc_sort\"],\n",
+    "        ctx[\"assoc\"],\n",
+    "    )\n",
+    "\n",
+    "    # Add requirements\n",
+    "    for req in requirements:\n",
+    "        req(ctx)\n",
+    "\n",
+    "    return ctx"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 38,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def req_every_vm_has_iface(ctx: Context):    \n",
+    "    vm, iface = Consts(\"vm iface\", ctx[\"elem_sort\"])\n",
+    "    vmIfaceAssertion = ForAll(\n",
+    "        [vm],\n",
+    "        Implies(\n",
+    "            ctx[\"elem_class_f\"](vm) == ctx[\"class_\"][\"infrastructure_VirtualMachine\"],\n",
+    "            Exists(\n",
+    "                [iface],\n",
+    "                And(\n",
+    "                    ctx[\"assoc_rel\"](vm, ctx[\"assoc\"][\"infrastructure_ComputingNode::ifaces\"], iface)\n",
+    "                )\n",
+    "            )\n",
+    "        )\n",
+    "    )\n",
+    "    ctx[\"solver\"].assert_and_track(vmIfaceAssertion, \"vm_iface\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 39,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def req_every_iface_has_a_secgroup(ctx):\n",
+    "    sg, iface = Consts(\"sg iface\", ctx[\"elem_sort\"])\n",
+    "    vmIfaceSecGroupAssertion = ForAll(\n",
+    "        [sg],\n",
+    "        Implies(\n",
+    "            ctx[\"elem_class_f\"](sg) == ctx[\"class_\"][\"infrastructure_SecurityGroup\"],\n",
+    "            Exists([iface], \n",
+    "                ctx[\"assoc_rel\"](iface, ctx[\"assoc\"][\"infrastructure_NetworkInterface::associated\"], sg)\n",
+    "            )\n",
+    "        )\n",
+    "    )\n",
+    "    ctx[\"solver\"].assert_and_track(vmIfaceSecGroupAssertion, \"vm_secgroup\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 40,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# There are no duplicated interfaces.\n",
+    "def req_iface_uniq(ctx):\n",
+    "    endPointAttr = ctx[\"attr\"][\"infrastructure_NetworkInterface::endPoint\"]\n",
+    "    ni1, ni2 = Consts(\"ni1, ni2\", ctx[\"elem_sort\"])\n",
+    "    value = Const(\"value\", ctx[\"attr_data_sort\"])\n",
+    "    uniqueIfaceAssertion = And(\n",
+    "        ctx[\"attr_rel\"](ni1, endPointAttr, value),\n",
+    "        ctx[\"attr_rel\"](ni2, endPointAttr, value),\n",
+    "        ni1 != ni2,\n",
+    "    )\n",
+    "    ctx[\"solver\"].assert_and_track(uniqueIfaceAssertion, \"unique_iface\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 41,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def check_with_ubvars(ubvars_n: int = 0, requirements: list = []) -> Context:\n",
+    "    ctx = initialize_solver(ubvars_n, requirements)\n",
+    "    solver = ctx[\"solver\"]\n",
+    "\n",
+    "    res = solver.check()\n",
+    "\n",
+    "    if res == sat:\n",
+    "        print(f\"Sat with {ubvars_n} unbounded variables\")\n",
+    "        return ctx\n",
+    "    elif res == unsat:\n",
+    "        # print(f\"ubvars={ubvars_n}; UNSAT_CORE:\")\n",
+    "        # print(solver.unsat_core())\n",
+    "        print(f\"Increasing unbound vars to {ubvars_n + 1}\")\n",
+    "        return check_with_ubvars(ubvars_n + 1, requirements=requirements)\n",
+    "    else:\n",
+    "        raise RuntimeError(\"It took too long to decide.\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 42,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "REQUIREMENTS = [\n",
+    "    req_every_vm_has_iface,\n",
+    "    req_every_iface_has_a_secgroup,\n",
+    "    req_iface_uniq\n",
+    "]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 43,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Increasing unbound vars to 1\n",
+      "Increasing unbound vars to 2\n",
+      "Sat with 2 unbounded variables\n"
+     ]
+    }
+   ],
+   "source": [
+    "solved_ctx = check_with_ubvars(requirements=REQUIREMENTS)\n",
+    "solved_model = solved_ctx[\"solver\"].model()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 44,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def get_ubvars_and_assoc(ctx: Context, model: Model):\n",
+    "    elem, assoc, assoc_rel, unbound_elems = itemgetter(\"elem\", \"assoc\", \"assoc_rel\", \"unbound_elems\")(ctx)\n",
+    "\n",
+    "    return [ ((e1n, e1), a, (e2n, e2)) \n",
+    "        for (e1n, e1), a, (e2n, e2) in product(elem.items(), assoc.values(), elem.items()) \n",
+    "        if (e1n in unbound_elems or e2n in unbound_elems) and model.eval(assoc_rel(e1, a, e2))\n",
+    "    ]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 45,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def pretty_ubvar_assoc(assoc):\n",
+    "    (e1n, e1), a, (e2n, e2) = assoc\n",
+    "    tokens = str(str(e1) + \" \" + str(a) + \" \" + str(e2)).split()\n",
+    "    ret_str = \"\"\n",
+    "    for token in tokens:\n",
+    "        if token[0:4] == \"elem\":\n",
+    "            value = im.get(token)\n",
+    "            ret_str += f\"{value.class_} ({value.user_friendly_name})\" if value else f\"<'{token}' not found>\"\n",
+    "        else:\n",
+    "            ret_str += token\n",
+    "        ret_str += \" \"\n",
+    "    return ret_str.strip()"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "As we can see, there are many associations that involve the unbound variable `unbound0`.\n",
+    "We can see that between them, there is the one we really want:\n",
+    "\n",
+    "`infrastructure_VirtualMachine (vm1) infrastructure_ComputingNode::ifaces unbound0`\n",
+    "\n",
+    "We now need to filter out all the others, by taking one of these lines at a time, and adding it as a negated constraint.\n",
+    "\n",
+    "NOTE: It appears that the list is not deterministic. Sometimes at the end there are associations that start from `unbound0`, sometimes there is none. "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 46,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "ubvars_and_assoc = get_ubvars_and_assoc(solved_ctx, solved_model)\n",
+    "# print(\"\\n\".join([pretty_ubvar_assoc(assoc) for assoc in ubvars_and_assoc]))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 52,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "-----------------------------------------\n",
+      "\tAdd constraint Not(infrastructure_VirtualMachine (vm1) infrastructure_ComputingNode::ifaces unbound0)\n"
+     ]
+    },
+    {
+     "ename": "Z3Exception",
+     "evalue": "True, False or Z3 Boolean expression expected. Received [__neg_{e1_name}_{str(a)}_{e2_name}] of type <class 'list'>",
+     "output_type": "error",
+     "traceback": [
+      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
+      "\u001b[0;31mZ3Exception\u001b[0m                               Traceback (most recent call last)",
+      "Cell \u001b[0;32mIn [52], line 44\u001b[0m\n\u001b[1;32m     40\u001b[0m             \u001b[39mprint\u001b[39m(\u001b[39m\"\u001b[39m\u001b[39m\\t\u001b[39;00m\u001b[39m\\t\u001b[39;00m\u001b[39m\"\u001b[39m \u001b[39m+\u001b[39m \u001b[39m\"\u001b[39m\u001b[39m\\n\u001b[39;00m\u001b[39m\\t\u001b[39;00m\u001b[39m\\t\u001b[39;00m\u001b[39m\"\u001b[39m\u001b[39m.\u001b[39mjoin([pretty_ubvar_assoc(assoc) \u001b[39mfor\u001b[39;00m assoc \u001b[39min\u001b[39;00m ubvars_and_assoc[\u001b[39m1\u001b[39m:]]))\n\u001b[1;32m     41\u001b[0m         \u001b[39mreturn\u001b[39;00m [\u001b[39m*\u001b[39m\u001b[39mset\u001b[39m([assoc] \u001b[39m+\u001b[39m thin_ubvars_and_assoc(ctx, ubvars_and_assoc[\u001b[39m1\u001b[39m:]))]\n\u001b[0;32m---> 44\u001b[0m assoc_to_implement \u001b[39m=\u001b[39m thin_ubvars_and_assoc(solved_ctx, ubvars_and_assoc)\n",
+      "Cell \u001b[0;32mIn [52], line 18\u001b[0m, in \u001b[0;36mthin_ubvars_and_assoc\u001b[0;34m(ctx, ubvars_and_assoc)\u001b[0m\n\u001b[1;32m     16\u001b[0m \u001b[39m# ctx[\"solver\"].assert_and_track(Not(assoc_rel), f\"__neg_{e1_name}_{str(a)}_{e2_name}\")\u001b[39;00m\n\u001b[1;32m     17\u001b[0m x \u001b[39m=\u001b[39m Bools(\u001b[39m\"\u001b[39m\u001b[39m__neg_\u001b[39m\u001b[39m{e1_name}\u001b[39;00m\u001b[39m_\u001b[39m\u001b[39m{\u001b[39m\u001b[39mstr(a)}_\u001b[39m\u001b[39m{e2_name}\u001b[39;00m\u001b[39m\"\u001b[39m)\n\u001b[0;32m---> 18\u001b[0m ctx[\u001b[39m\"\u001b[39m\u001b[39msolver\u001b[39m\u001b[39m\"\u001b[39m]\u001b[39m.\u001b[39madd(Implies(x, Not(assoc_rel)))\n\u001b[1;32m     20\u001b[0m res \u001b[39m=\u001b[39m ctx[\u001b[39m\"\u001b[39m\u001b[39msolver\u001b[39m\u001b[39m\"\u001b[39m]\u001b[39m.\u001b[39mcheck()\n\u001b[1;32m     21\u001b[0m \u001b[39mif\u001b[39;00m res \u001b[39m==\u001b[39m sat:\n",
+      "File \u001b[0;32m~/Projects/piacere-model-checker/.venv/lib/python3.10/site-packages/z3/z3.py:1785\u001b[0m, in \u001b[0;36mImplies\u001b[0;34m(a, b, ctx)\u001b[0m\n\u001b[1;32m   1783\u001b[0m ctx \u001b[39m=\u001b[39m _get_ctx(_ctx_from_ast_arg_list([a, b], ctx))\n\u001b[1;32m   1784\u001b[0m s \u001b[39m=\u001b[39m BoolSort(ctx)\n\u001b[0;32m-> 1785\u001b[0m a \u001b[39m=\u001b[39m s\u001b[39m.\u001b[39;49mcast(a)\n\u001b[1;32m   1786\u001b[0m b \u001b[39m=\u001b[39m s\u001b[39m.\u001b[39mcast(b)\n\u001b[1;32m   1787\u001b[0m \u001b[39mreturn\u001b[39;00m BoolRef(Z3_mk_implies(ctx\u001b[39m.\u001b[39mref(), a\u001b[39m.\u001b[39mas_ast(), b\u001b[39m.\u001b[39mas_ast()), ctx)\n",
+      "File \u001b[0;32m~/Projects/piacere-model-checker/.venv/lib/python3.10/site-packages/z3/z3.py:1528\u001b[0m, in \u001b[0;36mBoolSortRef.cast\u001b[0;34m(self, val)\u001b[0m\n\u001b[1;32m   1526\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mnot\u001b[39;00m is_expr(val):\n\u001b[1;32m   1527\u001b[0m     msg \u001b[39m=\u001b[39m \u001b[39m\"\u001b[39m\u001b[39mTrue, False or Z3 Boolean expression expected. Received \u001b[39m\u001b[39m%s\u001b[39;00m\u001b[39m of type \u001b[39m\u001b[39m%s\u001b[39;00m\u001b[39m\"\u001b[39m\n\u001b[0;32m-> 1528\u001b[0m     _z3_assert(is_expr(val), msg \u001b[39m%\u001b[39;49m (val, \u001b[39mtype\u001b[39;49m(val)))\n\u001b[1;32m   1529\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mnot\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39meq(val\u001b[39m.\u001b[39msort()):\n\u001b[1;32m   1530\u001b[0m     _z3_assert(\u001b[39mself\u001b[39m\u001b[39m.\u001b[39meq(val\u001b[39m.\u001b[39msort()), \u001b[39m\"\u001b[39m\u001b[39mValue cannot be converted into a Z3 Boolean value\u001b[39m\u001b[39m\"\u001b[39m)\n",
+      "File \u001b[0;32m~/Projects/piacere-model-checker/.venv/lib/python3.10/site-packages/z3/z3.py:107\u001b[0m, in \u001b[0;36m_z3_assert\u001b[0;34m(cond, msg)\u001b[0m\n\u001b[1;32m    105\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39m_z3_assert\u001b[39m(cond, msg):\n\u001b[1;32m    106\u001b[0m     \u001b[39mif\u001b[39;00m \u001b[39mnot\u001b[39;00m cond:\n\u001b[0;32m--> 107\u001b[0m         \u001b[39mraise\u001b[39;00m Z3Exception(msg)\n",
+      "\u001b[0;31mZ3Exception\u001b[0m: True, False or Z3 Boolean expression expected. Received [__neg_{e1_name}_{str(a)}_{e2_name}] of type <class 'list'>"
+     ]
+    }
+   ],
+   "source": [
+    "def thin_ubvars_and_assoc(ctx: Context, ubvars_and_assoc: list):\n",
+    "    \"\"\"Returns a tuple where the first item is\n",
+    "    \"\"\"\n",
+    "    if not ubvars_and_assoc:\n",
+    "        return []\n",
+    "\n",
+    "\n",
+    "    (e1_name, e1), a, (e2_name, e2) = assoc = ubvars_and_assoc[0]\n",
+    "    assoc_rel = ctx[\"assoc_rel\"](e1, a, e2)\n",
+    "    \n",
+    "    print(\"-----------------------------------------\")\n",
+    "\n",
+    "    # Add negated constraint\n",
+    "    print(f\"\\tAdd constraint Not({pretty_ubvar_assoc(ubvars_and_assoc[0])})\")\n",
+    "    ctx[\"solver\"].push()\n",
+    "    # ctx[\"solver\"].assert_and_track(Not(assoc_rel), f\"__neg_{e1_name}_{str(a)}_{e2_name}\")\n",
+    "    ctx[\"solver\"].add(Not(assoc_rel))\n",
+    "    \n",
+    "    res = ctx[\"solver\"].check()\n",
+    "    if res == sat:\n",
+    "        print(\"SAT:\\tAdding one more constraint and trying again\")\n",
+    "        # Get new ubvars_and_assoc\n",
+    "        model = ctx[\"solver\"].model()\n",
+    "        thinned_ubvars_and_assoc = get_ubvars_and_assoc(ctx, model)\n",
+    "        \n",
+    "        # Print table showing the diff\n",
+    "        from difflib import context_diff\n",
+    "        uvar_as_text = lambda input: [pretty_ubvar_assoc(assoc) for assoc in input]\n",
+    "        print(\"\\n\".join([a for a in context_diff(uvar_as_text(ubvars_and_assoc), uvar_as_text(thinned_ubvars_and_assoc), lineterm=\"\", fromfile='Before', tofile=\"After\")]))\n",
+    "\n",
+    "        # Iterate\n",
+    "        return thin_ubvars_and_assoc(ctx, thinned_ubvars_and_assoc)\n",
+    "    else:\n",
+    "        print(\"UNSAT\\tLast constraint was the association we are looking for!\")\n",
+    "        ctx[\"solver\"].pop()\n",
+    "        \n",
+    "        if ubvars_and_assoc[1:]:\n",
+    "            print(\"\\tIterating over\")\n",
+    "            print(\"\\t\\t\" + \"\\n\\t\\t\".join([pretty_ubvar_assoc(assoc) for assoc in ubvars_and_assoc[1:]]))\n",
+    "        return [*set([assoc] + thin_ubvars_and_assoc(ctx, ubvars_and_assoc[1:]))]\n",
+    "\n",
+    "\n",
+    "assoc_to_implement = thin_ubvars_and_assoc(solved_ctx, ubvars_and_assoc)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "infrastructure_VirtualMachine (vm1) infrastructure_ComputingNode::ifaces unbound1\n",
+      "unbound1 infrastructure_NetworkInterface::associated infrastructure_SecurityGroup (sg)\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(\"\\n\".join([pretty_ubvar_assoc(assoc) for assoc in assoc_to_implement]))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "From here, we should then add this in the Intermediate Model, and then in the ECore (?) to generate the DOML file somehow.\n",
+    "\n",
+    "We can then provide the new file, or a diff to be patched onto the original?"
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3.10.7 ('.venv': poetry)",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.10.8"
+  },
+  "orig_nbformat": 4,
+  "vscode": {
+   "interpreter": {
+    "hash": "d98256633358fe1daa4009223d54520a3e2548801398a173545d5698bb289e16"
+   }
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/mc_openapi/notebooks/find_missing_requirement_with_attrs.ipynb b/mc_openapi/notebooks/find_missing_requirement_with_attrs.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..a30bc463263626ab2c0341274b13f75b22d171ef
--- /dev/null
+++ b/mc_openapi/notebooks/find_missing_requirement_with_attrs.ipynb
@@ -0,0 +1,773 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Finding Missing Requirements (with Attributes)\n",
+    "\n",
+    "In this notebook, I try to put together an iterative way to:\n",
+    "1. Add *unbound variables* until the requirement is satisfied\n",
+    "2. Get the *relationships* of the unbound variables\n",
+    "3. Filter these relationships by adding one at a time as a negated constraint\n",
+    "   and check again the model.\n",
+    "4. When we find the one that makes the model unsat, it means we've found the right one.\n",
+    "\n",
+    "#### Goals\n",
+    "- Make the search of finding the correct relationship as fast as possible:\n",
+    "  usually relationships are quite a lot, and we need to iterate them at least a\n",
+    "  couple of times. We can add progressively only the relationships that remain\n",
+    "  after each pass, always one at a time and checking the model again."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 37,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from itertools import product\n",
+    "from operator import itemgetter\n",
+    "\n",
+    "import yaml\n",
+    "from z3 import (And, Const, Consts, DatatypeSortRef, Exists, ForAll,\n",
+    "                FuncDeclRef, Implies, Model, Not, Or, Solver, sat, unsat)\n",
+    "\n",
+    "from mc_openapi.doml_mc import DOMLVersion\n",
+    "from mc_openapi.doml_mc.intermediate_model.metamodel import (\n",
+    "    parse_inverse_associations, parse_metamodel)\n",
+    "from mc_openapi.doml_mc.xmi_parser.doml_model import (parse_doml_model,\n",
+    "                                                      parse_xmi_model)\n",
+    "from mc_openapi.doml_mc.z3encoding.im_encoding import (\n",
+    "    assert_im_associations, assert_im_attributes,\n",
+    "    def_elem_class_f_and_assert_classes, mk_attr_data_sort, mk_elem_sort_dict,\n",
+    "    mk_stringsym_sort_dict)\n",
+    "from mc_openapi.doml_mc.z3encoding.metamodel_encoding import (\n",
+    "    def_association_rel, def_attribute_rel, mk_association_sort_dict,\n",
+    "    mk_attribute_sort_dict, mk_class_sort_dict)\n",
+    "from mc_openapi.doml_mc.z3encoding.types import Refs"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 38,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "with open(\"../assets/doml_meta_v2.0.yaml\") as mmf:\n",
+    "    mmdoc = yaml.load(mmf, yaml.Loader)\n",
+    "mm = parse_metamodel(mmdoc)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "**You can change here the input DOML file**"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 39,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# doml_document_path = \"../../tests/doml/nginx-openstack_v2.0.domlx\"\n",
+    "# doml_document_path = \"../../tests/doml/v2.0/nginx-openstack_v2.0_wrong_vm_iface.domlx\"\n",
+    "# doml_document_path = \"../../tests/doml/nginx-openstack_v2.0_wrong_iface_uniq.domlx\"\n",
+    "# doml_document_path = \"../../tests/doml/saas_no_https_rule.domlx\"\n",
+    "# doml_document_path = \"../../tests/doml/saas_https_no_attrs.domlx\"\n",
+    "doml_document_path = \"../../tests/doml/openstack_template.domlx\""
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 40,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "with open(doml_document_path, \"rb\") as xmif:\n",
+    "    doc = xmif.read()\n",
+    "\n",
+    "im, _ = parse_doml_model(doc, DOMLVersion.V2_0)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "We need to initialize each time the Solver context before iterating,\n",
+    "since an unbound variable is an element, and elements are an EnumSort,\n",
+    "and EnumSorts cannot be modified and depend on the solver context.\n",
+    "\n",
+    "The following code is stuff that is already present in the `IntermediateModelChecker`."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 41,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from typing import Dict\n",
+    "\n",
+    "Context = Dict"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 42,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from mc_openapi.doml_mc.intermediate_model.metamodel import get_mangled_attribute_defaults\n",
+    "\n",
+    "\n",
+    "def initialize_solver(\n",
+    "    unbound_elems_quantity: int = 0,\n",
+    "    unbound_values_quantity: int = 0,\n",
+    "    requirements: list = []\n",
+    ") -> Context:\n",
+    "    ctx = dict()\n",
+    "    \n",
+    "    ctx[\"solver\"] = Solver()\n",
+    "\n",
+    "    ctx[\"class_sort\"], ctx[\"class_\"] = mk_class_sort_dict(mm, ctx[\"solver\"].ctx)\n",
+    "    ctx[\"assoc_sort\"], ctx[\"assoc\"] = mk_association_sort_dict(mm, ctx[\"solver\"].ctx)\n",
+    "    ctx[\"attr_sort\"], ctx[\"attr\"] = mk_attribute_sort_dict(mm, ctx[\"solver\"].ctx)\n",
+    "    ctx[\"str_sort\"], ctx[\"str\"] = mk_stringsym_sort_dict(im, mm, ctx[\"solver\"].ctx)\n",
+    "    ctx[\"attr_data_sort\"] = mk_attr_data_sort(ctx[\"str_sort\"], ctx[\"solver\"].ctx)\n",
+    "\n",
+    "    ctx[\"unbound_elems\"] = [f\"unbound_elem_{i}\" for i in range(unbound_elems_quantity)]\n",
+    "\n",
+    "    # Takes a list of strings and creates an Enum out of 'em\n",
+    "    ctx[\"elem_sort\"], ctx[\"elem\"] = mk_elem_sort_dict(im, ctx[\"solver\"].ctx, ctx[\"unbound_elems\"])\n",
+    "\n",
+    "    ub_val_names = [f\"unbound_val_{i}\" for i in range(unbound_values_quantity)]\n",
+    "    ctx[\"unbound_values\"] = {\n",
+    "        name : ctx[\"attr_data_sort\"].placeholder for name in ub_val_names\n",
+    "    }\n",
+    "    # Examples of values that can go in unbound_values:\n",
+    "    # ctx[\"attr_data_sort\"].int(42), # ok\n",
+    "    # ctx[\"attr_data_sort\"].bool(True), # ok\n",
+    "    # ctx[\"attr_data_sort\"].str(\"x\"), # cant do: it accept a ctx[\"str\"][<str_key>] as input\n",
+    "    # Const(\"x\", ctx[\"attr_data_sort\"]) # cant do: it is a symbolic value that cannot be converted to a BoolRef expression\n",
+    "\n",
+    "    ctx[\"elem_class_f\"] = def_elem_class_f_and_assert_classes(\n",
+    "        im,\n",
+    "        ctx[\"solver\"],\n",
+    "        ctx[\"elem_sort\"],\n",
+    "        ctx[\"elem\"],\n",
+    "        ctx[\"class_sort\"],\n",
+    "        ctx[\"class_\"]\n",
+    "    )\n",
+    "    \n",
+    "    # attr_rel :: (elem_sort, attr_sort, attr_data_sort) -> BoolRef\n",
+    "    ctx[\"attr_rel\"] = def_attribute_rel(\n",
+    "        ctx[\"attr_sort\"],\n",
+    "        ctx[\"elem_sort\"],\n",
+    "        ctx[\"attr_data_sort\"]\n",
+    "    )\n",
+    "\n",
+    "    assert_im_attributes(\n",
+    "        ctx[\"attr_rel\"],\n",
+    "        ctx[\"solver\"],\n",
+    "        im,\n",
+    "        mm,\n",
+    "        ctx[\"elem\"],\n",
+    "        ctx[\"attr_sort\"],\n",
+    "        ctx[\"attr\"],\n",
+    "        ctx[\"attr_data_sort\"],\n",
+    "        ctx[\"str\"]\n",
+    "    )\n",
+    "\n",
+    "    # assoc_rel :: (elem_sort, assoc_sort, elem_sort) -> BoolRef\n",
+    "    ctx[\"assoc_rel\"] = def_association_rel(\n",
+    "        ctx[\"assoc_sort\"],\n",
+    "        ctx[\"elem_sort\"]\n",
+    "    )\n",
+    "    \n",
+    "    assert_im_associations(\n",
+    "        ctx[\"assoc_rel\"],\n",
+    "        ctx[\"solver\"],\n",
+    "        {k: v for k, v in im.items() if k not in ctx[\"unbound_elems\"]},\n",
+    "        ctx[\"elem\"],\n",
+    "        ctx[\"assoc_sort\"],\n",
+    "        ctx[\"assoc\"],\n",
+    "    )\n",
+    "\n",
+    "    # Add requirements\n",
+    "    for req in requirements:\n",
+    "        req(ctx)\n",
+    "\n",
+    "    return ctx"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 43,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def req_every_vm_has_iface(ctx: Context):    \n",
+    "    vm, iface = Consts(\"vm iface\", ctx[\"elem_sort\"])\n",
+    "    vmIfaceAssertion = ForAll(\n",
+    "        [vm],\n",
+    "        Implies(\n",
+    "            ctx[\"elem_class_f\"](vm) == ctx[\"class_\"][\"infrastructure_VirtualMachine\"],\n",
+    "            Exists(\n",
+    "                [iface],\n",
+    "                And(\n",
+    "                    ctx[\"assoc_rel\"](vm, ctx[\"assoc\"][\"infrastructure_ComputingNode::ifaces\"], iface)\n",
+    "                )\n",
+    "            )\n",
+    "        )\n",
+    "    )\n",
+    "    ctx[\"solver\"].assert_and_track(vmIfaceAssertion, \"vm_iface\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 44,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def req_every_vm_has_cpucount(ctx: Context):    \n",
+    "    vm = Const(\"vm\", ctx[\"elem_sort\"])\n",
+    "    CpuCount = Const(\"cpucount\", ctx[\"attr_data_sort\"])\n",
+    "    vmIfaceAssertion = ForAll(\n",
+    "        [vm],\n",
+    "        Implies(\n",
+    "            ctx[\"elem_class_f\"](vm) == ctx[\"class_\"][\"infrastructure_VirtualMachine\"],\n",
+    "            Exists(\n",
+    "                [CpuCount],\n",
+    "                And(\n",
+    "                    ctx[\"attr_rel\"](vm, ctx[\"attr\"][\"infrastructure_ComputingNode::cpu_count\"], CpuCount)\n",
+    "                )\n",
+    "            )\n",
+    "        )\n",
+    "    )\n",
+    "    ctx[\"solver\"].assert_and_track(vmIfaceAssertion, \"vm_cpucount\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 45,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def req_every_iface_has_a_secgroup(ctx):\n",
+    "    sg, iface = Consts(\"sg iface\", ctx[\"elem_sort\"])\n",
+    "    vmIfaceSecGroupAssertion = ForAll(\n",
+    "        [sg],\n",
+    "        Implies(\n",
+    "            ctx[\"elem_class_f\"](sg) == ctx[\"class_\"][\"infrastructure_SecurityGroup\"],\n",
+    "            Exists([iface], \n",
+    "                ctx[\"assoc_rel\"](iface, ctx[\"assoc\"][\"infrastructure_NetworkInterface::associated\"], sg)\n",
+    "            )\n",
+    "        )\n",
+    "    )\n",
+    "    ctx[\"solver\"].assert_and_track(vmIfaceSecGroupAssertion, \"vm_secgroup\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 46,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def req_iface_uniq(ctx):\n",
+    "    endPointAttr = ctx[\"attr\"][\"infrastructure_NetworkInterface::endPoint\"]\n",
+    "    ni1, ni2 = Consts(\"ni1 ni2\", ctx[\"elem_sort\"])\n",
+    "    value = Const(\"value\", ctx[\"attr_data_sort\"])\n",
+    "    uniqueIfaceAssertion = And(\n",
+    "        ctx[\"attr_rel\"](ni1, endPointAttr, value),\n",
+    "        ctx[\"attr_rel\"](ni2, endPointAttr, value),\n",
+    "        ni1 != ni2,\n",
+    "    )\n",
+    "    ctx[\"solver\"].assert_and_track(uniqueIfaceAssertion, \"unique_iface\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 47,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def req_external_services_must_have_https(ctx):\n",
+    "    saas, sw_iface, sw_comp, deployment, ielem, net_iface, sec_group, rule = Consts(\"saas, sw_iface, sw_comp, deployment, ielem, net_iface, sec_group, rule\", ctx[\"elem_sort\"])\n",
+    "    assertion = ForAll(\n",
+    "        [saas, sec_group, sw_iface, sw_comp, deployment, ielem, net_iface],\n",
+    "        Implies(\n",
+    "            And(\n",
+    "                ctx[\"elem_class_f\"](saas) == ctx[\"class_\"][\"application_SaaS\"],\n",
+    "                ctx[\"elem_class_f\"](sec_group) == ctx[\"class_\"][\"infrastructure_SecurityGroup\"],\n",
+    "                ctx[\"assoc_rel\"](saas, ctx[\"assoc\"][\"application_SaaS::exposedInterfaces\"], sw_iface),\n",
+    "                ctx[\"assoc_rel\"](sw_comp, ctx[\"assoc\"][\"application_SoftwareComponent::consumedInterfaces\"], sw_iface),\n",
+    "                ctx[\"assoc_rel\"](deployment, ctx[\"assoc\"][\"commons_Deployment::component\"], sw_comp),\n",
+    "                ctx[\"assoc_rel\"](deployment, ctx[\"assoc\"][\"commons_Deployment::node\"], ielem),\n",
+    "                ctx[\"assoc_rel\"](ielem, ctx[\"assoc\"][\"infrastructure_ComputingNode::ifaces\"], net_iface),\n",
+    "                ctx[\"assoc_rel\"](net_iface, ctx[\"assoc\"][\"infrastructure_NetworkInterface::associated\"], sec_group),\n",
+    "                ctx[\"assoc_rel\"](sec_group, ctx[\"assoc\"][\"infrastructure_SecurityGroup::rules\"], rule),\n",
+    "            ),\n",
+    "            Exists([rule],\n",
+    "                And(\n",
+    "                    # Every node that contacts an external service should belong to a security group implementing HTTPS\n",
+    "                    ctx[\"attr_rel\"](rule, ctx[\"attr\"][\"infrastructure_Rule::fromPort\"], ctx[\"attr_data_sort\"].int(443)),\n",
+    "                    ctx[\"attr_rel\"](rule, ctx[\"attr\"][\"infrastructure_Rule::toPort\"], ctx[\"attr_data_sort\"].int(443)),\n",
+    "                    ctx[\"attr_rel\"](rule, ctx[\"attr\"][\"infrastructure_Rule::kind\"], ctx[\"attr_data_sort\"].str(ctx[\"str\"][\"INGRESS\"]))\n",
+    "                )\n",
+    "            )\n",
+    "        )\n",
+    "    )\n",
+    "    ctx[\"solver\"].assert_and_track(assertion, \"ext_service_https\")"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### REMEMBER TO ADD REQUIREMENTS TO THE LIST!"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 48,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "REQUIREMENTS = [\n",
+    "    req_every_vm_has_iface,\n",
+    "    # req_every_vm_has_cpucount\n",
+    "    # req_every_iface_has_a_secgroup,\n",
+    "    # req_iface_uniq,\n",
+    "    # req_external_services_must_have_https\n",
+    "]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 49,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def check_iteratively(ubelems_n: int = 0, ubvals_n: int = 0, requirements: list = [], curr_try: int = 0, max_tries: int = 10) -> Context:\n",
+    "    if curr_try > max_tries:\n",
+    "        raise RuntimeError(\"Max tries exceeded.\")\n",
+    "\n",
+    "    ctx = initialize_solver(ubelems_n, ubvals_n, requirements)\n",
+    "    solver = ctx[\"solver\"]\n",
+    "\n",
+    "    res = solver.check()\n",
+    "\n",
+    "    if res == sat:\n",
+    "        print(\"\\033[92m\" + f\"<Sat>\\tubelems_n={ubelems_n}, ubvals_n={ubvals_n}\" + \"\\033[0m\")\n",
+    "        return ctx\n",
+    "    elif res == unsat:\n",
+    "        print(\"\\033[91m\" + f\"<Unsat>\\tubelems_n={ubelems_n}, ubvals_n={ubvals_n}\" + \"\\033[0m\")\n",
+    "        if ubelems_n > ubvals_n:\n",
+    "            new_ubvals_n = ubvals_n * 2 if ubvals_n >= 1 else 1\n",
+    "            return check_iteratively(ubelems_n, new_ubvals_n, requirements, curr_try + 1, max_tries)\n",
+    "            # TODO: Choose which goes first\n",
+    "        elif ubelems_n <= ubvals_n:\n",
+    "            new_ubelems_n = ubelems_n * 2 if ubelems_n >= 1 else 1\n",
+    "            return check_iteratively(new_ubelems_n, ubvals_n, requirements, curr_try + 1, max_tries)\n",
+    "    else: # res == dontknow\n",
+    "        raise RuntimeError(\"It took too long to decide.\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 50,
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "\u001b[91m<Unsat>\tubelems_n=0, ubvals_n=0\u001b[0m\n",
+      "\u001b[92m<Sat>\tubelems_n=1, ubvals_n=0\u001b[0m\n"
+     ]
+    }
+   ],
+   "source": [
+    "solved_ctx = check_iteratively(0, 0, requirements=REQUIREMENTS)\n",
+    "\n",
+    "solved_model = solved_ctx[\"solver\"].model()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 51,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def get_ubelems_and_assoc(ctx: Context, model: Model):\n",
+    "    elem, assoc, assoc_rel, unbound_elems = itemgetter(\"elem\", \"assoc\", \"assoc_rel\", \"unbound_elems\")(ctx)\n",
+    "\n",
+    "    return [ ((e1n, e1), a, (e2n, e2)) \n",
+    "        for (e1n, e1), a, (e2n, e2) in product(elem.items(), assoc.values(), elem.items()) \n",
+    "        if (e1n in unbound_elems or e2n in unbound_elems) and model.eval(assoc_rel(e1, a, e2))\n",
+    "    ]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 52,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def get_ubvals_and_attr(ctx: Context, model: Model):\n",
+    "    elem, attr, attr_rel, unbound_values = itemgetter(\"elem\", \"attr\", \"attr_rel\", \"unbound_values\")(ctx)\n",
+    "\n",
+    "    return [ ((elem_k, elem_v), a, (ubval_k, ubval_v))\n",
+    "        for (elem_k, elem_v), a, (ubval_k, ubval_v) in product(elem.items(), attr.values(), unbound_values.items())\n",
+    "        if model.eval(attr_rel(elem_v, a, ubval_v))\n",
+    "    ]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 53,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Utility code to print the names of associations and attributes in a human-readable way\n",
+    "def pretty_ubelems_assoc(assoc):\n",
+    "    (elem_1_k, elem_1_v), a, (elem_2_k, elem_2_v) = assoc\n",
+    "    elem_1 = im.get(elem_1_k)\n",
+    "    if elem_1:\n",
+    "        elem_1_name = f\"{elem_1.class_} ({elem_1.user_friendly_name})\" if elem_1_k[0:4] == \"elem\" else f\"<'{elem_1_k}' not found>\"\n",
+    "    else:\n",
+    "        elem_1_name = elem_1_k\n",
+    "    \n",
+    "    elem_2 = im.get(elem_2_k)\n",
+    "    if elem_2:\n",
+    "        elem_2_name = f\"{elem_2.class_} ({elem_2.user_friendly_name})\" if elem_2_k[0:4] == \"elem\" else f\"<'{elem_2_k}' not found>\"\n",
+    "    else:\n",
+    "        elem_2_name = elem_2_k\n",
+    "    \n",
+    "    assoc_name = str(a)\n",
+    "\n",
+    "    return f\"{elem_1_name:<50s} {assoc_name:<60s} {elem_2_name:<30s}\"\n",
+    "\n",
+    "def pretty_ubvals_attrs(attrs):\n",
+    "    (elem_k, elem_v), a, (ubval_k, ubval_v) = attrs\n",
+    "\n",
+    "    elem_1 = im.get(elem_k)\n",
+    "    if elem_1:\n",
+    "        elem_1_name = f\"{elem_1.class_} ({elem_1.user_friendly_name})\" if elem_k[0:4] == \"elem\" else f\"<'{elem_k}' not found>\"\n",
+    "    else:\n",
+    "        elem_1_name = elem_k\n",
+    "\n",
+    "    attr_name = str(a)\n",
+    "\n",
+    "    val_name = str(ubval_k)\n",
+    "\n",
+    "    return f\"{elem_1_name:<50s} {attr_name:<60s} {val_name:<30s}\""
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 54,
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "infrastructure_VirtualMachine (vm1)                commons_Property::reference                                  unbound_elem_0                \n",
+      "infrastructure_VirtualMachine (vm1)                application_SoftwareComponent::exposedInterfaces             unbound_elem_0                \n",
+      "infrastructure_VirtualMachine (vm1)                application_SoftwareComponent::consumedInterfaces            unbound_elem_0                \n",
+      "infrastructure_VirtualMachine (vm1)                application_SaaS::exposedInterfaces                          unbound_elem_0                \n",
+      "infrastructure_VirtualMachine (vm1)                infrastructure_InfrastructureLayer::generators               unbound_elem_0                \n",
+      "infrastructure_VirtualMachine (vm1)                infrastructure_InfrastructureLayer::storages                 unbound_elem_0                \n",
+      "infrastructure_VirtualMachine (vm1)                infrastructure_InfrastructureLayer::faas                     unbound_elem_0                \n",
+      "infrastructure_VirtualMachine (vm1)                infrastructure_InfrastructureLayer::credentials              unbound_elem_0                \n",
+      "infrastructure_VirtualMachine (vm1)                infrastructure_InfrastructureLayer::groups                   unbound_elem_0                \n",
+      "infrastructure_VirtualMachine (vm1)                infrastructure_InfrastructureLayer::securityGroups           unbound_elem_0                \n",
+      "infrastructure_VirtualMachine (vm1)                infrastructure_InfrastructureLayer::networks                 unbound_elem_0                \n",
+      "infrastructure_VirtualMachine (vm1)                infrastructure_ComputingNode::ifaces                         unbound_elem_0                \n",
+      "infrastructure_VirtualMachine (vm1)                infrastructure_ComputingNode::location                       unbound_elem_0                \n",
+      "infrastructure_VirtualMachine (vm1)                infrastructure_ComputingNode::credentials                    unbound_elem_0                \n",
+      "infrastructure_VirtualMachine (vm1)                infrastructure_ComputingNode::group                          unbound_elem_0                \n",
+      "infrastructure_VirtualMachine (vm1)                infrastructure_VirtualMachine::generatedFrom                 unbound_elem_0                \n",
+      "infrastructure_VirtualMachine (vm1)                infrastructure_Container::generatedFrom                      unbound_elem_0                \n",
+      "infrastructure_VirtualMachine (vm1)                infrastructure_Container::hosts                              unbound_elem_0                \n",
+      "infrastructure_VirtualMachine (vm1)                infrastructure_VMImage::generatedVMs                         unbound_elem_0                \n",
+      "infrastructure_VirtualMachine (vm1)                infrastructure_ContainerImage::generatedContainers           unbound_elem_0                \n",
+      "infrastructure_VirtualMachine (vm1)                infrastructure_AutoScalingGroup::machineDefinition           unbound_elem_0                \n",
+      "infrastructure_VirtualMachine (vm1)                infrastructure_AutoScalingGroup::deploymentNetwork           unbound_elem_0                \n",
+      "infrastructure_VirtualMachine (vm1)                infrastructure_AutoScalingGroup::securityGroup               unbound_elem_0                \n",
+      "infrastructure_VirtualMachine (vm1)                infrastructure_Storage::ifaces                               unbound_elem_0                \n",
+      "infrastructure_VirtualMachine (vm1)                infrastructure_FunctionAsAService::ifaces                    unbound_elem_0                \n",
+      "infrastructure_VirtualMachine (vm1)                infrastructure_Network::connectedIfaces                      unbound_elem_0                \n",
+      "infrastructure_VirtualMachine (vm1)                infrastructure_Network::igws                                 unbound_elem_0                \n",
+      "infrastructure_VirtualMachine (vm1)                infrastructure_Network::subnets                              unbound_elem_0                \n",
+      "infrastructure_VirtualMachine (vm1)                infrastructure_Subnet::connectedTo                           unbound_elem_0                \n",
+      "infrastructure_VirtualMachine (vm1)                infrastructure_NetworkInterface::belongsTo                   unbound_elem_0                \n",
+      "infrastructure_VirtualMachine (vm1)                infrastructure_NetworkInterface::associated                  unbound_elem_0                \n",
+      "infrastructure_VirtualMachine (vm1)                infrastructure_ComputingGroup::groupedNodes                  unbound_elem_0                \n",
+      "infrastructure_VirtualMachine (vm1)                infrastructure_SecurityGroup::rules                          unbound_elem_0                \n",
+      "infrastructure_VirtualMachine (vm1)                infrastructure_SecurityGroup::ifaces                         unbound_elem_0                \n",
+      "infrastructure_VirtualMachine (vm1)                infrastructure_SwarmRole::nodes                              unbound_elem_0                \n",
+      "infrastructure_VirtualMachine (vm1)                infrastructure_Swarm::roles                                  unbound_elem_0                \n",
+      "infrastructure_VirtualMachine (vm1)                concrete_RuntimeProvider::vmImages                           unbound_elem_0                \n",
+      "infrastructure_VirtualMachine (vm1)                concrete_RuntimeProvider::containerImages                    unbound_elem_0                \n",
+      "infrastructure_VirtualMachine (vm1)                concrete_RuntimeProvider::networks                           unbound_elem_0                \n",
+      "infrastructure_VirtualMachine (vm1)                concrete_RuntimeProvider::storages                           unbound_elem_0                \n",
+      "infrastructure_VirtualMachine (vm1)                concrete_RuntimeProvider::faas                               unbound_elem_0                \n",
+      "infrastructure_VirtualMachine (vm1)                concrete_RuntimeProvider::group                              unbound_elem_0                \n",
+      "infrastructure_VirtualMachine (vm1)                concrete_VMImage::maps                                       unbound_elem_0                \n",
+      "infrastructure_VirtualMachine (vm1)                concrete_ContainerImage::maps                                unbound_elem_0                \n",
+      "infrastructure_VirtualMachine (vm1)                concrete_Network::maps                                       unbound_elem_0                \n",
+      "infrastructure_VirtualMachine (vm1)                concrete_Storage::maps                                       unbound_elem_0                \n",
+      "infrastructure_VirtualMachine (vm1)                concrete_FunctionAsAService::maps                            unbound_elem_0                \n",
+      "infrastructure_VirtualMachine (vm1)                concrete_ComputingGroup::maps                                unbound_elem_0                \n",
+      "------------------------------------------------------------------------------------------------------------------------\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "ubelems_and_assoc = get_ubelems_and_assoc(solved_ctx, solved_model)\n",
+    "print(\"\\n\".join([pretty_ubelems_assoc(assoc) for assoc in ubelems_and_assoc]))\n",
+    "\n",
+    "print(\"-\" * 120)\n",
+    "\n",
+    "ubvals_and_attr = get_ubvals_and_attr(solved_ctx, solved_model)\n",
+    "print(\"\\n\".join([pretty_ubvals_attrs(attr) for attr in ubvals_and_attr]))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 55,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "\tAdd constraint Not(infrastructure_VirtualMachine (vm1)                commons_Property::reference                                  unbound_elem_0                )\n",
+      "SAT:\tAdding one more constraint and trying again\n",
+      "*** Before\n",
+      "--- After\n",
+      "***************\n",
+      "*** 1,48 ****\n",
+      "- infrastructure_VirtualMachine (vm1)                commons_Property::reference                                  unbound_elem_0                \n",
+      "- infrastructure_VirtualMachine (vm1)                application_SoftwareComponent::exposedInterfaces             unbound_elem_0                \n",
+      "- infrastructure_VirtualMachine (vm1)                application_SoftwareComponent::consumedInterfaces            unbound_elem_0                \n",
+      "- infrastructure_VirtualMachine (vm1)                application_SaaS::exposedInterfaces                          unbound_elem_0                \n",
+      "- infrastructure_VirtualMachine (vm1)                infrastructure_InfrastructureLayer::generators               unbound_elem_0                \n",
+      "- infrastructure_VirtualMachine (vm1)                infrastructure_InfrastructureLayer::storages                 unbound_elem_0                \n",
+      "- infrastructure_VirtualMachine (vm1)                infrastructure_InfrastructureLayer::faas                     unbound_elem_0                \n",
+      "- infrastructure_VirtualMachine (vm1)                infrastructure_InfrastructureLayer::credentials              unbound_elem_0                \n",
+      "- infrastructure_VirtualMachine (vm1)                infrastructure_InfrastructureLayer::groups                   unbound_elem_0                \n",
+      "- infrastructure_VirtualMachine (vm1)                infrastructure_InfrastructureLayer::securityGroups           unbound_elem_0                \n",
+      "- infrastructure_VirtualMachine (vm1)                infrastructure_InfrastructureLayer::networks                 unbound_elem_0                \n",
+      "  infrastructure_VirtualMachine (vm1)                infrastructure_ComputingNode::ifaces                         unbound_elem_0                \n",
+      "- infrastructure_VirtualMachine (vm1)                infrastructure_ComputingNode::location                       unbound_elem_0                \n",
+      "- infrastructure_VirtualMachine (vm1)                infrastructure_ComputingNode::credentials                    unbound_elem_0                \n",
+      "- infrastructure_VirtualMachine (vm1)                infrastructure_ComputingNode::group                          unbound_elem_0                \n",
+      "- infrastructure_VirtualMachine (vm1)                infrastructure_VirtualMachine::generatedFrom                 unbound_elem_0                \n",
+      "- infrastructure_VirtualMachine (vm1)                infrastructure_Container::generatedFrom                      unbound_elem_0                \n",
+      "- infrastructure_VirtualMachine (vm1)                infrastructure_Container::hosts                              unbound_elem_0                \n",
+      "- infrastructure_VirtualMachine (vm1)                infrastructure_VMImage::generatedVMs                         unbound_elem_0                \n",
+      "- infrastructure_VirtualMachine (vm1)                infrastructure_ContainerImage::generatedContainers           unbound_elem_0                \n",
+      "- infrastructure_VirtualMachine (vm1)                infrastructure_AutoScalingGroup::machineDefinition           unbound_elem_0                \n",
+      "- infrastructure_VirtualMachine (vm1)                infrastructure_AutoScalingGroup::deploymentNetwork           unbound_elem_0                \n",
+      "- infrastructure_VirtualMachine (vm1)                infrastructure_AutoScalingGroup::securityGroup               unbound_elem_0                \n",
+      "- infrastructure_VirtualMachine (vm1)                infrastructure_Storage::ifaces                               unbound_elem_0                \n",
+      "- infrastructure_VirtualMachine (vm1)                infrastructure_FunctionAsAService::ifaces                    unbound_elem_0                \n",
+      "- infrastructure_VirtualMachine (vm1)                infrastructure_Network::connectedIfaces                      unbound_elem_0                \n",
+      "- infrastructure_VirtualMachine (vm1)                infrastructure_Network::igws                                 unbound_elem_0                \n",
+      "- infrastructure_VirtualMachine (vm1)                infrastructure_Network::subnets                              unbound_elem_0                \n",
+      "- infrastructure_VirtualMachine (vm1)                infrastructure_Subnet::connectedTo                           unbound_elem_0                \n",
+      "- infrastructure_VirtualMachine (vm1)                infrastructure_NetworkInterface::belongsTo                   unbound_elem_0                \n",
+      "- infrastructure_VirtualMachine (vm1)                infrastructure_NetworkInterface::associated                  unbound_elem_0                \n",
+      "- infrastructure_VirtualMachine (vm1)                infrastructure_ComputingGroup::groupedNodes                  unbound_elem_0                \n",
+      "- infrastructure_VirtualMachine (vm1)                infrastructure_SecurityGroup::rules                          unbound_elem_0                \n",
+      "- infrastructure_VirtualMachine (vm1)                infrastructure_SecurityGroup::ifaces                         unbound_elem_0                \n",
+      "- infrastructure_VirtualMachine (vm1)                infrastructure_SwarmRole::nodes                              unbound_elem_0                \n",
+      "- infrastructure_VirtualMachine (vm1)                infrastructure_Swarm::roles                                  unbound_elem_0                \n",
+      "- infrastructure_VirtualMachine (vm1)                concrete_RuntimeProvider::vmImages                           unbound_elem_0                \n",
+      "- infrastructure_VirtualMachine (vm1)                concrete_RuntimeProvider::containerImages                    unbound_elem_0                \n",
+      "- infrastructure_VirtualMachine (vm1)                concrete_RuntimeProvider::networks                           unbound_elem_0                \n",
+      "- infrastructure_VirtualMachine (vm1)                concrete_RuntimeProvider::storages                           unbound_elem_0                \n",
+      "- infrastructure_VirtualMachine (vm1)                concrete_RuntimeProvider::faas                               unbound_elem_0                \n",
+      "- infrastructure_VirtualMachine (vm1)                concrete_RuntimeProvider::group                              unbound_elem_0                \n",
+      "- infrastructure_VirtualMachine (vm1)                concrete_VMImage::maps                                       unbound_elem_0                \n",
+      "- infrastructure_VirtualMachine (vm1)                concrete_ContainerImage::maps                                unbound_elem_0                \n",
+      "- infrastructure_VirtualMachine (vm1)                concrete_Network::maps                                       unbound_elem_0                \n",
+      "- infrastructure_VirtualMachine (vm1)                concrete_Storage::maps                                       unbound_elem_0                \n",
+      "- infrastructure_VirtualMachine (vm1)                concrete_FunctionAsAService::maps                            unbound_elem_0                \n",
+      "- infrastructure_VirtualMachine (vm1)                concrete_ComputingGroup::maps                                unbound_elem_0                \n",
+      "--- 1 ----\n",
+      "\tAdd constraint Not(infrastructure_VirtualMachine (vm1)                infrastructure_ComputingNode::ifaces                         unbound_elem_0                )\n",
+      "UNSAT\tLast constraint was the association we are looking for!\n"
+     ]
+    }
+   ],
+   "source": [
+    "def thin_ubelems_and_assoc(ctx: Context, ubelems_and_assoc: list):\n",
+    "    if not ubelems_and_assoc:\n",
+    "        return []\n",
+    "\n",
+    "    (_, elem_1_v), a, (_, elem_2_v) = assoc = ubelems_and_assoc[0]\n",
+    "    assoc_rel = ctx[\"assoc_rel\"](elem_1_v, a, elem_2_v)\n",
+    "\n",
+    "    # Add negated constraint\n",
+    "    ctx[\"solver\"].push()\n",
+    "    print(f\"\\tAdd constraint Not({pretty_ubelems_assoc(assoc)})\")\n",
+    "    ctx[\"solver\"].add(Not(assoc_rel))\n",
+    "    \n",
+    "    res = ctx[\"solver\"].check()\n",
+    "    \n",
+    "    if res == sat:\n",
+    "        print(\"SAT:\\tAdding one more constraint and trying again\")\n",
+    "        # Get new ubelems_and_assoc\n",
+    "        model = ctx[\"solver\"].model()\n",
+    "        thinned_ubelems_and_assoc = get_ubelems_and_assoc(ctx, model)\n",
+    "        \n",
+    "        # Print table showing the diff\n",
+    "        from difflib import context_diff\n",
+    "        uvar_as_text = lambda input: [pretty_ubelems_assoc(assoc) for assoc in input]\n",
+    "        print(\"\\n\".join([a for a in context_diff(uvar_as_text(ubelems_and_assoc), uvar_as_text(thinned_ubelems_and_assoc), lineterm=\"\", fromfile='Before', tofile=\"After\")]))\n",
+    "\n",
+    "        # Iterate\n",
+    "        return thin_ubelems_and_assoc(ctx, thinned_ubelems_and_assoc)\n",
+    "    else:\n",
+    "        print(\"UNSAT\\tLast constraint was the association we are looking for!\")\n",
+    "        ctx[\"solver\"].pop()\n",
+    "        \n",
+    "        if ubelems_and_assoc[1:]:\n",
+    "            print(\"\\tIterating over\")\n",
+    "            print(\"\\t\\t\" + \"\\n\\t\\t\".join([pretty_ubelems_assoc(assoc) for assoc in ubelems_and_assoc[1:]]))\n",
+    "        return [*set([assoc] + thin_ubelems_and_assoc(ctx, ubelems_and_assoc[1:]))]\n",
+    "\n",
+    "\n",
+    "assoc_to_implement = thin_ubelems_and_assoc(solved_ctx, ubelems_and_assoc)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 56,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "infrastructure_VirtualMachine (vm1)                infrastructure_ComputingNode::ifaces                         unbound_elem_0                \n"
+     ]
+    }
+   ],
+   "source": [
+    "print(\"\\n\".join([pretty_ubelems_assoc(assoc) for assoc in assoc_to_implement]))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 57,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def thin_ubvals_and_attr(ctx: Context, ubvals_and_attr: list):\n",
+    "    if not ubvals_and_attr:\n",
+    "        return []\n",
+    "\n",
+    "    (_, elem_v), a, (_, attr_v) = attr = ubvals_and_attr[0]\n",
+    "    attr_rel = ctx[\"attr_rel\"](elem_v, a, attr_v)\n",
+    "\n",
+    "    # Add negated constraint\n",
+    "    ctx[\"solver\"].push()\n",
+    "    print(f\"\\tAdd constraint Not({pretty_ubvals_attrs(attr)})\")\n",
+    "    ctx[\"solver\"].add(Not(attr_rel))\n",
+    "    \n",
+    "    res = ctx[\"solver\"].check()\n",
+    "    \n",
+    "    if res == sat:\n",
+    "        print(\"SAT:\\tAdding one more constraint and trying again\")\n",
+    "        # Get new ubelems_and_assoc\n",
+    "        model = ctx[\"solver\"].model()\n",
+    "        thinned_ubvals_and_attr = get_ubvals_and_attr(ctx, model)\n",
+    "        \n",
+    "        # Print table showing the diff\n",
+    "        from difflib import context_diff\n",
+    "        uvar_as_text = lambda input: [pretty_ubvals_attrs(attr) for attr in input]\n",
+    "        print(\"\\n\".join([a for a in context_diff(uvar_as_text(ubelems_and_assoc), uvar_as_text(thinned_ubvals_and_attr), lineterm=\"\", fromfile='Before', tofile=\"After\")]))\n",
+    "\n",
+    "        # Iterate\n",
+    "        return thin_ubvals_and_attr(ctx, thinned_ubvals_and_attr)\n",
+    "    else:\n",
+    "        print(\"UNSAT\\tLast constraint was the attribute we are looking for!\")\n",
+    "        ctx[\"solver\"].pop()\n",
+    "        \n",
+    "        if ubvals_and_attr[1:]:\n",
+    "            print(\"\\tIterating over\")\n",
+    "            print(\"\\t\\t\" + \"\\n\\t\\t\".join([pretty_ubvals_attrs(attr) for attr in ubvals_and_attr[1:]]))\n",
+    "        return [*set([attr] + thin_ubvals_and_attr(ctx, ubvals_and_attr[1:]))]\n",
+    "\n",
+    "\n",
+    "attrs_to_implement = thin_ubvals_and_attr(solved_ctx, ubvals_and_attr)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 58,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(\"\\n\".join([pretty_ubvals_attrs(attr) for attr in attrs_to_implement]))"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "From here, we should then add this in the Intermediate Model, and then in the ECore (?) to generate the DOML file somehow.\n",
+    "\n",
+    "We can then provide the new file, or a diff to be patched onto the original?"
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3.10.7 ('.venv': poetry)",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.11.0"
+  },
+  "orig_nbformat": 4,
+  "vscode": {
+   "interpreter": {
+    "hash": "d98256633358fe1daa4009223d54520a3e2548801398a173545d5698bb289e16"
+   }
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/mc_openapi/notebooks/net_diagram.ipynb b/mc_openapi/notebooks/net_diagram.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..3f4ba4c94b2f72020349941dcaf747a0a703202c
--- /dev/null
+++ b/mc_openapi/notebooks/net_diagram.ipynb
@@ -0,0 +1,239 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "/home/andrea/Projects/piacere-model-checker\n"
+     ]
+    }
+   ],
+   "source": [
+    "%cd ../.."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Collecting diagrams\n",
+      "  Downloading diagrams-0.23.3-py3-none-any.whl (24.4 MB)\n",
+      "\u001b[2K     \u001b[38;2;114;156;31m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m24.4/24.4 MB\u001b[0m \u001b[31m14.1 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0mm eta \u001b[36m0:00:01\u001b[0m[36m0:00:01\u001b[0m\n",
+      "\u001b[?25hCollecting graphviz<0.21.0,>=0.13.2 (from diagrams)\n",
+      "  Downloading graphviz-0.20.1-py3-none-any.whl (47 kB)\n",
+      "\u001b[2K     \u001b[38;2;114;156;31m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m47.0/47.0 kB\u001b[0m \u001b[31m16.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
+      "\u001b[?25hRequirement already satisfied: jinja2<4.0,>=2.10 in ./.venv/lib64/python3.11/site-packages (from diagrams) (3.1.2)\n",
+      "Collecting typed-ast<2.0.0,>=1.5.4 (from diagrams)\n",
+      "  Downloading typed_ast-1.5.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (860 kB)\n",
+      "\u001b[2K     \u001b[38;2;114;156;31m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m860.3/860.3 kB\u001b[0m \u001b[31m14.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m31m15.1 MB/s\u001b[0m eta \u001b[36m0:00:01\u001b[0m\n",
+      "\u001b[?25hRequirement already satisfied: MarkupSafe>=2.0 in ./.venv/lib64/python3.11/site-packages (from jinja2<4.0,>=2.10->diagrams) (2.1.2)\n",
+      "Installing collected packages: typed-ast, graphviz, diagrams\n",
+      "Successfully installed diagrams-0.23.3 graphviz-0.20.1 typed-ast-1.5.5\n",
+      "\n",
+      "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip is available: \u001b[0m\u001b[31;49m23.1.2\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m23.2.1\u001b[0m\n",
+      "\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\n",
+      "Note: you may need to restart the kernel to use updated packages.\n"
+     ]
+    }
+   ],
+   "source": [
+    "%pip install diagrams"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 98,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# XMI_PATH = \"./tests/doml/CaseStudies/posidonia.domlx\"\n",
+    "XMI_PATH = \"./tests/doml/CaseStudies/nio3_test_exec_env.domlx\"\n",
+    "\n",
+    "with open(XMI_PATH, 'rb') as f:\n",
+    "    doml_xmi = f.read()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 99,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "[]"
+      ]
+     },
+     "execution_count": 99,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "from mc_openapi.doml_mc.intermediate_model.metamodel import DOMLVersion\n",
+    "from mc_openapi.doml_mc.main import init_model\n",
+    "\n",
+    "dmc = init_model(doml_xmi, doml_ver=None)\n",
+    "\n",
+    "[x for x in dmc.intermediate_model.values() if x.user_friendly_name and x.user_friendly_name.startswith(\"co1\")]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 104,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from diagrams import Diagram, Cluster, Node, Edge\n",
+    "from diagrams.aws.compute import EC2, ECS, AutoScaling, AMI, Compute, EC2Instance, AppRunner\n",
+    "from diagrams.aws.network import CloudFront, APIGateway, TransitGateway\n",
+    "from diagrams.aws.storage import S3\n",
+    "from diagrams.aws.security import Shield, IAMPermissions, IdentityAndAccessManagementIamAddOn as KeyPair\n",
+    "from diagrams.aws.general import General\n",
+    "from diagrams.aws.database import DB\n",
+    "from diagrams.aws.mobile import APIGateway\n",
+    "\n",
+    "from mc_openapi.doml_mc.intermediate_model.doml_element import DOMLElement\n",
+    "\n",
+    "elems = [elem for elem in dmc.intermediate_model.values()]\n",
+    "\n",
+    "common_elems = [e for e in elems if e.class_.startswith(\"commons_\") if e.class_ not in [\"commons_Deployment\", \"commons_Configuration\", \"commons_SProperty\", \"commons_FProperty\", \"commons_BProperty\"]] \n",
+    "deployments = [e for e in elems if e.class_ == \"commons_Deployment\"] \n",
+    "app_elems = [e for e in elems if e.class_.startswith(\"application_\") and e.class_ != \"application_ApplicationLayer\"] \n",
+    "infr_elems = [e for e in elems if e.class_.startswith(\"infrastructure_\") and e.class_ != \"infrastructure_InfrastructureLayer\"] \n",
+    "concr_elems = [e for e in elems if e.class_.startswith(\"concrete_\") and e.class_ != \"concrete_ConcreteInfrastructure\"] \n",
+    "\n",
+    "group_elems = {\"Application\": app_elems, \"Infrastructure\": infr_elems, \"Concretization\": concr_elems}\n",
+    "\n",
+    "def prettify_class_name(name: str):\n",
+    "    _, name = name.split('_', 1)\n",
+    "    return name\n",
+    "\n",
+    "def prettify_assoc_name(assoc: str):\n",
+    "    _, assoc = assoc.split('::', 1)\n",
+    "    return assoc\n",
+    "\n",
+    "def get_component(elem: DOMLElement):\n",
+    "    \n",
+    "    class_name = prettify_class_name(elem.class_)\n",
+    "\n",
+    "    name = f\"{elem.user_friendly_name or ''}\\n({class_name})\"\n",
+    "\n",
+    "    match class_name:\n",
+    "        case \"SoftwareComponent\":\n",
+    "            return Compute(name)\n",
+    "        case \"SoftwareInterface\":\n",
+    "            return APIGateway(name)\n",
+    "        case \"DBMS\":\n",
+    "            return DB(name)\n",
+    "        case \"Network\":\n",
+    "            if address := elem.attributes.get('infrastructure_Network::cidr'):\n",
+    "                name += f'\\nCIDR: {address[0]}'\n",
+    "            return CloudFront(name)\n",
+    "        case \"Subnet\":\n",
+    "            if address := elem.attributes.get('infrastructure_Network::cidr'):\n",
+    "                name += f'\\nCIDR: {address[0]}'\n",
+    "            return CloudFront(name)\n",
+    "        case \"InternetGateway\":\n",
+    "            if address := elem.attributes.get('infrastructure_InternetGateway::address'):\n",
+    "                name += f'\\nIP: {address[0]}'\n",
+    "            return TransitGateway(name)\n",
+    "        case \"NetworkInterface\":\n",
+    "            if address := elem.attributes.get('infrastructure_NetworkInterface::endPoint'):\n",
+    "                name += f'\\nIP: {address[0]}'\n",
+    "            return APIGateway(name)\n",
+    "        case \"Storage\":\n",
+    "            return S3(name)\n",
+    "        case \"VirtualMachine\":\n",
+    "            return EC2(name)\n",
+    "        case \"Container\":\n",
+    "            return ECS(name)\n",
+    "        case \"VMImage\":\n",
+    "            return AMI(name)\n",
+    "        case \"AutoScalingGroup\":\n",
+    "            return AutoScaling(name)\n",
+    "        case \"ComputingGroup\":\n",
+    "            return EC2Instance(name)\n",
+    "        case \"RuntimeProvider\":\n",
+    "            return AppRunner(name)\n",
+    "        case \"KeyPair\":\n",
+    "            return KeyPair(name)\n",
+    "        case \"UserPass\":\n",
+    "            return KeyPair(name)\n",
+    "        case \"SecurityGroup\":\n",
+    "            return Shield(name)\n",
+    "        case \"Rule\":\n",
+    "            return IAMPermissions(name)\n",
+    "        case _:\n",
+    "            return General(name)\n",
+    "        \n",
+    "graph_attr = {\n",
+    "    \"pad\": \"1pt\"\n",
+    "}\n",
+    "\n",
+    "HIGHLIGHT_CONNECTIONS = [\n",
+    "    'infrastructure_NetworkInterface::belongsTo'\n",
+    "]\n",
+    "\n",
+    "with Diagram(\"DOML Model\", show=True, outformat=\"svg\", direction=\"TB\", graph_attr=graph_attr) as diagram:\n",
+    "    cached_nodes: dict[str, Node] = {}\n",
+    "    for gk, gv in group_elems.items():\n",
+    "        with Cluster(gk):\n",
+    "            cached_nodes |= {e.id_: get_component(e) for e in gv}\n",
+    "    \n",
+    "    # Dont group common elements\n",
+    "    cached_nodes |= {e.id_: get_component(e) for e in common_elems}\n",
+    "\n",
+    "    for groups in group_elems.values():\n",
+    "        for elem in groups:\n",
+    "            for assoc_k, assocs_v in elem.associations.items():\n",
+    "                for assoc in assocs_v:\n",
+    "                    if (start := cached_nodes.get(elem.id_)) and (end := cached_nodes.get(assoc)):\n",
+    "                        if assoc_k in HIGHLIGHT_CONNECTIONS:\n",
+    "                                start >> Edge(label=prettify_assoc_name(assoc_k), color='green', style=\"bold\") >> end\n",
+    "                        elif 'maps' in assoc_k:\n",
+    "                            start >> Edge(label=prettify_assoc_name(assoc_k), style=\"bold\") >> end\n",
+    "                        else:\n",
+    "                            start >> end\n",
+    "\n",
+    "    for dep in deployments:\n",
+    "        for _component in dep.associations.get('commons_Deployment::component'):\n",
+    "            for _node in dep.associations.get('commons_Deployment::node'):\n",
+    "                 if (start := cached_nodes.get(_component)) and (end := cached_nodes.get(_node)):\n",
+    "                        start >> Edge(style=\"bold\") >> end\n"
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": ".venv",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.11.4"
+  },
+  "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/mc_openapi/notebooks/net_validation.ipynb b/mc_openapi/notebooks/net_validation.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..7e432991179e0387f072f7ae99e568493c701e39
--- /dev/null
+++ b/mc_openapi/notebooks/net_validation.ipynb
@@ -0,0 +1,201 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "/home/andrea/Projects/piacere-model-checker\n"
+     ]
+    }
+   ],
+   "source": [
+    "%cd ../.."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# XMI_PATH = \"./tests/doml/CaseStudies/posidonia.domlx\"\n",
+    "# XMI_PATH = \"../piacere-workspace/Playground/NetValidation/test1.domlx\" # Subnets, Ifaces, Gateway\n",
+    "# XMI_PATH = \"./tests/doml/CaseStudies/posidonia_IOP.domlx\" # Subnets, no Gateway\n",
+    "# XMI_PATH = \"../piacere-workspace/Playground/CaseStudies/nio3_test_exec_env.domlx\" # No subnets, Gateway\n",
+    "# XMI_PATH = \"../piacere-workspace/Playground/CaseStudies/posidonia.domlx\"\n",
+    "XMI_PATH = \"../piacere-workspace/Playground/3.1/Ericsson_DOML.domlx\"\n",
+    "\n",
+    "with open(XMI_PATH, 'rb') as f:\n",
+    "    doml_xmi = f.read()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from mc_openapi.doml_mc.main import init_model\n",
+    "\n",
+    "dmc = init_model(doml_xmi, doml_ver=None)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "ename": "AddressValueError",
+     "evalue": "Expected 4 octets in 'None'",
+     "output_type": "error",
+     "traceback": [
+      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
+      "\u001b[0;31mAddressValueError\u001b[0m                         Traceback (most recent call last)",
+      "\u001b[1;32m/home/andrea/Projects/piacere-model-checker/mc_openapi/notebooks/net_validation.ipynb Cell 4\u001b[0m line \u001b[0;36m1\n\u001b[1;32m    <a href='vscode-notebook-cell:/home/andrea/Projects/piacere-model-checker/mc_openapi/notebooks/net_validation.ipynb#W3sZmlsZQ%3D%3D?line=99'>100</a>\u001b[0m         \u001b[39mfor\u001b[39;00m (obj, addr) \u001b[39min\u001b[39;00m addresses:\n\u001b[1;32m    <a href='vscode-notebook-cell:/home/andrea/Projects/piacere-model-checker/mc_openapi/notebooks/net_validation.ipynb#W3sZmlsZQ%3D%3D?line=100'>101</a>\u001b[0m             \u001b[39mprint\u001b[39m(\u001b[39mf\u001b[39m\u001b[39m\"\u001b[39m\u001b[39mNetworkInterface \u001b[39m\u001b[39m'\u001b[39m\u001b[39m{\u001b[39;00mobj\u001b[39m.\u001b[39muser_friendly_name\u001b[39m}\u001b[39;00m\u001b[39m'\u001b[39m\u001b[39m (\u001b[39m\u001b[39m{\u001b[39;00maddr\u001b[39m}\u001b[39;00m\u001b[39m) belong to net \u001b[39m\u001b[39m'\u001b[39m\u001b[39m{\u001b[39;00mnetwork\u001b[39m.\u001b[39muser_friendly_name\u001b[39m}\u001b[39;00m\u001b[39m'\u001b[39m\u001b[39m (\u001b[39m\u001b[39m{\u001b[39;00mnet_addr\u001b[39m}\u001b[39;00m\u001b[39m)? \u001b[39m\u001b[39m{\u001b[39;00maddr\u001b[39m \u001b[39m\u001b[39min\u001b[39;00m\u001b[39m \u001b[39mnet\u001b[39m.\u001b[39mhosts()\u001b[39m}\u001b[39;00m\u001b[39m\"\u001b[39m)\n\u001b[0;32m--> <a href='vscode-notebook-cell:/home/andrea/Projects/piacere-model-checker/mc_openapi/notebooks/net_validation.ipynb#W3sZmlsZQ%3D%3D?line=104'>105</a>\u001b[0m validate_network_address(dmc)\n",
+      "\u001b[1;32m/home/andrea/Projects/piacere-model-checker/mc_openapi/notebooks/net_validation.ipynb Cell 4\u001b[0m line \u001b[0;36m6\n\u001b[1;32m     <a href='vscode-notebook-cell:/home/andrea/Projects/piacere-model-checker/mc_openapi/notebooks/net_validation.ipynb#W3sZmlsZQ%3D%3D?line=56'>57</a>\u001b[0m addresses: \u001b[39mlist\u001b[39m[\u001b[39mtuple\u001b[39m[DOMLElement, IPv4Address]] \u001b[39m=\u001b[39m []\n\u001b[1;32m     <a href='vscode-notebook-cell:/home/andrea/Projects/piacere-model-checker/mc_openapi/notebooks/net_validation.ipynb#W3sZmlsZQ%3D%3D?line=58'>59</a>\u001b[0m \u001b[39m# Add subnets (Networks)\u001b[39;00m\n\u001b[0;32m---> <a href='vscode-notebook-cell:/home/andrea/Projects/piacere-model-checker/mc_openapi/notebooks/net_validation.ipynb#W3sZmlsZQ%3D%3D?line=59'>60</a>\u001b[0m visit_subnet(network, subnets)\n\u001b[1;32m     <a href='vscode-notebook-cell:/home/andrea/Projects/piacere-model-checker/mc_openapi/notebooks/net_validation.ipynb#W3sZmlsZQ%3D%3D?line=61'>62</a>\u001b[0m \u001b[39m# pprint(\"SUBNETS:\")\u001b[39;00m\n\u001b[1;32m     <a href='vscode-notebook-cell:/home/andrea/Projects/piacere-model-checker/mc_openapi/notebooks/net_validation.ipynb#W3sZmlsZQ%3D%3D?line=62'>63</a>\u001b[0m \u001b[39m# pprint(subnets)\u001b[39;00m\n\u001b[1;32m     <a href='vscode-notebook-cell:/home/andrea/Projects/piacere-model-checker/mc_openapi/notebooks/net_validation.ipynb#W3sZmlsZQ%3D%3D?line=63'>64</a>\u001b[0m \n\u001b[1;32m     <a href='vscode-notebook-cell:/home/andrea/Projects/piacere-model-checker/mc_openapi/notebooks/net_validation.ipynb#W3sZmlsZQ%3D%3D?line=64'>65</a>\u001b[0m \u001b[39m# Add addresses (gateways, ifaces)\u001b[39;00m\n\u001b[1;32m     <a href='vscode-notebook-cell:/home/andrea/Projects/piacere-model-checker/mc_openapi/notebooks/net_validation.ipynb#W3sZmlsZQ%3D%3D?line=65'>66</a>\u001b[0m \u001b[39mfor\u001b[39;00m gateway \u001b[39min\u001b[39;00m get_assocs(network, ASSOC_GATEWAYS):\n",
+      "\u001b[1;32m/home/andrea/Projects/piacere-model-checker/mc_openapi/notebooks/net_validation.ipynb Cell 4\u001b[0m line \u001b[0;36m4\n\u001b[1;32m     <a href='vscode-notebook-cell:/home/andrea/Projects/piacere-model-checker/mc_openapi/notebooks/net_validation.ipynb#W3sZmlsZQ%3D%3D?line=40'>41</a>\u001b[0m subnet \u001b[39m=\u001b[39m im[subnet]\n\u001b[1;32m     <a href='vscode-notebook-cell:/home/andrea/Projects/piacere-model-checker/mc_openapi/notebooks/net_validation.ipynb#W3sZmlsZQ%3D%3D?line=41'>42</a>\u001b[0m subnet_addr \u001b[39m=\u001b[39m fix_invalid_address( get_attr(subnet, ATTR_NET_ADDRESS) )\n\u001b[0;32m---> <a href='vscode-notebook-cell:/home/andrea/Projects/piacere-model-checker/mc_openapi/notebooks/net_validation.ipynb#W3sZmlsZQ%3D%3D?line=42'>43</a>\u001b[0m acc\u001b[39m.\u001b[39mappend((subnet, IPv4Network(subnet_addr)))\n\u001b[1;32m     <a href='vscode-notebook-cell:/home/andrea/Projects/piacere-model-checker/mc_openapi/notebooks/net_validation.ipynb#W3sZmlsZQ%3D%3D?line=43'>44</a>\u001b[0m visit_subnet(subnet, acc)\n",
+      "File \u001b[0;32m/usr/lib64/python3.11/ipaddress.py:1512\u001b[0m, in \u001b[0;36mIPv4Network.__init__\u001b[0;34m(self, address, strict)\u001b[0m\n\u001b[1;32m   1476\u001b[0m \u001b[39m\u001b[39m\u001b[39m\"\"\"Instantiate a new IPv4 network object.\u001b[39;00m\n\u001b[1;32m   1477\u001b[0m \n\u001b[1;32m   1478\u001b[0m \u001b[39mArgs:\u001b[39;00m\n\u001b[0;32m   (...)\u001b[0m\n\u001b[1;32m   1508\u001b[0m \u001b[39m      supplied.\u001b[39;00m\n\u001b[1;32m   1509\u001b[0m \u001b[39m\"\"\"\u001b[39;00m\n\u001b[1;32m   1510\u001b[0m addr, mask \u001b[39m=\u001b[39m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_split_addr_prefix(address)\n\u001b[0;32m-> 1512\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mnetwork_address \u001b[39m=\u001b[39m IPv4Address(addr)\n\u001b[1;32m   1513\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mnetmask, \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_prefixlen \u001b[39m=\u001b[39m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_make_netmask(mask)\n\u001b[1;32m   1514\u001b[0m packed \u001b[39m=\u001b[39m \u001b[39mint\u001b[39m(\u001b[39mself\u001b[39m\u001b[39m.\u001b[39mnetwork_address)\n",
+      "File \u001b[0;32m/usr/lib64/python3.11/ipaddress.py:1315\u001b[0m, in \u001b[0;36mIPv4Address.__init__\u001b[0;34m(self, address)\u001b[0m\n\u001b[1;32m   1313\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39m'\u001b[39m\u001b[39m/\u001b[39m\u001b[39m'\u001b[39m \u001b[39min\u001b[39;00m addr_str:\n\u001b[1;32m   1314\u001b[0m     \u001b[39mraise\u001b[39;00m AddressValueError(\u001b[39mf\u001b[39m\u001b[39m\"\u001b[39m\u001b[39mUnexpected \u001b[39m\u001b[39m'\u001b[39m\u001b[39m/\u001b[39m\u001b[39m'\u001b[39m\u001b[39m in \u001b[39m\u001b[39m{\u001b[39;00maddress\u001b[39m!r}\u001b[39;00m\u001b[39m\"\u001b[39m)\n\u001b[0;32m-> 1315\u001b[0m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_ip \u001b[39m=\u001b[39m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49m_ip_int_from_string(addr_str)\n",
+      "File \u001b[0;32m/usr/lib64/python3.11/ipaddress.py:1202\u001b[0m, in \u001b[0;36m_BaseV4._ip_int_from_string\u001b[0;34m(cls, ip_str)\u001b[0m\n\u001b[1;32m   1200\u001b[0m octets \u001b[39m=\u001b[39m ip_str\u001b[39m.\u001b[39msplit(\u001b[39m'\u001b[39m\u001b[39m.\u001b[39m\u001b[39m'\u001b[39m)\n\u001b[1;32m   1201\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mlen\u001b[39m(octets) \u001b[39m!=\u001b[39m \u001b[39m4\u001b[39m:\n\u001b[0;32m-> 1202\u001b[0m     \u001b[39mraise\u001b[39;00m AddressValueError(\u001b[39m\"\u001b[39m\u001b[39mExpected 4 octets in \u001b[39m\u001b[39m%r\u001b[39;00m\u001b[39m\"\u001b[39m \u001b[39m%\u001b[39m ip_str)\n\u001b[1;32m   1204\u001b[0m \u001b[39mtry\u001b[39;00m:\n\u001b[1;32m   1205\u001b[0m     \u001b[39mreturn\u001b[39;00m \u001b[39mint\u001b[39m\u001b[39m.\u001b[39mfrom_bytes(\u001b[39mmap\u001b[39m(\u001b[39mcls\u001b[39m\u001b[39m.\u001b[39m_parse_octet, octets), \u001b[39m'\u001b[39m\u001b[39mbig\u001b[39m\u001b[39m'\u001b[39m)\n",
+      "\u001b[0;31mAddressValueError\u001b[0m: Expected 4 octets in 'None'"
+     ]
+    }
+   ],
+   "source": [
+    "from pprint import pprint\n",
+    "from mc_openapi.doml_mc.intermediate_model import DOMLElement\n",
+    "from mc_openapi.doml_mc.mc import ModelChecker\n",
+    "\n",
+    "from ipaddress import IPv4Address, IPv4Network\n",
+    "\n",
+    "BASE_ADDR = '0.0.0.0'\n",
+    "\n",
+    "ASSOC_SUBNETS = 'infrastructure_Network::subnets'\n",
+    "ASSOC_GATEWAYS = 'infrastructure_Network::gateways'\n",
+    "ASSOC_IFACE_NET = 'infrastructure_NetworkInterface::belongsTo'\n",
+    "\n",
+    "ATTR_NET_ADDRESS = 'infrastructure_Network::cidr' # not here anymore\n",
+    "ATTR_GATEWAY_ADDRESS = 'infrastructure_InternetGateway::address'\n",
+    "ATTR_IFACE_ADDRESS = 'infrastructure_NetworkInterface::endPoint'\n",
+    "\n",
+    "def get_attr(elem: DOMLElement, attr_id: str):\n",
+    "    if elem := elem.attributes.get(attr_id):\n",
+    "        return elem[0]\n",
+    "    return None\n",
+    "    \n",
+    "def get_assocs(elem: DOMLElement, assoc_id: str):\n",
+    "    return elem.associations.get(assoc_id, [])\n",
+    "\n",
+    "def validate_network_address(dmc: ModelChecker):\n",
+    "    im = dmc.intermediate_model\n",
+    "\n",
+    "    networks = [e for e in im.values() if e.class_ == 'infrastructure_Network']\n",
+    "    ifaces = [e for e in im.values() if e.class_ == 'infrastructure_NetworkInterface']\n",
+    "    subnets = [e for e in im.values() if e.class_ == 'infrastructure_Subnet']\n",
+    "\n",
+    "# Network/24\n",
+    "#   Subnet/28\n",
+    "#   Subnet/30\n",
+    "#   Address\n",
+    "#   Address\n",
+    "\n",
+    "    def visit_subnet(net: DOMLElement, acc: list):\n",
+    "        \"\"\"Recursively navigate subnets to populate the `acc` list with all the subnet in a network.\"\"\"\n",
+    "        for subnet in get_assocs(net, ASSOC_SUBNETS):\n",
+    "            subnet = im[subnet]\n",
+    "            subnet_addr = fix_invalid_address( get_attr(subnet, ATTR_NET_ADDRESS) )\n",
+    "            acc.append((subnet, IPv4Network(subnet_addr)))\n",
+    "            visit_subnet(subnet, acc)\n",
+    "\n",
+    "    def fix_invalid_address(address: any):\n",
+    "        if isinstance(address, str) and address.startswith('/'):\n",
+    "            return f\"{BASE_ADDR}{address}\"\n",
+    "\n",
+    "        return address\n",
+    "\n",
+    "\n",
+    "    for network in networks:\n",
+    "        # Tuple(elem, cidr)\n",
+    "        subnets: list[tuple[DOMLElement, IPv4Network]] = []\n",
+    "        # Tuple(elem, address)\n",
+    "        addresses: list[tuple[DOMLElement, IPv4Address]] = []\n",
+    "\n",
+    "        # Add subnets (Networks)\n",
+    "        visit_subnet(network, subnets)\n",
+    "\n",
+    "        # pprint(\"SUBNETS:\")\n",
+    "        # pprint(subnets)\n",
+    "\n",
+    "        # Add addresses (gateways, ifaces)\n",
+    "        for gateway in get_assocs(network, ASSOC_GATEWAYS):\n",
+    "            gateway = im[gateway]\n",
+    "            if gateway_address := get_attr(gateway, ATTR_GATEWAY_ADDRESS):\n",
+    "                addresses.append((gateway, IPv4Address(gateway_address)))\n",
+    "\n",
+    "        for iface in ifaces:\n",
+    "            if owner_id := get_assocs(iface, ASSOC_IFACE_NET):\n",
+    "                owner = im[list(owner_id)[0]]\n",
+    "                if owner.id_ in [s.id_ for (s, _) in subnets] + [network.id_]:\n",
+    "                    if ((iface_address := get_attr(iface, ATTR_IFACE_ADDRESS))\n",
+    "                    and (owner_address := get_attr(owner, ATTR_NET_ADDRESS))):\n",
+    "                        owner_address = fix_invalid_address(owner_address)\n",
+    "                        iface_address = IPv4Address(iface_address)\n",
+    "                        owner_address = IPv4Network(owner_address)\n",
+    "                        print(f\"{iface.user_friendly_name} ({iface_address}) belongs to {owner.user_friendly_name} ({owner_address})? {iface_address in owner_address.hosts()}\")\n",
+    "\n",
+    "                        addresses.append((iface, iface_address))\n",
+    "                else:\n",
+    "                    print(f\"NetworkInterface '{iface.user_friendly_name}' does not belong to net '{owner.user_friendly_name}'.\")\n",
+    "\n",
+    "        # Validate Network and Subnets\n",
+    "        net_addr = fix_invalid_address( get_attr(network, ATTR_NET_ADDRESS) )\n",
+    "        # prepend 0.0.0.0 if starts with / i guess, print a warning\n",
+    "        print(f\"{net_addr}\\t{network.user_friendly_name}\")\n",
+    "\n",
+    "        net = IPv4Network(net_addr)\n",
+    "\n",
+    "        if len(subnets) > 0:\n",
+    "            for (obj, sn) in subnets:\n",
+    "                print(f\"{sn}\\t{obj.user_friendly_name} belongs? {sn.subnet_of(net)}\")\n",
+    "        else:\n",
+    "            print(\"No subnets!\")\n",
+    "\n",
+    "        # Validate addresses (again)\n",
+    "        for (obj, addr) in addresses:\n",
+    "            print(f\"NetworkInterface '{obj.user_friendly_name}' ({addr}) belong to net '{network.user_friendly_name}' ({net_addr})? {addr in net.hosts()}\")\n",
+    "\n",
+    "  \n",
+    "\n",
+    "validate_network_address(dmc)"
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": ".venv",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.11.5"
+  },
+  "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/mc_openapi/notebooks/stats.ipynb b/mc_openapi/notebooks/stats.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..08318bbb50f864e2df5ce8456edd537b4b5e89ae
--- /dev/null
+++ b/mc_openapi/notebooks/stats.ipynb
@@ -0,0 +1,297 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 246,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "PROJ_PATH = '/home/andrea/Projects/piacere-model-checker'\n",
+    "TESTS_PATH = PROJ_PATH + '/tests/doml/CaseStudies/*.domlx'"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 247,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from glob import glob"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 248,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "['/home/andrea/Projects/piacere-model-checker/tests/doml/CaseStudies/SIMPA_Validation_v2.domlx',\n",
+       " '/home/andrea/Projects/piacere-model-checker/tests/doml/CaseStudies/nio3_test_exec_env.domlx',\n",
+       " '/home/andrea/Projects/piacere-model-checker/tests/doml/CaseStudies/posidonia.domlx',\n",
+       " '/home/andrea/Projects/piacere-model-checker/tests/doml/CaseStudies/posidonia_IOP.domlx',\n",
+       " '/home/andrea/Projects/piacere-model-checker/tests/doml/CaseStudies/uc3-openstack_v2.domlx']"
+      ]
+     },
+     "execution_count": 248,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "domlx_files = glob(TESTS_PATH)\n",
+    "\n",
+    "domlx_files"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 249,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "/home/andrea/Projects/piacere-model-checker\n",
+      "Using DOML v2.2.1\n",
+      "[RESULT]\n",
+      "unsat\n",
+      "[ERRORS]\n",
+      "\u001b[91m[Built-in]\n",
+      "Software component 'nio3_git' is not deployed to any abstract infrastructure node.\u001b[00m\n",
+      "[STATS]\n",
+      "memory,conflicts,quant instantiations\n",
+      "40.38,1273,1253\n",
+      "\n",
+      "\n",
+      "Using DOML v2.2.1\n",
+      "[RESULT]\n",
+      "sat\n",
+      "[STATS]\n",
+      "memory,conflicts,quant instantiations\n",
+      "43.29,2592,2614\n",
+      "\n",
+      "\n",
+      "Using DOML v2.2.1\n",
+      "[RESULT]\n",
+      "unsat\n",
+      "[ERRORS]\n",
+      "\u001b[91m[Built-in]\n",
+      "Virtual machine gestaut_vm is connected to no network interface.\n",
+      "Software components 'Database' and 'Gestaut' are supposed to communicate through interface 'dbAccess', but they are deployed to nodes that cannot communicate through a common network.\n",
+      "Abstract infrastructure element 'gestaut_vm' has not been mapped to any element in the active concretization.\n",
+      "Security group 'sg' is not associated with any network interface.\u001b[00m\n",
+      "[STATS]\n",
+      "memory,conflicts,quant instantiations\n",
+      "91.13,1875,2794\n",
+      "\n",
+      "\n",
+      "Using DOML v2.2.1\n",
+      "[RESULT]\n",
+      "unsat\n",
+      "[ERRORS]\n",
+      "\u001b[91m[Built-in]\n",
+      "Virtual machine gestaut_vm is connected to no network interface.\n",
+      "Software components 'Database' and 'Gestaut' are supposed to communicate through interface 'dbAccess', but they are deployed to nodes that cannot communicate through a common network.\n",
+      "Abstract infrastructure element 'gestaut_vm' has not been mapped to any element in the active concretization.\n",
+      "Security group 'sg' is not associated with any network interface.\u001b[00m\n",
+      "[STATS]\n",
+      "memory,conflicts,quant instantiations\n",
+      "91.45,1417,2263\n",
+      "\n",
+      "\n",
+      "Using DOML v2.2.1\n",
+      "[RESULT]\n",
+      "unsat\n",
+      "[ERRORS]\n",
+      "\u001b[91m[Built-in]\n",
+      "Security group 'sg' is not associated with any network interface.\u001b[00m\n",
+      "[STATS]\n",
+      "memory,conflicts,quant instantiations\n",
+      "91.29,7649,8422\n",
+      "\n",
+      "\n"
+     ]
+    },
+    {
+     "data": {
+      "text/html": [
+       "<div>\n",
+       "<style scoped>\n",
+       "    .dataframe tbody tr th:only-of-type {\n",
+       "        vertical-align: middle;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe tbody tr th {\n",
+       "        vertical-align: top;\n",
+       "    }\n",
+       "\n",
+       "    .dataframe thead th {\n",
+       "        text-align: right;\n",
+       "    }\n",
+       "</style>\n",
+       "<table border=\"1\" class=\"dataframe\">\n",
+       "  <thead>\n",
+       "    <tr style=\"text-align: right;\">\n",
+       "      <th></th>\n",
+       "      <th>filename</th>\n",
+       "      <th>time</th>\n",
+       "      <th>doml_ver</th>\n",
+       "      <th>result</th>\n",
+       "      <th>#error</th>\n",
+       "      <th>memory</th>\n",
+       "      <th>conflicts</th>\n",
+       "      <th>quant inst</th>\n",
+       "    </tr>\n",
+       "  </thead>\n",
+       "  <tbody>\n",
+       "    <tr>\n",
+       "      <th>0</th>\n",
+       "      <td>SIMPA_Validation_v2.domlx</td>\n",
+       "      <td>1.344904</td>\n",
+       "      <td>2.2.1</td>\n",
+       "      <td>unsat</td>\n",
+       "      <td>3</td>\n",
+       "      <td>40.38</td>\n",
+       "      <td>1273</td>\n",
+       "      <td>1253</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>0</th>\n",
+       "      <td>nio3_test_exec_env.domlx</td>\n",
+       "      <td>1.602703</td>\n",
+       "      <td>2.2.1</td>\n",
+       "      <td></td>\n",
+       "      <td>2</td>\n",
+       "      <td>43.29</td>\n",
+       "      <td>2592</td>\n",
+       "      <td>2614</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>0</th>\n",
+       "      <td>posidonia.domlx</td>\n",
+       "      <td>16.781076</td>\n",
+       "      <td>2.2.1</td>\n",
+       "      <td>unsat</td>\n",
+       "      <td>6</td>\n",
+       "      <td>91.13</td>\n",
+       "      <td>1875</td>\n",
+       "      <td>2794</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>0</th>\n",
+       "      <td>posidonia_IOP.domlx</td>\n",
+       "      <td>16.956536</td>\n",
+       "      <td>2.2.1</td>\n",
+       "      <td>unsat</td>\n",
+       "      <td>6</td>\n",
+       "      <td>91.45</td>\n",
+       "      <td>1417</td>\n",
+       "      <td>2263</td>\n",
+       "    </tr>\n",
+       "    <tr>\n",
+       "      <th>0</th>\n",
+       "      <td>uc3-openstack_v2.domlx</td>\n",
+       "      <td>10.553367</td>\n",
+       "      <td>2.2.1</td>\n",
+       "      <td>unsat</td>\n",
+       "      <td>3</td>\n",
+       "      <td>91.29</td>\n",
+       "      <td>7649</td>\n",
+       "      <td>8422</td>\n",
+       "    </tr>\n",
+       "  </tbody>\n",
+       "</table>\n",
+       "</div>"
+      ],
+      "text/plain": [
+       "                    filename       time doml_ver result #error memory  \\\n",
+       "0  SIMPA_Validation_v2.domlx   1.344904    2.2.1  unsat      3  40.38   \n",
+       "0   nio3_test_exec_env.domlx   1.602703    2.2.1             2  43.29   \n",
+       "0            posidonia.domlx  16.781076    2.2.1  unsat      6  91.13   \n",
+       "0        posidonia_IOP.domlx  16.956536    2.2.1  unsat      6  91.45   \n",
+       "0     uc3-openstack_v2.domlx  10.553367    2.2.1  unsat      3  91.29   \n",
+       "\n",
+       "  conflicts quant inst  \n",
+       "0      1273       1253  \n",
+       "0      2592       2614  \n",
+       "0      1875       2794  \n",
+       "0      1417       2263  \n",
+       "0      7649       8422  "
+      ]
+     },
+     "execution_count": 249,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "import subprocess\n",
+    "import os\n",
+    "from time import time\n",
+    "import pandas as pd\n",
+    "\n",
+    "os.chdir(PROJ_PATH)\n",
+    "\n",
+    "print(os.getcwd())\n",
+    "\n",
+    "test_cmd = lambda file: f\"python -m mc_openapi -z -d {file}\"\n",
+    "\n",
+    "df = pd.DataFrame(columns=['filename', 'time', 'doml_ver', 'result', '#error', 'memory', 'conflicts', 'quant inst'])\n",
+    "\n",
+    "for file in domlx_files:\n",
+    "\n",
+    "    filename = file.split(\"/\")[-1]\n",
+    "\n",
+    "    # I know that using time is inaccurate, but it's simple and it works for generating simple benchmarks\n",
+    "    start_time = time()\n",
+    "    out = subprocess.run(test_cmd(file), shell=True, capture_output=True)\n",
+    "    run_time = time() - start_time\n",
+    "\n",
+    "    r = out.stdout.decode('utf-8')\n",
+    "\n",
+    "    print(r)\n",
+    "\n",
+    "    doml_ver, _, r = r.rpartition(\"[RESULT]\")\n",
+    "    result, _, r = r.rpartition(\"[ERRORS]\")\n",
+    "    errors, _, stats = r.rpartition(\"[STATS]\")\n",
+    "    _, _, doml_ver = doml_ver.rpartition(\"v\")\n",
+    "\n",
+    "    doml_ver = doml_ver.replace(\"\\n\", \"\")\n",
+    "    result = result.replace(\"\\n\", \"\")\n",
+    "    error_num = len(errors.split(\"\\n\")) - 1\n",
+    "    stats = stats.split(\"\\n\")[2].split(\",\")[-3:]\n",
+    "\n",
+    "    df2 = pd.DataFrame([[filename, run_time, doml_ver, result, error_num, *stats]], columns=df.columns)\n",
+    "\n",
+    "    df = pd.concat([df, df2])\n",
+    "\n",
+    "df"
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": ".venv",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.11.2"
+  },
+  "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/mc_openapi/doml_mc/test.ipynb b/mc_openapi/notebooks/test.ipynb
similarity index 62%
rename from mc_openapi/doml_mc/test.ipynb
rename to mc_openapi/notebooks/test.ipynb
index 8f66fd800269e476de78ff06491f3044e3bfca38..c94c86e4f20176442a329ef00ad45ef6d54d6de9 100644
--- a/mc_openapi/doml_mc/test.ipynb
+++ b/mc_openapi/notebooks/test.ipynb
@@ -8,13 +8,13 @@
    "source": [
     "import mc_openapi.doml_mc as mc\n",
     "\n",
-    "doml_document_path = \"../../tests/doml/nginx-openstack_v2.domlx\"\n",
-    "# doml_document_path = \"../../tests/doml/nginx-openstack_v2_wrong.domlx\"\n",
-    "# doml_document_path = \"../../tests/doml/faas.domlx\"\n",
+    "doml_document_path = \"../../tests/doml/v2.0/nginx-openstack_v2.0.domlx\"\n",
+    "# doml_document_path = \"../../tests/doml/v2.0/nginx-openstack_v2.0_wrong_vm_iface.domlx\"\n",
+    "# doml_document_path = \"../../tests/doml/v2.0/faas.domlx\"\n",
     "with open(doml_document_path, \"rb\") as xmif:\n",
     "    doc = xmif.read()\n",
     "\n",
-    "dmc = mc.ModelChecker(doc)"
+    "dmc = mc.ModelChecker(doc, mc.DOMLVersion.V2_0)"
    ]
   },
   {
@@ -23,14 +23,14 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "r = dmc.check_common_requirements(2, False, 50)\n",
+    "r = dmc.check_requirements(2, False, 50)\n",
     "r.summarize()"
    ]
   }
  ],
  "metadata": {
   "kernelspec": {
-   "display_name": "Python 3.10.4 ('mc-openapi-dl7Bx6Lh-py3.10')",
+   "display_name": "Python 3.11.0 ('.venv': poetry)",
    "language": "python",
    "name": "python3"
   },
@@ -44,12 +44,12 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.10.4"
+   "version": "3.11.0"
   },
   "orig_nbformat": 4,
   "vscode": {
    "interpreter": {
-    "hash": "ad63ed7e22c54016fdab5faefd8d83d59c3e39bc25e97a3e7b72bed4daaf83ed"
+    "hash": "d98256633358fe1daa4009223d54520a3e2548801398a173545d5698bb289e16"
    }
   }
  },
diff --git a/mc_openapi/openapi/model_checker.yaml b/mc_openapi/openapi/model_checker.yaml
deleted file mode 100644
index b1875dd5fcab22615fd7d6bb63595aa38d96ae98..0000000000000000000000000000000000000000
--- a/mc_openapi/openapi/model_checker.yaml
+++ /dev/null
@@ -1,73 +0,0 @@
-openapi: 3.0.2
-info:
-  license:
-    name: Apache-2.0
-  title: PIACERE Model Checker
-  version: "1.0"
-paths:
-  /modelcheck:
-    post:
-      description: Send a DOML model in XMI format and a requirement to check.
-        The response says whether the requirement is satisfied by the model,
-        with a description of the issue if it is not.
-      operationId: mc_openapi.handlers.post
-      requestBody:
-        content:
-          application/xml:
-            schema:
-              type: string
-        required: true
-      parameters:
-        - in: query
-          name: requirement
-          required: false
-          schema:
-            type: string
-          description: Requirement to be verified (optional)
-      responses:
-        "200":
-          content:
-            application/json:
-              schema:
-                type: object
-                properties:
-                  result:
-                    type: string
-                    enum:
-                      - sat
-                      - unsat
-                      - dontknow
-                  description:
-                    type: string
-                required:
-                  - result
-          description: OK - model checking succeded
-        "400":
-          content:
-            application/json:
-              schema:
-                $ref: '#/components/schemas/error'
-          description: malformed request
-        "500":
-          content:
-            application/json:
-              schema:
-                $ref: '#/components/schemas/error'
-          description: internal error
-components:
-  schemas:
-    error:
-      type: object
-      properties:
-        timestamp:
-          type: string
-          format: date-time
-        message:
-          type: string
-          description: Error message for the user
-        debug_message:
-          type: string
-          description: Detailed error message for debugging purposes
-      required:
-        - timestamp
-        - message
diff --git a/poetry.lock b/poetry.lock
deleted file mode 100644
index f8c1a69aea59cc944a26952524db9517d5389592..0000000000000000000000000000000000000000
--- a/poetry.lock
+++ /dev/null
@@ -1,1433 +0,0 @@
-[[package]]
-name = "appnope"
-version = "0.1.3"
-description = "Disable App Nap on macOS >= 10.9"
-category = "dev"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "asttokens"
-version = "2.0.5"
-description = "Annotate AST trees with source code positions"
-category = "dev"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-six = "*"
-
-[package.extras]
-test = ["astroid", "pytest"]
-
-[[package]]
-name = "atomicwrites"
-version = "1.4.1"
-description = "Atomic file writes."
-category = "dev"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
-
-[[package]]
-name = "attrs"
-version = "22.1.0"
-description = "Classes Without Boilerplate"
-category = "main"
-optional = false
-python-versions = ">=3.5"
-
-[package.extras]
-dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "mypy (>=0.900,!=0.940)", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit", "cloudpickle"]
-docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"]
-tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "mypy (>=0.900,!=0.940)", "pytest-mypy-plugins", "zope.interface", "cloudpickle"]
-tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "mypy (>=0.900,!=0.940)", "pytest-mypy-plugins", "cloudpickle"]
-
-[[package]]
-name = "backcall"
-version = "0.2.0"
-description = "Specifications for callback functions passed in to an API"
-category = "dev"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "certifi"
-version = "2022.6.15"
-description = "Python package for providing Mozilla's CA Bundle."
-category = "main"
-optional = false
-python-versions = ">=3.6"
-
-[[package]]
-name = "cffi"
-version = "1.15.1"
-description = "Foreign Function Interface for Python calling C code."
-category = "dev"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-pycparser = "*"
-
-[[package]]
-name = "charset-normalizer"
-version = "2.1.0"
-description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
-category = "main"
-optional = false
-python-versions = ">=3.6.0"
-
-[package.extras]
-unicode_backport = ["unicodedata2"]
-
-[[package]]
-name = "click"
-version = "8.1.3"
-description = "Composable command line interface toolkit"
-category = "main"
-optional = false
-python-versions = ">=3.7"
-
-[package.dependencies]
-colorama = {version = "*", markers = "platform_system == \"Windows\""}
-
-[[package]]
-name = "clickclick"
-version = "20.10.2"
-description = "Click utility functions"
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-click = ">=4.0"
-PyYAML = ">=3.11"
-
-[[package]]
-name = "colorama"
-version = "0.4.5"
-description = "Cross-platform colored terminal text."
-category = "main"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
-
-[[package]]
-name = "colorful"
-version = "0.5.4"
-description = "Terminal string styling done right, in Python."
-category = "dev"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-colorama = {version = "*", markers = "platform_system == \"Windows\""}
-
-[[package]]
-name = "connexion"
-version = "2.14.0"
-description = "Connexion - API first applications with OpenAPI/Swagger and Flask"
-category = "main"
-optional = false
-python-versions = ">=3.6"
-
-[package.dependencies]
-clickclick = ">=1.2,<21"
-flask = ">=1.0.4,<3"
-inflection = ">=0.3.1,<0.6"
-itsdangerous = ">=0.24"
-jsonschema = ">=2.5.1,<5"
-packaging = ">=20"
-PyYAML = ">=5.1,<7"
-requests = ">=2.9.1,<3"
-swagger-ui-bundle = {version = ">=0.0.2,<0.1", optional = true, markers = "extra == \"swagger-ui\""}
-werkzeug = ">=1.0,<3"
-
-[package.extras]
-aiohttp = ["aiohttp (>=2.3.10,<4)", "aiohttp-jinja2 (>=0.14.0,<2)", "MarkupSafe (>=0.23)"]
-docs = ["sphinx-autoapi (==1.8.1)"]
-flask = ["flask (>=1.0.4,<3)", "itsdangerous (>=0.24)"]
-swagger-ui = ["swagger-ui-bundle (>=0.0.2,<0.1)"]
-tests = ["decorator (>=5,<6)", "pytest (>=6,<7)", "pytest-cov (>=2,<3)", "testfixtures (>=6,<7)", "flask (>=1.0.4,<3)", "itsdangerous (>=0.24)", "swagger-ui-bundle (>=0.0.2,<0.1)", "aiohttp (>=2.3.10,<4)", "aiohttp-jinja2 (>=0.14.0,<2)", "MarkupSafe (>=0.23)", "pytest-aiohttp", "aiohttp-remotes"]
-
-[[package]]
-name = "debugpy"
-version = "1.6.2"
-description = "An implementation of the Debug Adapter Protocol for Python"
-category = "dev"
-optional = false
-python-versions = ">=3.7"
-
-[[package]]
-name = "decorator"
-version = "5.1.1"
-description = "Decorators for Humans"
-category = "dev"
-optional = false
-python-versions = ">=3.5"
-
-[[package]]
-name = "entrypoints"
-version = "0.4"
-description = "Discover and load entry points from installed packages."
-category = "dev"
-optional = false
-python-versions = ">=3.6"
-
-[[package]]
-name = "executing"
-version = "0.9.1"
-description = "Get the currently executing AST node of a frame, and other information"
-category = "dev"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "flask"
-version = "2.1.3"
-description = "A simple framework for building complex web applications."
-category = "main"
-optional = false
-python-versions = ">=3.7"
-
-[package.dependencies]
-click = ">=8.0"
-importlib-metadata = {version = ">=3.6.0", markers = "python_version < \"3.10\""}
-itsdangerous = ">=2.0"
-Jinja2 = ">=3.0"
-Werkzeug = ">=2.0"
-
-[package.extras]
-async = ["asgiref (>=3.2)"]
-dotenv = ["python-dotenv"]
-
-[[package]]
-name = "future-fstrings"
-version = "1.2.0"
-description = "A backport of fstrings to python<3.6"
-category = "main"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
-
-[package.extras]
-rewrite = ["tokenize-rt (>=3)"]
-
-[[package]]
-name = "idna"
-version = "3.3"
-description = "Internationalized Domain Names in Applications (IDNA)"
-category = "main"
-optional = false
-python-versions = ">=3.5"
-
-[[package]]
-name = "importlib-metadata"
-version = "4.12.0"
-description = "Read metadata from Python packages"
-category = "main"
-optional = false
-python-versions = ">=3.7"
-
-[package.dependencies]
-zipp = ">=0.5"
-
-[package.extras]
-docs = ["sphinx", "jaraco.packaging (>=9)", "rst.linker (>=1.9)"]
-perf = ["ipython"]
-testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.3)", "packaging", "pyfakefs", "flufl.flake8", "pytest-perf (>=0.9.2)", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)", "importlib-resources (>=1.3)"]
-
-[[package]]
-name = "inflection"
-version = "0.5.1"
-description = "A port of Ruby on Rails inflector to Python"
-category = "main"
-optional = false
-python-versions = ">=3.5"
-
-[[package]]
-name = "iniconfig"
-version = "1.1.1"
-description = "iniconfig: brain-dead simple config-ini parsing"
-category = "dev"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "ipykernel"
-version = "6.15.1"
-description = "IPython Kernel for Jupyter"
-category = "dev"
-optional = false
-python-versions = ">=3.7"
-
-[package.dependencies]
-appnope = {version = "*", markers = "platform_system == \"Darwin\""}
-debugpy = ">=1.0"
-ipython = ">=7.23.1"
-jupyter-client = ">=6.1.12"
-matplotlib-inline = ">=0.1"
-nest-asyncio = "*"
-packaging = "*"
-psutil = "*"
-pyzmq = ">=17"
-tornado = ">=6.1"
-traitlets = ">=5.1.0"
-
-[package.extras]
-test = ["flaky", "ipyparallel", "pre-commit", "pytest-cov", "pytest-timeout", "pytest (>=6.0)"]
-
-[[package]]
-name = "ipython"
-version = "8.4.0"
-description = "IPython: Productive Interactive Computing"
-category = "dev"
-optional = false
-python-versions = ">=3.8"
-
-[package.dependencies]
-appnope = {version = "*", markers = "sys_platform == \"darwin\""}
-backcall = "*"
-colorama = {version = "*", markers = "sys_platform == \"win32\""}
-decorator = "*"
-jedi = ">=0.16"
-matplotlib-inline = "*"
-pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""}
-pickleshare = "*"
-prompt-toolkit = ">=2.0.0,<3.0.0 || >3.0.0,<3.0.1 || >3.0.1,<3.1.0"
-pygments = ">=2.4.0"
-stack-data = "*"
-traitlets = ">=5"
-
-[package.extras]
-all = ["black", "Sphinx (>=1.3)", "ipykernel", "nbconvert", "nbformat", "ipywidgets", "notebook", "ipyparallel", "qtconsole", "pytest (<7.1)", "pytest-asyncio", "testpath", "curio", "matplotlib (!=3.2.0)", "numpy (>=1.19)", "pandas", "trio"]
-black = ["black"]
-doc = ["Sphinx (>=1.3)"]
-kernel = ["ipykernel"]
-nbconvert = ["nbconvert"]
-nbformat = ["nbformat"]
-notebook = ["ipywidgets", "notebook"]
-parallel = ["ipyparallel"]
-qtconsole = ["qtconsole"]
-test = ["pytest (<7.1)", "pytest-asyncio", "testpath"]
-test_extra = ["pytest (<7.1)", "pytest-asyncio", "testpath", "curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.19)", "pandas", "trio"]
-
-[[package]]
-name = "itsdangerous"
-version = "2.1.2"
-description = "Safely pass data to untrusted environments and back."
-category = "main"
-optional = false
-python-versions = ">=3.7"
-
-[[package]]
-name = "jedi"
-version = "0.18.1"
-description = "An autocompletion tool for Python that can be used for text editors."
-category = "dev"
-optional = false
-python-versions = ">=3.6"
-
-[package.dependencies]
-parso = ">=0.8.0,<0.9.0"
-
-[package.extras]
-qa = ["flake8 (==3.8.3)", "mypy (==0.782)"]
-testing = ["Django (<3.1)", "colorama", "docopt", "pytest (<7.0.0)"]
-
-[[package]]
-name = "jinja2"
-version = "3.1.2"
-description = "A very fast and expressive template engine."
-category = "main"
-optional = false
-python-versions = ">=3.7"
-
-[package.dependencies]
-MarkupSafe = ">=2.0"
-
-[package.extras]
-i18n = ["Babel (>=2.7)"]
-
-[[package]]
-name = "joblib"
-version = "1.1.0"
-description = "Lightweight pipelining with Python functions"
-category = "main"
-optional = false
-python-versions = ">=3.6"
-
-[[package]]
-name = "jsonschema"
-version = "4.8.0"
-description = "An implementation of JSON Schema validation for Python"
-category = "main"
-optional = false
-python-versions = ">=3.7"
-
-[package.dependencies]
-attrs = ">=17.4.0"
-pyrsistent = ">=0.14.0,<0.17.0 || >0.17.0,<0.17.1 || >0.17.1,<0.17.2 || >0.17.2"
-
-[package.extras]
-format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"]
-format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"]
-
-[[package]]
-name = "jupyter-client"
-version = "7.3.4"
-description = "Jupyter protocol implementation and client libraries"
-category = "dev"
-optional = false
-python-versions = ">=3.7"
-
-[package.dependencies]
-entrypoints = "*"
-jupyter-core = ">=4.9.2"
-nest-asyncio = ">=1.5.4"
-python-dateutil = ">=2.8.2"
-pyzmq = ">=23.0"
-tornado = ">=6.0"
-traitlets = "*"
-
-[package.extras]
-doc = ["ipykernel", "myst-parser", "sphinx-rtd-theme", "sphinx (>=1.3.6)", "sphinxcontrib-github-alt"]
-test = ["codecov", "coverage", "ipykernel (>=6.5)", "ipython", "mypy", "pre-commit", "pytest", "pytest-asyncio (>=0.18)", "pytest-cov", "pytest-timeout"]
-
-[[package]]
-name = "jupyter-core"
-version = "4.11.1"
-description = "Jupyter core package. A base package on which Jupyter projects rely."
-category = "dev"
-optional = false
-python-versions = ">=3.7"
-
-[package.dependencies]
-pywin32 = {version = ">=1.0", markers = "sys_platform == \"win32\" and platform_python_implementation != \"PyPy\""}
-traitlets = "*"
-
-[package.extras]
-test = ["ipykernel", "pre-commit", "pytest", "pytest-cov", "pytest-timeout"]
-
-[[package]]
-name = "lxml"
-version = "4.9.1"
-description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API."
-category = "main"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, != 3.4.*"
-
-[package.extras]
-cssselect = ["cssselect (>=0.7)"]
-html5 = ["html5lib"]
-htmlsoup = ["beautifulsoup4"]
-source = ["Cython (>=0.29.7)"]
-
-[[package]]
-name = "markupsafe"
-version = "2.1.1"
-description = "Safely add untrusted strings to HTML/XML markup."
-category = "main"
-optional = false
-python-versions = ">=3.7"
-
-[[package]]
-name = "matplotlib-inline"
-version = "0.1.3"
-description = "Inline Matplotlib backend for Jupyter"
-category = "dev"
-optional = false
-python-versions = ">=3.5"
-
-[package.dependencies]
-traitlets = "*"
-
-[[package]]
-name = "nest-asyncio"
-version = "1.5.5"
-description = "Patch asyncio to allow nested event loops"
-category = "dev"
-optional = false
-python-versions = ">=3.5"
-
-[[package]]
-name = "networkx"
-version = "2.8.5"
-description = "Python package for creating and manipulating graphs and networks"
-category = "main"
-optional = false
-python-versions = ">=3.8"
-
-[package.extras]
-default = ["numpy (>=1.19)", "scipy (>=1.8)", "matplotlib (>=3.4)", "pandas (>=1.3)"]
-developer = ["pre-commit (>=2.19)", "mypy (>=0.960)"]
-doc = ["sphinx (>=5)", "pydata-sphinx-theme (>=0.9)", "sphinx-gallery (>=0.10)", "numpydoc (>=1.4)", "pillow (>=9.1)", "nb2plots (>=0.6)", "texext (>=0.6.6)"]
-extra = ["lxml (>=4.6)", "pygraphviz (>=1.9)", "pydot (>=1.4.2)", "sympy (>=1.10)"]
-test = ["pytest (>=7.1)", "pytest-cov (>=3.0)", "codecov (>=2.1)"]
-
-[[package]]
-name = "ordered-set"
-version = "4.1.0"
-description = "An OrderedSet is a custom MutableSet that remembers its order, so that every"
-category = "main"
-optional = false
-python-versions = ">=3.7"
-
-[package.extras]
-dev = ["pytest", "black", "mypy"]
-
-[[package]]
-name = "packaging"
-version = "21.3"
-description = "Core utilities for Python packages"
-category = "main"
-optional = false
-python-versions = ">=3.6"
-
-[package.dependencies]
-pyparsing = ">=2.0.2,<3.0.5 || >3.0.5"
-
-[[package]]
-name = "parso"
-version = "0.8.3"
-description = "A Python Parser"
-category = "dev"
-optional = false
-python-versions = ">=3.6"
-
-[package.extras]
-qa = ["flake8 (==3.8.3)", "mypy (==0.782)"]
-testing = ["docopt", "pytest (<6.0.0)"]
-
-[[package]]
-name = "pexpect"
-version = "4.8.0"
-description = "Pexpect allows easy control of interactive console applications."
-category = "dev"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-ptyprocess = ">=0.5"
-
-[[package]]
-name = "pickleshare"
-version = "0.7.5"
-description = "Tiny 'shelve'-like database with concurrency support"
-category = "dev"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "pluggy"
-version = "1.0.0"
-description = "plugin and hook calling mechanisms for python"
-category = "dev"
-optional = false
-python-versions = ">=3.6"
-
-[package.extras]
-dev = ["pre-commit", "tox"]
-testing = ["pytest", "pytest-benchmark"]
-
-[[package]]
-name = "prettyprinter"
-version = "0.18.0"
-description = "Syntax-highlighting, declarative and composable pretty printer for Python 3.5+"
-category = "dev"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-colorful = ">=0.4.0"
-Pygments = ">=2.2.0"
-
-[[package]]
-name = "prompt-toolkit"
-version = "3.0.30"
-description = "Library for building powerful interactive command lines in Python"
-category = "dev"
-optional = false
-python-versions = ">=3.6.2"
-
-[package.dependencies]
-wcwidth = "*"
-
-[[package]]
-name = "psutil"
-version = "5.9.1"
-description = "Cross-platform lib for process and system monitoring in Python."
-category = "dev"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
-
-[package.extras]
-test = ["ipaddress", "mock", "enum34", "pywin32", "wmi"]
-
-[[package]]
-name = "ptyprocess"
-version = "0.7.0"
-description = "Run a subprocess in a pseudo terminal"
-category = "dev"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "pure-eval"
-version = "0.2.2"
-description = "Safely evaluate AST nodes without side effects"
-category = "dev"
-optional = false
-python-versions = "*"
-
-[package.extras]
-tests = ["pytest"]
-
-[[package]]
-name = "py"
-version = "1.11.0"
-description = "library with cross-python path, ini-parsing, io, code, log facilities"
-category = "dev"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
-
-[[package]]
-name = "pycparser"
-version = "2.21"
-description = "C parser in Python"
-category = "dev"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
-
-[[package]]
-name = "pyecore"
-version = "0.12.2"
-description = "A Python(ic) Implementation of the Eclipse Modeling Framework (EMF/Ecore)"
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-future-fstrings = "*"
-lxml = "*"
-ordered-set = ">=4.0.1"
-restrictedpython = ">=4.0b6"
-
-[[package]]
-name = "pygments"
-version = "2.12.0"
-description = "Pygments is a syntax highlighting package written in Python."
-category = "dev"
-optional = false
-python-versions = ">=3.6"
-
-[[package]]
-name = "pyparsing"
-version = "3.0.9"
-description = "pyparsing module - Classes and methods to define and execute parsing grammars"
-category = "main"
-optional = false
-python-versions = ">=3.6.8"
-
-[package.extras]
-diagrams = ["railroad-diagrams", "jinja2"]
-
-[[package]]
-name = "pyrsistent"
-version = "0.18.1"
-description = "Persistent/Functional/Immutable data structures"
-category = "main"
-optional = false
-python-versions = ">=3.7"
-
-[[package]]
-name = "pytest"
-version = "6.2.5"
-description = "pytest: simple powerful testing with Python"
-category = "dev"
-optional = false
-python-versions = ">=3.6"
-
-[package.dependencies]
-atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""}
-attrs = ">=19.2.0"
-colorama = {version = "*", markers = "sys_platform == \"win32\""}
-iniconfig = "*"
-packaging = "*"
-pluggy = ">=0.12,<2.0"
-py = ">=1.8.2"
-toml = "*"
-
-[package.extras]
-testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"]
-
-[[package]]
-name = "python-dateutil"
-version = "2.8.2"
-description = "Extensions to the standard Python datetime module"
-category = "dev"
-optional = false
-python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7"
-
-[package.dependencies]
-six = ">=1.5"
-
-[[package]]
-name = "pywin32"
-version = "304"
-description = "Python for Window Extensions"
-category = "dev"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "pyyaml"
-version = "6.0"
-description = "YAML parser and emitter for Python"
-category = "main"
-optional = false
-python-versions = ">=3.6"
-
-[[package]]
-name = "pyzmq"
-version = "23.2.0"
-description = "Python bindings for 0MQ"
-category = "dev"
-optional = false
-python-versions = ">=3.6"
-
-[package.dependencies]
-cffi = {version = "*", markers = "implementation_name == \"pypy\""}
-py = {version = "*", markers = "implementation_name == \"pypy\""}
-
-[[package]]
-name = "requests"
-version = "2.28.1"
-description = "Python HTTP for Humans."
-category = "main"
-optional = false
-python-versions = ">=3.7, <4"
-
-[package.dependencies]
-certifi = ">=2017.4.17"
-charset-normalizer = ">=2,<3"
-idna = ">=2.5,<4"
-urllib3 = ">=1.21.1,<1.27"
-
-[package.extras]
-socks = ["PySocks (>=1.5.6,!=1.5.7)"]
-use_chardet_on_py3 = ["chardet (>=3.0.2,<6)"]
-
-[[package]]
-name = "restrictedpython"
-version = "5.0"
-description = "RestrictedPython is a defined subset of the Python language which allows to provide a program input into a trusted environment."
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.extras]
-test = ["pytest", "pytest-mock"]
-
-[[package]]
-name = "six"
-version = "1.16.0"
-description = "Python 2 and 3 compatibility utilities"
-category = "dev"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
-
-[[package]]
-name = "stack-data"
-version = "0.3.0"
-description = "Extract data from python stack frames and tracebacks for informative displays"
-category = "dev"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-asttokens = "*"
-executing = "*"
-pure-eval = "*"
-
-[package.extras]
-tests = ["pytest", "typeguard", "pygments", "littleutils", "cython"]
-
-[[package]]
-name = "swagger-ui-bundle"
-version = "0.0.9"
-description = "swagger_ui_bundle - swagger-ui files in a pip package"
-category = "main"
-optional = false
-python-versions = "*"
-
-[package.dependencies]
-Jinja2 = ">=2.0"
-
-[[package]]
-name = "toml"
-version = "0.10.2"
-description = "Python Library for Tom's Obvious, Minimal Language"
-category = "dev"
-optional = false
-python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
-
-[[package]]
-name = "tornado"
-version = "6.2"
-description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed."
-category = "dev"
-optional = false
-python-versions = ">= 3.7"
-
-[[package]]
-name = "traitlets"
-version = "5.3.0"
-description = ""
-category = "dev"
-optional = false
-python-versions = ">=3.7"
-
-[package.extras]
-test = ["pre-commit", "pytest"]
-
-[[package]]
-name = "urllib3"
-version = "1.26.11"
-description = "HTTP library with thread-safe connection pooling, file post, and more."
-category = "main"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, <4"
-
-[package.extras]
-brotli = ["brotlicffi (>=0.8.0)", "brotli (>=1.0.9)", "brotlipy (>=0.6.0)"]
-secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"]
-socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
-
-[[package]]
-name = "uwsgi"
-version = "2.0.20"
-description = "The uWSGI server"
-category = "main"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "wcwidth"
-version = "0.2.5"
-description = "Measures the displayed width of unicode strings in a terminal"
-category = "dev"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "werkzeug"
-version = "2.2.1"
-description = "The comprehensive WSGI web application library."
-category = "main"
-optional = false
-python-versions = ">=3.7"
-
-[package.dependencies]
-MarkupSafe = ">=2.1.1"
-
-[package.extras]
-watchdog = ["watchdog"]
-
-[[package]]
-name = "z3-solver"
-version = "4.10.2.0"
-description = "an efficient SMT solver library"
-category = "main"
-optional = false
-python-versions = "*"
-
-[[package]]
-name = "zipp"
-version = "3.8.1"
-description = "Backport of pathlib-compatible object wrapper for zip files"
-category = "main"
-optional = false
-python-versions = ">=3.7"
-
-[package.extras]
-docs = ["sphinx", "jaraco.packaging (>=9)", "rst.linker (>=1.9)", "jaraco.tidelift (>=1.4)"]
-testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.3)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy (>=0.9.1)"]
-
-[metadata]
-lock-version = "1.1"
-python-versions = "^3.9"
-content-hash = "a3bdfb031327e5a6361afc9fb3c81b3e132d8d8babe46c26aa671dedfe4ba70b"
-
-[metadata.files]
-appnope = [
-    {file = "appnope-0.1.3-py2.py3-none-any.whl", hash = "sha256:265a455292d0bd8a72453494fa24df5a11eb18373a60c7c0430889f22548605e"},
-    {file = "appnope-0.1.3.tar.gz", hash = "sha256:02bd91c4de869fbb1e1c50aafc4098827a7a54ab2f39d9dcba6c9547ed920e24"},
-]
-asttokens = [
-    {file = "asttokens-2.0.5-py2.py3-none-any.whl", hash = "sha256:0844691e88552595a6f4a4281a9f7f79b8dd45ca4ccea82e5e05b4bbdb76705c"},
-    {file = "asttokens-2.0.5.tar.gz", hash = "sha256:9a54c114f02c7a9480d56550932546a3f1fe71d8a02f1bc7ccd0ee3ee35cf4d5"},
-]
-atomicwrites = []
-attrs = []
-backcall = [
-    {file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"},
-    {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"},
-]
-certifi = [
-    {file = "certifi-2022.6.15-py3-none-any.whl", hash = "sha256:fe86415d55e84719d75f8b69414f6438ac3547d2078ab91b67e779ef69378412"},
-    {file = "certifi-2022.6.15.tar.gz", hash = "sha256:84c85a9078b11105f04f3036a9482ae10e4621616db313fe045dd24743a0820d"},
-]
-cffi = [
-    {file = "cffi-1.15.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2"},
-    {file = "cffi-1.15.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2"},
-    {file = "cffi-1.15.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914"},
-    {file = "cffi-1.15.1-cp27-cp27m-win32.whl", hash = "sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3"},
-    {file = "cffi-1.15.1-cp27-cp27m-win_amd64.whl", hash = "sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e"},
-    {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162"},
-    {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b"},
-    {file = "cffi-1.15.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21"},
-    {file = "cffi-1.15.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185"},
-    {file = "cffi-1.15.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd"},
-    {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc"},
-    {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f"},
-    {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e"},
-    {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4"},
-    {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01"},
-    {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e"},
-    {file = "cffi-1.15.1-cp310-cp310-win32.whl", hash = "sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2"},
-    {file = "cffi-1.15.1-cp310-cp310-win_amd64.whl", hash = "sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d"},
-    {file = "cffi-1.15.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac"},
-    {file = "cffi-1.15.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83"},
-    {file = "cffi-1.15.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9"},
-    {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c"},
-    {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325"},
-    {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c"},
-    {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef"},
-    {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8"},
-    {file = "cffi-1.15.1-cp311-cp311-win32.whl", hash = "sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d"},
-    {file = "cffi-1.15.1-cp311-cp311-win_amd64.whl", hash = "sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104"},
-    {file = "cffi-1.15.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7"},
-    {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6"},
-    {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d"},
-    {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a"},
-    {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405"},
-    {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e"},
-    {file = "cffi-1.15.1-cp36-cp36m-win32.whl", hash = "sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf"},
-    {file = "cffi-1.15.1-cp36-cp36m-win_amd64.whl", hash = "sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497"},
-    {file = "cffi-1.15.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375"},
-    {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e"},
-    {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82"},
-    {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b"},
-    {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c"},
-    {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426"},
-    {file = "cffi-1.15.1-cp37-cp37m-win32.whl", hash = "sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9"},
-    {file = "cffi-1.15.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045"},
-    {file = "cffi-1.15.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3"},
-    {file = "cffi-1.15.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a"},
-    {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5"},
-    {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca"},
-    {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02"},
-    {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192"},
-    {file = "cffi-1.15.1-cp38-cp38-win32.whl", hash = "sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314"},
-    {file = "cffi-1.15.1-cp38-cp38-win_amd64.whl", hash = "sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5"},
-    {file = "cffi-1.15.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585"},
-    {file = "cffi-1.15.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0"},
-    {file = "cffi-1.15.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415"},
-    {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d"},
-    {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984"},
-    {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35"},
-    {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27"},
-    {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76"},
-    {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3"},
-    {file = "cffi-1.15.1-cp39-cp39-win32.whl", hash = "sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee"},
-    {file = "cffi-1.15.1-cp39-cp39-win_amd64.whl", hash = "sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c"},
-    {file = "cffi-1.15.1.tar.gz", hash = "sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9"},
-]
-charset-normalizer = [
-    {file = "charset-normalizer-2.1.0.tar.gz", hash = "sha256:575e708016ff3a5e3681541cb9d79312c416835686d054a23accb873b254f413"},
-    {file = "charset_normalizer-2.1.0-py3-none-any.whl", hash = "sha256:5189b6f22b01957427f35b6a08d9a0bc45b46d3788ef5a92e978433c7a35f8a5"},
-]
-click = [
-    {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"},
-    {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"},
-]
-clickclick = [
-    {file = "clickclick-20.10.2-py2.py3-none-any.whl", hash = "sha256:c8f33e6d9ec83f68416dd2136a7950125bd256ec39ccc9a85c6e280a16be2bb5"},
-    {file = "clickclick-20.10.2.tar.gz", hash = "sha256:4efb13e62353e34c5eef7ed6582c4920b418d7dedc86d819e22ee089ba01802c"},
-]
-colorama = [
-    {file = "colorama-0.4.5-py2.py3-none-any.whl", hash = "sha256:854bf444933e37f5824ae7bfc1e98d5bce2ebe4160d46b5edf346a89358e99da"},
-    {file = "colorama-0.4.5.tar.gz", hash = "sha256:e6c6b4334fc50988a639d9b98aa429a0b57da6e17b9a44f0451f930b6967b7a4"},
-]
-colorful = [
-    {file = "colorful-0.5.4-py2.py3-none-any.whl", hash = "sha256:8d264b52a39aae4c0ba3e2a46afbaec81b0559a99be0d2cfe2aba4cf94531348"},
-    {file = "colorful-0.5.4.tar.gz", hash = "sha256:86848ad4e2eda60cd2519d8698945d22f6f6551e23e95f3f14dfbb60997807ea"},
-]
-connexion = [
-    {file = "connexion-2.14.0-py2.py3-none-any.whl", hash = "sha256:4e50c1b0b6d287e20830d053c8de09a73bead5ac0760200ade074364c7362ab6"},
-    {file = "connexion-2.14.0.tar.gz", hash = "sha256:ed6f9c97ca5281257935c5530570b2a2394a689ece1b171c18d855cf751adbb4"},
-]
-debugpy = []
-decorator = [
-    {file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"},
-    {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"},
-]
-entrypoints = [
-    {file = "entrypoints-0.4-py3-none-any.whl", hash = "sha256:f174b5ff827504fd3cd97cc3f8649f3693f51538c7e4bdf3ef002c8429d42f9f"},
-    {file = "entrypoints-0.4.tar.gz", hash = "sha256:b706eddaa9218a19ebcd67b56818f05bb27589b1ca9e8d797b74affad4ccacd4"},
-]
-executing = []
-flask = []
-future-fstrings = [
-    {file = "future_fstrings-1.2.0-py2.py3-none-any.whl", hash = "sha256:90e49598b553d8746c4dc7d9442e0359d038c3039d802c91c0a55505da318c63"},
-    {file = "future_fstrings-1.2.0.tar.gz", hash = "sha256:6cf41cbe97c398ab5a81168ce0dbb8ad95862d3caf23c21e4430627b90844089"},
-]
-idna = [
-    {file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"},
-    {file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"},
-]
-importlib-metadata = [
-    {file = "importlib_metadata-4.12.0-py3-none-any.whl", hash = "sha256:7401a975809ea1fdc658c3aa4f78cc2195a0e019c5cbc4c06122884e9ae80c23"},
-    {file = "importlib_metadata-4.12.0.tar.gz", hash = "sha256:637245b8bab2b6502fcbc752cc4b7a6f6243bb02b31c5c26156ad103d3d45670"},
-]
-inflection = [
-    {file = "inflection-0.5.1-py2.py3-none-any.whl", hash = "sha256:f38b2b640938a4f35ade69ac3d053042959b62a0f1076a5bbaa1b9526605a8a2"},
-    {file = "inflection-0.5.1.tar.gz", hash = "sha256:1a29730d366e996aaacffb2f1f1cb9593dc38e2ddd30c91250c6dde09ea9b417"},
-]
-iniconfig = [
-    {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"},
-    {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"},
-]
-ipykernel = []
-ipython = [
-    {file = "ipython-8.4.0-py3-none-any.whl", hash = "sha256:7ca74052a38fa25fe9bedf52da0be7d3fdd2fb027c3b778ea78dfe8c212937d1"},
-    {file = "ipython-8.4.0.tar.gz", hash = "sha256:f2db3a10254241d9b447232cec8b424847f338d9d36f9a577a6192c332a46abd"},
-]
-itsdangerous = [
-    {file = "itsdangerous-2.1.2-py3-none-any.whl", hash = "sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44"},
-    {file = "itsdangerous-2.1.2.tar.gz", hash = "sha256:5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a"},
-]
-jedi = [
-    {file = "jedi-0.18.1-py2.py3-none-any.whl", hash = "sha256:637c9635fcf47945ceb91cd7f320234a7be540ded6f3e99a50cb6febdfd1ba8d"},
-    {file = "jedi-0.18.1.tar.gz", hash = "sha256:74137626a64a99c8eb6ae5832d99b3bdd7d29a3850fe2aa80a4126b2a7d949ab"},
-]
-jinja2 = [
-    {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"},
-    {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"},
-]
-joblib = []
-jsonschema = []
-jupyter-client = [
-    {file = "jupyter_client-7.3.4-py3-none-any.whl", hash = "sha256:17d74b0d0a7b24f1c8c527b24fcf4607c56bee542ffe8e3418e50b21e514b621"},
-    {file = "jupyter_client-7.3.4.tar.gz", hash = "sha256:aa9a6c32054b290374f95f73bb0cae91455c58dfb84f65c8591912b8f65e6d56"},
-]
-jupyter-core = []
-lxml = [
-    {file = "lxml-4.9.1-cp27-cp27m-macosx_10_15_x86_64.whl", hash = "sha256:98cafc618614d72b02185ac583c6f7796202062c41d2eeecdf07820bad3295ed"},
-    {file = "lxml-4.9.1-cp27-cp27m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c62e8dd9754b7debda0c5ba59d34509c4688f853588d75b53c3791983faa96fc"},
-    {file = "lxml-4.9.1-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:21fb3d24ab430fc538a96e9fbb9b150029914805d551deeac7d7822f64631dfc"},
-    {file = "lxml-4.9.1-cp27-cp27m-win32.whl", hash = "sha256:86e92728ef3fc842c50a5cb1d5ba2bc66db7da08a7af53fb3da79e202d1b2cd3"},
-    {file = "lxml-4.9.1-cp27-cp27m-win_amd64.whl", hash = "sha256:4cfbe42c686f33944e12f45a27d25a492cc0e43e1dc1da5d6a87cbcaf2e95627"},
-    {file = "lxml-4.9.1-cp27-cp27mu-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:dad7b164905d3e534883281c050180afcf1e230c3d4a54e8038aa5cfcf312b84"},
-    {file = "lxml-4.9.1-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:a614e4afed58c14254e67862456d212c4dcceebab2eaa44d627c2ca04bf86837"},
-    {file = "lxml-4.9.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:f9ced82717c7ec65a67667bb05865ffe38af0e835cdd78728f1209c8fffe0cad"},
-    {file = "lxml-4.9.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:d9fc0bf3ff86c17348dfc5d322f627d78273eba545db865c3cd14b3f19e57fa5"},
-    {file = "lxml-4.9.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:e5f66bdf0976ec667fc4594d2812a00b07ed14d1b44259d19a41ae3fff99f2b8"},
-    {file = "lxml-4.9.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:fe17d10b97fdf58155f858606bddb4e037b805a60ae023c009f760d8361a4eb8"},
-    {file = "lxml-4.9.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8caf4d16b31961e964c62194ea3e26a0e9561cdf72eecb1781458b67ec83423d"},
-    {file = "lxml-4.9.1-cp310-cp310-win32.whl", hash = "sha256:4780677767dd52b99f0af1f123bc2c22873d30b474aa0e2fc3fe5e02217687c7"},
-    {file = "lxml-4.9.1-cp310-cp310-win_amd64.whl", hash = "sha256:b122a188cd292c4d2fcd78d04f863b789ef43aa129b233d7c9004de08693728b"},
-    {file = "lxml-4.9.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:be9eb06489bc975c38706902cbc6888f39e946b81383abc2838d186f0e8b6a9d"},
-    {file = "lxml-4.9.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:f1be258c4d3dc609e654a1dc59d37b17d7fef05df912c01fc2e15eb43a9735f3"},
-    {file = "lxml-4.9.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:927a9dd016d6033bc12e0bf5dee1dde140235fc8d0d51099353c76081c03dc29"},
-    {file = "lxml-4.9.1-cp35-cp35m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9232b09f5efee6a495a99ae6824881940d6447debe272ea400c02e3b68aad85d"},
-    {file = "lxml-4.9.1-cp35-cp35m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:04da965dfebb5dac2619cb90fcf93efdb35b3c6994fea58a157a834f2f94b318"},
-    {file = "lxml-4.9.1-cp35-cp35m-win32.whl", hash = "sha256:4d5bae0a37af799207140652a700f21a85946f107a199bcb06720b13a4f1f0b7"},
-    {file = "lxml-4.9.1-cp35-cp35m-win_amd64.whl", hash = "sha256:4878e667ebabe9b65e785ac8da4d48886fe81193a84bbe49f12acff8f7a383a4"},
-    {file = "lxml-4.9.1-cp36-cp36m-macosx_10_15_x86_64.whl", hash = "sha256:1355755b62c28950f9ce123c7a41460ed9743c699905cbe664a5bcc5c9c7c7fb"},
-    {file = "lxml-4.9.1-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:bcaa1c495ce623966d9fc8a187da80082334236a2a1c7e141763ffaf7a405067"},
-    {file = "lxml-4.9.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6eafc048ea3f1b3c136c71a86db393be36b5b3d9c87b1c25204e7d397cee9536"},
-    {file = "lxml-4.9.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:13c90064b224e10c14dcdf8086688d3f0e612db53766e7478d7754703295c7c8"},
-    {file = "lxml-4.9.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:206a51077773c6c5d2ce1991327cda719063a47adc02bd703c56a662cdb6c58b"},
-    {file = "lxml-4.9.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:e8f0c9d65da595cfe91713bc1222af9ecabd37971762cb830dea2fc3b3bb2acf"},
-    {file = "lxml-4.9.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:8f0a4d179c9a941eb80c3a63cdb495e539e064f8054230844dcf2fcb812b71d3"},
-    {file = "lxml-4.9.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:830c88747dce8a3e7525defa68afd742b4580df6aa2fdd6f0855481e3994d391"},
-    {file = "lxml-4.9.1-cp36-cp36m-win32.whl", hash = "sha256:1e1cf47774373777936c5aabad489fef7b1c087dcd1f426b621fda9dcc12994e"},
-    {file = "lxml-4.9.1-cp36-cp36m-win_amd64.whl", hash = "sha256:5974895115737a74a00b321e339b9c3f45c20275d226398ae79ac008d908bff7"},
-    {file = "lxml-4.9.1-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:1423631e3d51008871299525b541413c9b6c6423593e89f9c4cfbe8460afc0a2"},
-    {file = "lxml-4.9.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:2aaf6a0a6465d39b5ca69688fce82d20088c1838534982996ec46633dc7ad6cc"},
-    {file = "lxml-4.9.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:9f36de4cd0c262dd9927886cc2305aa3f2210db437aa4fed3fb4940b8bf4592c"},
-    {file = "lxml-4.9.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:ae06c1e4bc60ee076292e582a7512f304abdf6c70db59b56745cca1684f875a4"},
-    {file = "lxml-4.9.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:57e4d637258703d14171b54203fd6822fda218c6c2658a7d30816b10995f29f3"},
-    {file = "lxml-4.9.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6d279033bf614953c3fc4a0aa9ac33a21e8044ca72d4fa8b9273fe75359d5cca"},
-    {file = "lxml-4.9.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:a60f90bba4c37962cbf210f0188ecca87daafdf60271f4c6948606e4dabf8785"},
-    {file = "lxml-4.9.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:6ca2264f341dd81e41f3fffecec6e446aa2121e0b8d026fb5130e02de1402785"},
-    {file = "lxml-4.9.1-cp37-cp37m-win32.whl", hash = "sha256:27e590352c76156f50f538dbcebd1925317a0f70540f7dc8c97d2931c595783a"},
-    {file = "lxml-4.9.1-cp37-cp37m-win_amd64.whl", hash = "sha256:eea5d6443b093e1545ad0210e6cf27f920482bfcf5c77cdc8596aec73523bb7e"},
-    {file = "lxml-4.9.1-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:f05251bbc2145349b8d0b77c0d4e5f3b228418807b1ee27cefb11f69ed3d233b"},
-    {file = "lxml-4.9.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:487c8e61d7acc50b8be82bda8c8d21d20e133c3cbf41bd8ad7eb1aaeb3f07c97"},
-    {file = "lxml-4.9.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:8d1a92d8e90b286d491e5626af53afef2ba04da33e82e30744795c71880eaa21"},
-    {file = "lxml-4.9.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:b570da8cd0012f4af9fa76a5635cd31f707473e65a5a335b186069d5c7121ff2"},
-    {file = "lxml-4.9.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5ef87fca280fb15342726bd5f980f6faf8b84a5287fcc2d4962ea8af88b35130"},
-    {file = "lxml-4.9.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:93e414e3206779ef41e5ff2448067213febf260ba747fc65389a3ddaa3fb8715"},
-    {file = "lxml-4.9.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6653071f4f9bac46fbc30f3c7838b0e9063ee335908c5d61fb7a4a86c8fd2036"},
-    {file = "lxml-4.9.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:32a73c53783becdb7eaf75a2a1525ea8e49379fb7248c3eeefb9412123536387"},
-    {file = "lxml-4.9.1-cp38-cp38-win32.whl", hash = "sha256:1a7c59c6ffd6ef5db362b798f350e24ab2cfa5700d53ac6681918f314a4d3b94"},
-    {file = "lxml-4.9.1-cp38-cp38-win_amd64.whl", hash = "sha256:1436cf0063bba7888e43f1ba8d58824f085410ea2025befe81150aceb123e345"},
-    {file = "lxml-4.9.1-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:4beea0f31491bc086991b97517b9683e5cfb369205dac0148ef685ac12a20a67"},
-    {file = "lxml-4.9.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:41fb58868b816c202e8881fd0f179a4644ce6e7cbbb248ef0283a34b73ec73bb"},
-    {file = "lxml-4.9.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:bd34f6d1810d9354dc7e35158aa6cc33456be7706df4420819af6ed966e85448"},
-    {file = "lxml-4.9.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:edffbe3c510d8f4bf8640e02ca019e48a9b72357318383ca60e3330c23aaffc7"},
-    {file = "lxml-4.9.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6d949f53ad4fc7cf02c44d6678e7ff05ec5f5552b235b9e136bd52e9bf730b91"},
-    {file = "lxml-4.9.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:079b68f197c796e42aa80b1f739f058dcee796dc725cc9a1be0cdb08fc45b000"},
-    {file = "lxml-4.9.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9c3a88d20e4fe4a2a4a84bf439a5ac9c9aba400b85244c63a1ab7088f85d9d25"},
-    {file = "lxml-4.9.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4e285b5f2bf321fc0857b491b5028c5f276ec0c873b985d58d7748ece1d770dd"},
-    {file = "lxml-4.9.1-cp39-cp39-win32.whl", hash = "sha256:ef72013e20dd5ba86a8ae1aed7f56f31d3374189aa8b433e7b12ad182c0d2dfb"},
-    {file = "lxml-4.9.1-cp39-cp39-win_amd64.whl", hash = "sha256:10d2017f9150248563bb579cd0d07c61c58da85c922b780060dcc9a3aa9f432d"},
-    {file = "lxml-4.9.1-pp37-pypy37_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0538747a9d7827ce3e16a8fdd201a99e661c7dee3c96c885d8ecba3c35d1032c"},
-    {file = "lxml-4.9.1-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:0645e934e940107e2fdbe7c5b6fb8ec6232444260752598bc4d09511bd056c0b"},
-    {file = "lxml-4.9.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:6daa662aba22ef3258934105be2dd9afa5bb45748f4f702a3b39a5bf53a1f4dc"},
-    {file = "lxml-4.9.1-pp38-pypy38_pp73-macosx_10_15_x86_64.whl", hash = "sha256:603a464c2e67d8a546ddaa206d98e3246e5db05594b97db844c2f0a1af37cf5b"},
-    {file = "lxml-4.9.1-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:c4b2e0559b68455c085fb0f6178e9752c4be3bba104d6e881eb5573b399d1eb2"},
-    {file = "lxml-4.9.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:0f3f0059891d3254c7b5fb935330d6db38d6519ecd238ca4fce93c234b4a0f73"},
-    {file = "lxml-4.9.1-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_24_i686.whl", hash = "sha256:c852b1530083a620cb0de5f3cd6826f19862bafeaf77586f1aef326e49d95f0c"},
-    {file = "lxml-4.9.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:287605bede6bd36e930577c5925fcea17cb30453d96a7b4c63c14a257118dbb9"},
-    {file = "lxml-4.9.1.tar.gz", hash = "sha256:fe749b052bb7233fe5d072fcb549221a8cb1a16725c47c37e42b0b9cb3ff2c3f"},
-]
-markupsafe = [
-    {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812"},
-    {file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a"},
-    {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a49907dd8420c5685cfa064a1335b6754b74541bbb3706c259c02ed65b644b3e"},
-    {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10c1bfff05d95783da83491be968e8fe789263689c02724e0c691933c52994f5"},
-    {file = "MarkupSafe-2.1.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7bd98b796e2b6553da7225aeb61f447f80a1ca64f41d83612e6139ca5213aa4"},
-    {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b09bf97215625a311f669476f44b8b318b075847b49316d3e28c08e41a7a573f"},
-    {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:694deca8d702d5db21ec83983ce0bb4b26a578e71fbdbd4fdcd387daa90e4d5e"},
-    {file = "MarkupSafe-2.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:efc1913fd2ca4f334418481c7e595c00aad186563bbc1ec76067848c7ca0a933"},
-    {file = "MarkupSafe-2.1.1-cp310-cp310-win32.whl", hash = "sha256:4a33dea2b688b3190ee12bd7cfa29d39c9ed176bda40bfa11099a3ce5d3a7ac6"},
-    {file = "MarkupSafe-2.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:dda30ba7e87fbbb7eab1ec9f58678558fd9a6b8b853530e176eabd064da81417"},
-    {file = "MarkupSafe-2.1.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:671cd1187ed5e62818414afe79ed29da836dde67166a9fac6d435873c44fdd02"},
-    {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3799351e2336dc91ea70b034983ee71cf2f9533cdff7c14c90ea126bfd95d65a"},
-    {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e72591e9ecd94d7feb70c1cbd7be7b3ebea3f548870aa91e2732960fa4d57a37"},
-    {file = "MarkupSafe-2.1.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6fbf47b5d3728c6aea2abb0589b5d30459e369baa772e0f37a0320185e87c980"},
-    {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d5ee4f386140395a2c818d149221149c54849dfcfcb9f1debfe07a8b8bd63f9a"},
-    {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:bcb3ed405ed3222f9904899563d6fc492ff75cce56cba05e32eff40e6acbeaa3"},
-    {file = "MarkupSafe-2.1.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e1c0b87e09fa55a220f058d1d49d3fb8df88fbfab58558f1198e08c1e1de842a"},
-    {file = "MarkupSafe-2.1.1-cp37-cp37m-win32.whl", hash = "sha256:8dc1c72a69aa7e082593c4a203dcf94ddb74bb5c8a731e4e1eb68d031e8498ff"},
-    {file = "MarkupSafe-2.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:97a68e6ada378df82bc9f16b800ab77cbf4b2fada0081794318520138c088e4a"},
-    {file = "MarkupSafe-2.1.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e8c843bbcda3a2f1e3c2ab25913c80a3c5376cd00c6e8c4a86a89a28c8dc5452"},
-    {file = "MarkupSafe-2.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0212a68688482dc52b2d45013df70d169f542b7394fc744c02a57374a4207003"},
-    {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e576a51ad59e4bfaac456023a78f6b5e6e7651dcd383bcc3e18d06f9b55d6d1"},
-    {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b9fe39a2ccc108a4accc2676e77da025ce383c108593d65cc909add5c3bd601"},
-    {file = "MarkupSafe-2.1.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:96e37a3dc86e80bf81758c152fe66dbf60ed5eca3d26305edf01892257049925"},
-    {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6d0072fea50feec76a4c418096652f2c3238eaa014b2f94aeb1d56a66b41403f"},
-    {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:089cf3dbf0cd6c100f02945abeb18484bd1ee57a079aefd52cffd17fba910b88"},
-    {file = "MarkupSafe-2.1.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6a074d34ee7a5ce3effbc526b7083ec9731bb3cbf921bbe1d3005d4d2bdb3a63"},
-    {file = "MarkupSafe-2.1.1-cp38-cp38-win32.whl", hash = "sha256:421be9fbf0ffe9ffd7a378aafebbf6f4602d564d34be190fc19a193232fd12b1"},
-    {file = "MarkupSafe-2.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:fc7b548b17d238737688817ab67deebb30e8073c95749d55538ed473130ec0c7"},
-    {file = "MarkupSafe-2.1.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e04e26803c9c3851c931eac40c695602c6295b8d432cbe78609649ad9bd2da8a"},
-    {file = "MarkupSafe-2.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b87db4360013327109564f0e591bd2a3b318547bcef31b468a92ee504d07ae4f"},
-    {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99a2a507ed3ac881b975a2976d59f38c19386d128e7a9a18b7df6fff1fd4c1d6"},
-    {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56442863ed2b06d19c37f94d999035e15ee982988920e12a5b4ba29b62ad1f77"},
-    {file = "MarkupSafe-2.1.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3ce11ee3f23f79dbd06fb3d63e2f6af7b12db1d46932fe7bd8afa259a5996603"},
-    {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:33b74d289bd2f5e527beadcaa3f401e0df0a89927c1559c8566c066fa4248ab7"},
-    {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:43093fb83d8343aac0b1baa75516da6092f58f41200907ef92448ecab8825135"},
-    {file = "MarkupSafe-2.1.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8e3dcf21f367459434c18e71b2a9532d96547aef8a871872a5bd69a715c15f96"},
-    {file = "MarkupSafe-2.1.1-cp39-cp39-win32.whl", hash = "sha256:d4306c36ca495956b6d568d276ac11fdd9c30a36f1b6eb928070dc5360b22e1c"},
-    {file = "MarkupSafe-2.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247"},
-    {file = "MarkupSafe-2.1.1.tar.gz", hash = "sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b"},
-]
-matplotlib-inline = [
-    {file = "matplotlib-inline-0.1.3.tar.gz", hash = "sha256:a04bfba22e0d1395479f866853ec1ee28eea1485c1d69a6faf00dc3e24ff34ee"},
-    {file = "matplotlib_inline-0.1.3-py3-none-any.whl", hash = "sha256:aed605ba3b72462d64d475a21a9296f400a19c4f74a31b59103d2a99ffd5aa5c"},
-]
-nest-asyncio = [
-    {file = "nest_asyncio-1.5.5-py3-none-any.whl", hash = "sha256:b98e3ec1b246135e4642eceffa5a6c23a3ab12c82ff816a92c612d68205813b2"},
-    {file = "nest_asyncio-1.5.5.tar.gz", hash = "sha256:e442291cd942698be619823a17a86a5759eabe1f8613084790de189fe9e16d65"},
-]
-networkx = []
-ordered-set = [
-    {file = "ordered-set-4.1.0.tar.gz", hash = "sha256:694a8e44c87657c59292ede72891eb91d34131f6531463aab3009191c77364a8"},
-    {file = "ordered_set-4.1.0-py3-none-any.whl", hash = "sha256:046e1132c71fcf3330438a539928932caf51ddbc582496833e23de611de14562"},
-]
-packaging = [
-    {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"},
-    {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"},
-]
-parso = [
-    {file = "parso-0.8.3-py2.py3-none-any.whl", hash = "sha256:c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75"},
-    {file = "parso-0.8.3.tar.gz", hash = "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0"},
-]
-pexpect = [
-    {file = "pexpect-4.8.0-py2.py3-none-any.whl", hash = "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937"},
-    {file = "pexpect-4.8.0.tar.gz", hash = "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c"},
-]
-pickleshare = [
-    {file = "pickleshare-0.7.5-py2.py3-none-any.whl", hash = "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56"},
-    {file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"},
-]
-pluggy = [
-    {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"},
-    {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"},
-]
-prettyprinter = [
-    {file = "prettyprinter-0.18.0-py2.py3-none-any.whl", hash = "sha256:358a58f276cb312e3ca29d7a7f244c91e4e0bda7848249d30e4f36d2eb58b67c"},
-    {file = "prettyprinter-0.18.0.tar.gz", hash = "sha256:9fe5da7ec53510881dd35d7a5c677ba45f34cfe6a8e78d1abd20652cf82139a8"},
-]
-prompt-toolkit = [
-    {file = "prompt_toolkit-3.0.30-py3-none-any.whl", hash = "sha256:d8916d3f62a7b67ab353a952ce4ced6a1d2587dfe9ef8ebc30dd7c386751f289"},
-    {file = "prompt_toolkit-3.0.30.tar.gz", hash = "sha256:859b283c50bde45f5f97829f77a4674d1c1fcd88539364f1b28a37805cfd89c0"},
-]
-psutil = [
-    {file = "psutil-5.9.1-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:799759d809c31aab5fe4579e50addf84565e71c1dc9f1c31258f159ff70d3f87"},
-    {file = "psutil-5.9.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:9272167b5f5fbfe16945be3db475b3ce8d792386907e673a209da686176552af"},
-    {file = "psutil-5.9.1-cp27-cp27m-win32.whl", hash = "sha256:0904727e0b0a038830b019551cf3204dd48ef5c6868adc776e06e93d615fc5fc"},
-    {file = "psutil-5.9.1-cp27-cp27m-win_amd64.whl", hash = "sha256:e7e10454cb1ab62cc6ce776e1c135a64045a11ec4c6d254d3f7689c16eb3efd2"},
-    {file = "psutil-5.9.1-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:56960b9e8edcca1456f8c86a196f0c3d8e3e361320071c93378d41445ffd28b0"},
-    {file = "psutil-5.9.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:44d1826150d49ffd62035785a9e2c56afcea66e55b43b8b630d7706276e87f22"},
-    {file = "psutil-5.9.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c7be9d7f5b0d206f0bbc3794b8e16fb7dbc53ec9e40bbe8787c6f2d38efcf6c9"},
-    {file = "psutil-5.9.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abd9246e4cdd5b554a2ddd97c157e292ac11ef3e7af25ac56b08b455c829dca8"},
-    {file = "psutil-5.9.1-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:29a442e25fab1f4d05e2655bb1b8ab6887981838d22effa2396d584b740194de"},
-    {file = "psutil-5.9.1-cp310-cp310-win32.whl", hash = "sha256:20b27771b077dcaa0de1de3ad52d22538fe101f9946d6dc7869e6f694f079329"},
-    {file = "psutil-5.9.1-cp310-cp310-win_amd64.whl", hash = "sha256:58678bbadae12e0db55186dc58f2888839228ac9f41cc7848853539b70490021"},
-    {file = "psutil-5.9.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:3a76ad658641172d9c6e593de6fe248ddde825b5866464c3b2ee26c35da9d237"},
-    {file = "psutil-5.9.1-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a6a11e48cb93a5fa606306493f439b4aa7c56cb03fc9ace7f6bfa21aaf07c453"},
-    {file = "psutil-5.9.1-cp36-cp36m-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:068935df39055bf27a29824b95c801c7a5130f118b806eee663cad28dca97685"},
-    {file = "psutil-5.9.1-cp36-cp36m-win32.whl", hash = "sha256:0f15a19a05f39a09327345bc279c1ba4a8cfb0172cc0d3c7f7d16c813b2e7d36"},
-    {file = "psutil-5.9.1-cp36-cp36m-win_amd64.whl", hash = "sha256:db417f0865f90bdc07fa30e1aadc69b6f4cad7f86324b02aa842034efe8d8c4d"},
-    {file = "psutil-5.9.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:91c7ff2a40c373d0cc9121d54bc5f31c4fa09c346528e6a08d1845bce5771ffc"},
-    {file = "psutil-5.9.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fea896b54f3a4ae6f790ac1d017101252c93f6fe075d0e7571543510f11d2676"},
-    {file = "psutil-5.9.1-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3054e923204b8e9c23a55b23b6df73a8089ae1d075cb0bf711d3e9da1724ded4"},
-    {file = "psutil-5.9.1-cp37-cp37m-win32.whl", hash = "sha256:d2d006286fbcb60f0b391741f520862e9b69f4019b4d738a2a45728c7e952f1b"},
-    {file = "psutil-5.9.1-cp37-cp37m-win_amd64.whl", hash = "sha256:b14ee12da9338f5e5b3a3ef7ca58b3cba30f5b66f7662159762932e6d0b8f680"},
-    {file = "psutil-5.9.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:19f36c16012ba9cfc742604df189f2f28d2720e23ff7d1e81602dbe066be9fd1"},
-    {file = "psutil-5.9.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:944c4b4b82dc4a1b805329c980f270f170fdc9945464223f2ec8e57563139cf4"},
-    {file = "psutil-5.9.1-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b6750a73a9c4a4e689490ccb862d53c7b976a2a35c4e1846d049dcc3f17d83b"},
-    {file = "psutil-5.9.1-cp38-cp38-win32.whl", hash = "sha256:a8746bfe4e8f659528c5c7e9af5090c5a7d252f32b2e859c584ef7d8efb1e689"},
-    {file = "psutil-5.9.1-cp38-cp38-win_amd64.whl", hash = "sha256:79c9108d9aa7fa6fba6e668b61b82facc067a6b81517cab34d07a84aa89f3df0"},
-    {file = "psutil-5.9.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:28976df6c64ddd6320d281128817f32c29b539a52bdae5e192537bc338a9ec81"},
-    {file = "psutil-5.9.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b88f75005586131276634027f4219d06e0561292be8bd6bc7f2f00bdabd63c4e"},
-    {file = "psutil-5.9.1-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:645bd4f7bb5b8633803e0b6746ff1628724668681a434482546887d22c7a9537"},
-    {file = "psutil-5.9.1-cp39-cp39-win32.whl", hash = "sha256:32c52611756096ae91f5d1499fe6c53b86f4a9ada147ee42db4991ba1520e574"},
-    {file = "psutil-5.9.1-cp39-cp39-win_amd64.whl", hash = "sha256:f65f9a46d984b8cd9b3750c2bdb419b2996895b005aefa6cbaba9a143b1ce2c5"},
-    {file = "psutil-5.9.1.tar.gz", hash = "sha256:57f1819b5d9e95cdfb0c881a8a5b7d542ed0b7c522d575706a80bedc848c8954"},
-]
-ptyprocess = [
-    {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"},
-    {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"},
-]
-pure-eval = [
-    {file = "pure_eval-0.2.2-py3-none-any.whl", hash = "sha256:01eaab343580944bc56080ebe0a674b39ec44a945e6d09ba7db3cb8cec289350"},
-    {file = "pure_eval-0.2.2.tar.gz", hash = "sha256:2b45320af6dfaa1750f543d714b6d1c520a1688dec6fd24d339063ce0aaa9ac3"},
-]
-py = [
-    {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"},
-    {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"},
-]
-pycparser = [
-    {file = "pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"},
-    {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"},
-]
-pyecore = [
-    {file = "pyecore-0.12.2-py3-none-any.whl", hash = "sha256:8ebbefea2fcb97602ddb9eb859ae15d7c0900231128da92e10b7f9a9e1a29b76"},
-    {file = "pyecore-0.12.2.tar.gz", hash = "sha256:4fb417df37fc5433da37f3d42724f7c4cc36cbbe63988f3e43ad7653e0808387"},
-]
-pygments = [
-    {file = "Pygments-2.12.0-py3-none-any.whl", hash = "sha256:dc9c10fb40944260f6ed4c688ece0cd2048414940f1cea51b8b226318411c519"},
-    {file = "Pygments-2.12.0.tar.gz", hash = "sha256:5eb116118f9612ff1ee89ac96437bb6b49e8f04d8a13b514ba26f620208e26eb"},
-]
-pyparsing = [
-    {file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"},
-    {file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"},
-]
-pyrsistent = [
-    {file = "pyrsistent-0.18.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:df46c854f490f81210870e509818b729db4488e1f30f2a1ce1698b2295a878d1"},
-    {file = "pyrsistent-0.18.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d45866ececf4a5fff8742c25722da6d4c9e180daa7b405dc0a2a2790d668c26"},
-    {file = "pyrsistent-0.18.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4ed6784ceac462a7d6fcb7e9b663e93b9a6fb373b7f43594f9ff68875788e01e"},
-    {file = "pyrsistent-0.18.1-cp310-cp310-win32.whl", hash = "sha256:e4f3149fd5eb9b285d6bfb54d2e5173f6a116fe19172686797c056672689daf6"},
-    {file = "pyrsistent-0.18.1-cp310-cp310-win_amd64.whl", hash = "sha256:636ce2dc235046ccd3d8c56a7ad54e99d5c1cd0ef07d9ae847306c91d11b5fec"},
-    {file = "pyrsistent-0.18.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e92a52c166426efbe0d1ec1332ee9119b6d32fc1f0bbfd55d5c1088070e7fc1b"},
-    {file = "pyrsistent-0.18.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7a096646eab884bf8bed965bad63ea327e0d0c38989fc83c5ea7b8a87037bfc"},
-    {file = "pyrsistent-0.18.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cdfd2c361b8a8e5d9499b9082b501c452ade8bbf42aef97ea04854f4a3f43b22"},
-    {file = "pyrsistent-0.18.1-cp37-cp37m-win32.whl", hash = "sha256:7ec335fc998faa4febe75cc5268a9eac0478b3f681602c1f27befaf2a1abe1d8"},
-    {file = "pyrsistent-0.18.1-cp37-cp37m-win_amd64.whl", hash = "sha256:6455fc599df93d1f60e1c5c4fe471499f08d190d57eca040c0ea182301321286"},
-    {file = "pyrsistent-0.18.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:fd8da6d0124efa2f67d86fa70c851022f87c98e205f0594e1fae044e7119a5a6"},
-    {file = "pyrsistent-0.18.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7bfe2388663fd18bd8ce7db2c91c7400bf3e1a9e8bd7d63bf7e77d39051b85ec"},
-    {file = "pyrsistent-0.18.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e3e1fcc45199df76053026a51cc59ab2ea3fc7c094c6627e93b7b44cdae2c8c"},
-    {file = "pyrsistent-0.18.1-cp38-cp38-win32.whl", hash = "sha256:b568f35ad53a7b07ed9b1b2bae09eb15cdd671a5ba5d2c66caee40dbf91c68ca"},
-    {file = "pyrsistent-0.18.1-cp38-cp38-win_amd64.whl", hash = "sha256:d1b96547410f76078eaf66d282ddca2e4baae8964364abb4f4dcdde855cd123a"},
-    {file = "pyrsistent-0.18.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f87cc2863ef33c709e237d4b5f4502a62a00fab450c9e020892e8e2ede5847f5"},
-    {file = "pyrsistent-0.18.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bc66318fb7ee012071b2792024564973ecc80e9522842eb4e17743604b5e045"},
-    {file = "pyrsistent-0.18.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:914474c9f1d93080338ace89cb2acee74f4f666fb0424896fcfb8d86058bf17c"},
-    {file = "pyrsistent-0.18.1-cp39-cp39-win32.whl", hash = "sha256:1b34eedd6812bf4d33814fca1b66005805d3640ce53140ab8bbb1e2651b0d9bc"},
-    {file = "pyrsistent-0.18.1-cp39-cp39-win_amd64.whl", hash = "sha256:e24a828f57e0c337c8d8bb9f6b12f09dfdf0273da25fda9e314f0b684b415a07"},
-    {file = "pyrsistent-0.18.1.tar.gz", hash = "sha256:d4d61f8b993a7255ba714df3aca52700f8125289f84f704cf80916517c46eb96"},
-]
-pytest = [
-    {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"},
-    {file = "pytest-6.2.5.tar.gz", hash = "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89"},
-]
-python-dateutil = [
-    {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"},
-    {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"},
-]
-pywin32 = [
-    {file = "pywin32-304-cp310-cp310-win32.whl", hash = "sha256:3c7bacf5e24298c86314f03fa20e16558a4e4138fc34615d7de4070c23e65af3"},
-    {file = "pywin32-304-cp310-cp310-win_amd64.whl", hash = "sha256:4f32145913a2447736dad62495199a8e280a77a0ca662daa2332acf849f0be48"},
-    {file = "pywin32-304-cp310-cp310-win_arm64.whl", hash = "sha256:d3ee45adff48e0551d1aa60d2ec066fec006083b791f5c3527c40cd8aefac71f"},
-    {file = "pywin32-304-cp311-cp311-win32.whl", hash = "sha256:30c53d6ce44c12a316a06c153ea74152d3b1342610f1b99d40ba2795e5af0269"},
-    {file = "pywin32-304-cp311-cp311-win_amd64.whl", hash = "sha256:7ffa0c0fa4ae4077e8b8aa73800540ef8c24530057768c3ac57c609f99a14fd4"},
-    {file = "pywin32-304-cp311-cp311-win_arm64.whl", hash = "sha256:cbbe34dad39bdbaa2889a424d28752f1b4971939b14b1bb48cbf0182a3bcfc43"},
-    {file = "pywin32-304-cp36-cp36m-win32.whl", hash = "sha256:be253e7b14bc601718f014d2832e4c18a5b023cbe72db826da63df76b77507a1"},
-    {file = "pywin32-304-cp36-cp36m-win_amd64.whl", hash = "sha256:de9827c23321dcf43d2f288f09f3b6d772fee11e809015bdae9e69fe13213988"},
-    {file = "pywin32-304-cp37-cp37m-win32.whl", hash = "sha256:f64c0377cf01b61bd5e76c25e1480ca8ab3b73f0c4add50538d332afdf8f69c5"},
-    {file = "pywin32-304-cp37-cp37m-win_amd64.whl", hash = "sha256:bb2ea2aa81e96eee6a6b79d87e1d1648d3f8b87f9a64499e0b92b30d141e76df"},
-    {file = "pywin32-304-cp38-cp38-win32.whl", hash = "sha256:94037b5259701988954931333aafd39cf897e990852115656b014ce72e052e96"},
-    {file = "pywin32-304-cp38-cp38-win_amd64.whl", hash = "sha256:ead865a2e179b30fb717831f73cf4373401fc62fbc3455a0889a7ddac848f83e"},
-    {file = "pywin32-304-cp39-cp39-win32.whl", hash = "sha256:25746d841201fd9f96b648a248f731c1dec851c9a08b8e33da8b56148e4c65cc"},
-    {file = "pywin32-304-cp39-cp39-win_amd64.whl", hash = "sha256:d24a3382f013b21aa24a5cfbfad5a2cd9926610c0affde3e8ab5b3d7dbcf4ac9"},
-]
-pyyaml = [
-    {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"},
-    {file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"},
-    {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc"},
-    {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b"},
-    {file = "PyYAML-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"},
-    {file = "PyYAML-6.0-cp310-cp310-win32.whl", hash = "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513"},
-    {file = "PyYAML-6.0-cp310-cp310-win_amd64.whl", hash = "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a"},
-    {file = "PyYAML-6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86"},
-    {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f"},
-    {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92"},
-    {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4"},
-    {file = "PyYAML-6.0-cp36-cp36m-win32.whl", hash = "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293"},
-    {file = "PyYAML-6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57"},
-    {file = "PyYAML-6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c"},
-    {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0"},
-    {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4"},
-    {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9"},
-    {file = "PyYAML-6.0-cp37-cp37m-win32.whl", hash = "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737"},
-    {file = "PyYAML-6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d"},
-    {file = "PyYAML-6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b"},
-    {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba"},
-    {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34"},
-    {file = "PyYAML-6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287"},
-    {file = "PyYAML-6.0-cp38-cp38-win32.whl", hash = "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78"},
-    {file = "PyYAML-6.0-cp38-cp38-win_amd64.whl", hash = "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07"},
-    {file = "PyYAML-6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b"},
-    {file = "PyYAML-6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174"},
-    {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803"},
-    {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3"},
-    {file = "PyYAML-6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0"},
-    {file = "PyYAML-6.0-cp39-cp39-win32.whl", hash = "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb"},
-    {file = "PyYAML-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c"},
-    {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"},
-]
-pyzmq = [
-    {file = "pyzmq-23.2.0-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:22ac0243a41798e3eb5d5714b28c2f28e3d10792dffbc8a5fca092f975fdeceb"},
-    {file = "pyzmq-23.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f685003d836ad0e5d4f08d1e024ee3ac7816eb2f873b2266306eef858f058133"},
-    {file = "pyzmq-23.2.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:d4651de7316ec8560afe430fb042c0782ed8ac54c0be43a515944d7c78fddac8"},
-    {file = "pyzmq-23.2.0-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:bcc6953e47bcfc9028ddf9ab2a321a3c51d7cc969db65edec092019bb837959f"},
-    {file = "pyzmq-23.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e08671dc202a1880fa522f921f35ca5925ba30da8bc96228d74a8f0643ead9c"},
-    {file = "pyzmq-23.2.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:de727ea906033b30527b4a99498f19aca3f4d1073230a958679a5b726e2784e0"},
-    {file = "pyzmq-23.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5aa9da520e4bb8cee8189f2f541701405e7690745094ded7a37b425d60527ea"},
-    {file = "pyzmq-23.2.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:f3ff6abde52e702397949054cb5b06c1c75b5d6542f6a2ce029e46f71ffbbbf2"},
-    {file = "pyzmq-23.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e2e2db5c6ef376e97c912733dfc24406f5949474d03e800d5f07b6aca4d870af"},
-    {file = "pyzmq-23.2.0-cp310-cp310-win32.whl", hash = "sha256:e669913cb2179507628419ec4f0e453e48ce6f924de5884d396f18c31836089c"},
-    {file = "pyzmq-23.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:a3dc339f7bc185d5fd0fd976242a5baf35de404d467e056484def8a4dd95868b"},
-    {file = "pyzmq-23.2.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:30c365e60c39c53f8eea042b37ea28304ffa6558fb7241cf278745095a5757da"},
-    {file = "pyzmq-23.2.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c2d8b69a2bf239ae3d987537bf3fbc2b044a405394cf4c258fc684971dd48b2"},
-    {file = "pyzmq-23.2.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:602835e5672ca9ca1d78e6c148fb28c4f91b748ebc41fbd2f479d8763d58bc9b"},
-    {file = "pyzmq-23.2.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:831da96ba3f36cc892f0afbb4fb89b28b61b387261676e55d55a682addbd29f7"},
-    {file = "pyzmq-23.2.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:c8dec8a2f3f0bb462e6439df436cd8c7ec37968e90b4209ac621e7fbc0ed3b00"},
-    {file = "pyzmq-23.2.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:814e5aaf0c3be9991a59066eafb2d6e117aed6b413e3e7e9be45d4e55f5e2748"},
-    {file = "pyzmq-23.2.0-cp36-cp36m-win32.whl", hash = "sha256:8496a2a5efd055c61ac2c6a18116c768a25c644b6747dcfde43e91620ab3453c"},
-    {file = "pyzmq-23.2.0-cp36-cp36m-win_amd64.whl", hash = "sha256:60746a7e8558655420a69441c0a1d47ed225ed3ac355920b96a96d0554ef7e6b"},
-    {file = "pyzmq-23.2.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5cb642e94337b0c76c9c8cb9bfb0f8a78654575847d080d3e1504f312d691fc3"},
-    {file = "pyzmq-23.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:444f7d615d5f686d0ef508b9edfa8a286e6d89f449a1ba37b60ef69d869220a3"},
-    {file = "pyzmq-23.2.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c9638e0057e3f1a8b7c5ce33c7575349d9183a033a19b5676ad55096ae36820b"},
-    {file = "pyzmq-23.2.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:004a431dfa0459123e6f4660d7e3c4ac19217d134ca38bacfffb2e78716fe944"},
-    {file = "pyzmq-23.2.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:5592fb4316f895922b1cacb91b04a0fa09d6f6f19bbab4442b4d0a0825177b93"},
-    {file = "pyzmq-23.2.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:c0a5f987d73fd9b46c3d180891f829afda714ab6bab30a1218724d4a0a63afd8"},
-    {file = "pyzmq-23.2.0-cp37-cp37m-win32.whl", hash = "sha256:d11628212fd731b8986f1561d9bb3f8c38d9c15b330c3d8a88963519fbcd553b"},
-    {file = "pyzmq-23.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:558f5f636e3e65f261b64925e8b190e8689e334911595394572cc7523879006d"},
-    {file = "pyzmq-23.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:61b97f624da42813f74977425a3a6144d604ea21cf065616d36ea3a866d92c1c"},
-    {file = "pyzmq-23.2.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:693c96ae4d975eb8efa1639670e9b1fac0c3f98b7845b65c0f369141fb4bb21f"},
-    {file = "pyzmq-23.2.0-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2b054525c9f7e240562185bf21671ca16d56bde92e9bd0f822c07dec7626b704"},
-    {file = "pyzmq-23.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:859059caf564f0c9398c9005278055ed3d37af4d73de6b1597821193b04ca09b"},
-    {file = "pyzmq-23.2.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8355744fdbdeac5cfadfa4f38b82029b5f2b8cab7472a33453a217a7f3a9dce2"},
-    {file = "pyzmq-23.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:420b9abd1a7330687a095373b8280a20cdee04342fbc8ccb3b56d9ec8efd4e62"},
-    {file = "pyzmq-23.2.0-cp38-cp38-win32.whl", hash = "sha256:59928dfebe93cf1e203e3cb0fd5d5dd384da56b99c8305f2e1b0a933751710f6"},
-    {file = "pyzmq-23.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:c882f1d4f96fbd807e92c334251d8ebd159a1ef89059ccd386ddea83fdb91bd8"},
-    {file = "pyzmq-23.2.0-cp39-cp39-macosx_10_15_universal2.whl", hash = "sha256:ced12075cdf3c7332ecc1960f77f7439d5ebb8ea20bbd3c34c8299e694f1b0a1"},
-    {file = "pyzmq-23.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3a4d87342c2737fbb9eee5c33c792db27b36b04957b4e6b7edd73a5b239a2a13"},
-    {file = "pyzmq-23.2.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:99cedf38eaddf263cf7e2a50e405f12c02cedf6d9df00a0d9c5d7b9417b57f76"},
-    {file = "pyzmq-23.2.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d1610260cc672975723fcf7705c69a95f3b88802a594c9867781bedd9b13422c"},
-    {file = "pyzmq-23.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c223a13555444707a0a7ebc6f9ee63053147c8c082bd1a31fd1207a03e8b0500"},
-    {file = "pyzmq-23.2.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f5fdb00d65ec44b10cc6b9b6318ef1363b81647a4aa3270ca39565eadb2d1201"},
-    {file = "pyzmq-23.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:984b232802eddf9f0be264a4d57a10b3a1fd7319df14ee6fc7b41c6d155a3e6c"},
-    {file = "pyzmq-23.2.0-cp39-cp39-win32.whl", hash = "sha256:f146648941cadaaaf01254a75651a23c08159d009d36c5af42a7cc200a5e53ec"},
-    {file = "pyzmq-23.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:83005d8928f8a5cebcfb33af3bfb84b1ad65d882b899141a331cc5d07d89f093"},
-    {file = "pyzmq-23.2.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:fee86542dc4ee8229e023003e3939b4d58cc2453922cf127778b69505fc9064b"},
-    {file = "pyzmq-23.2.0-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5d57542429df6acff02ff022067aa75b677603cee70e3abb9742787545eec966"},
-    {file = "pyzmq-23.2.0-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:057b154471e096e2dda147f7b057041acc303bb7ca4aa24c3b88c6cecdd78717"},
-    {file = "pyzmq-23.2.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:5d92e7cbeab7f70b08cc0f27255b0bb2500afc30f31075bca0b1cb87735d186c"},
-    {file = "pyzmq-23.2.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:eb4a573a8499685d62545e806d8fd143c84ac8b3439f925cd92c8763f0ed9bd7"},
-    {file = "pyzmq-23.2.0-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:da338e2728410d74ddeb1479ec67cfba73311607037455a40f92b6f5c62bf11d"},
-    {file = "pyzmq-23.2.0-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1b2a21f595f8cc549abd6c8de1fcd34c83441e35fb24b8a59bf161889c62a486"},
-    {file = "pyzmq-23.2.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:8c0f4d6f8c985bab83792be26ff3233940ba42e22237610ac50cbcfc10a5c235"},
-    {file = "pyzmq-23.2.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:bbabd1df23bf63ae829e81200034c0e433499275a6ed29ca1a912ea7629426d9"},
-    {file = "pyzmq-23.2.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:21552624ce69e69f7924f413b802b1fb554f4c0497f837810e429faa1cd4f163"},
-    {file = "pyzmq-23.2.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c616893a577e9d6773a3836732fd7e2a729157a108b8fccd31c87512fa01671a"},
-    {file = "pyzmq-23.2.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:ce4f71e17fa849de41a06109030d3f6815fcc33338bf98dd0dde6d456d33c929"},
-    {file = "pyzmq-23.2.0.tar.gz", hash = "sha256:a51f12a8719aad9dcfb55d456022f16b90abc8dde7d3ca93ce3120b40e3fa169"},
-]
-requests = [
-    {file = "requests-2.28.1-py3-none-any.whl", hash = "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349"},
-    {file = "requests-2.28.1.tar.gz", hash = "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983"},
-]
-restrictedpython = [
-    {file = "RestrictedPython-5.0-py2.py3-none-any.whl", hash = "sha256:9bd69505147b0ff8c68f4ff5a275975a3ab66fc43cbf3b61a195650ed767cd4e"},
-    {file = "RestrictedPython-5.0.tar.gz", hash = "sha256:a080569bffdf53371ae3e754ab1732f43054b1bab904fc100f74ba68ac731abc"},
-]
-six = [
-    {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
-    {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
-]
-stack-data = [
-    {file = "stack_data-0.3.0-py3-none-any.whl", hash = "sha256:aa1d52d14d09c7a9a12bb740e6bdfffe0f5e8f4f9218d85e7c73a8c37f7ae38d"},
-    {file = "stack_data-0.3.0.tar.gz", hash = "sha256:77bec1402dcd0987e9022326473fdbcc767304892a533ed8c29888dacb7dddbc"},
-]
-swagger-ui-bundle = [
-    {file = "swagger_ui_bundle-0.0.9-py3-none-any.whl", hash = "sha256:cea116ed81147c345001027325c1ddc9ca78c1ee7319935c3c75d3669279d575"},
-    {file = "swagger_ui_bundle-0.0.9.tar.gz", hash = "sha256:b462aa1460261796ab78fd4663961a7f6f347ce01760f1303bbbdf630f11f516"},
-]
-toml = [
-    {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"},
-    {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"},
-]
-tornado = [
-    {file = "tornado-6.2-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:20f638fd8cc85f3cbae3c732326e96addff0a15e22d80f049e00121651e82e72"},
-    {file = "tornado-6.2-cp37-abi3-macosx_10_9_x86_64.whl", hash = "sha256:87dcafae3e884462f90c90ecc200defe5e580a7fbbb4365eda7c7c1eb809ebc9"},
-    {file = "tornado-6.2-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba09ef14ca9893954244fd872798b4ccb2367c165946ce2dd7376aebdde8e3ac"},
-    {file = "tornado-6.2-cp37-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b8150f721c101abdef99073bf66d3903e292d851bee51910839831caba341a75"},
-    {file = "tornado-6.2-cp37-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3a2f5999215a3a06a4fc218026cd84c61b8b2b40ac5296a6db1f1451ef04c1e"},
-    {file = "tornado-6.2-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:5f8c52d219d4995388119af7ccaa0bcec289535747620116a58d830e7c25d8a8"},
-    {file = "tornado-6.2-cp37-abi3-musllinux_1_1_i686.whl", hash = "sha256:6fdfabffd8dfcb6cf887428849d30cf19a3ea34c2c248461e1f7d718ad30b66b"},
-    {file = "tornado-6.2-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:1d54d13ab8414ed44de07efecb97d4ef7c39f7438cf5e976ccd356bebb1b5fca"},
-    {file = "tornado-6.2-cp37-abi3-win32.whl", hash = "sha256:5c87076709343557ef8032934ce5f637dbb552efa7b21d08e89ae7619ed0eb23"},
-    {file = "tornado-6.2-cp37-abi3-win_amd64.whl", hash = "sha256:e5f923aa6a47e133d1cf87d60700889d7eae68988704e20c75fb2d65677a8e4b"},
-    {file = "tornado-6.2.tar.gz", hash = "sha256:9b630419bde84ec666bfd7ea0a4cb2a8a651c2d5cccdbdd1972a0c859dfc3c13"},
-]
-traitlets = [
-    {file = "traitlets-5.3.0-py3-none-any.whl", hash = "sha256:65fa18961659635933100db8ca120ef6220555286949774b9cfc106f941d1c7a"},
-    {file = "traitlets-5.3.0.tar.gz", hash = "sha256:0bb9f1f9f017aa8ec187d8b1b2a7a6626a2a1d877116baba52a129bfa124f8e2"},
-]
-urllib3 = []
-uwsgi = [
-    {file = "uwsgi-2.0.20.tar.gz", hash = "sha256:88ab9867d8973d8ae84719cf233b7dafc54326fcaec89683c3f9f77c002cdff9"},
-]
-wcwidth = [
-    {file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"},
-    {file = "wcwidth-0.2.5.tar.gz", hash = "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"},
-]
-werkzeug = []
-z3-solver = []
-zipp = []
diff --git a/pyproject.toml b/pyproject.toml
deleted file mode 100644
index bbde285695f94094f7b8e21a36da55253d4751a4..0000000000000000000000000000000000000000
--- a/pyproject.toml
+++ /dev/null
@@ -1,26 +0,0 @@
-[tool.poetry]
-name = "mc_openapi"
-version = "0.2.0"
-description = "OpenAPI interface for the PIACERE DOML model checker."
-authors = ["Michele Chiari <michele.chiari@polimi.it>", "Michele De Pascalis <michele.de.pascalis.1024@gmail.com>"]
-license = "Apache-2.0"
-
-[tool.poetry.dependencies]
-python = "^3.9"
-connexion = {extras = ["swagger-ui"], version = "^2.9.0"}
-uWSGI = "^2.0.20"
-pyecore = "^0.12.2"
-z3-solver = "^4.8.15"
-PyYAML = "^6.0"
-networkx = "^2.7.1"
-joblib = "^1.1.0"
-
-[tool.poetry.dev-dependencies]
-pytest = "^6.0"
-requests = "^2.26.0"
-ipykernel = "^6.12.1"
-prettyprinter = "^0.18.0"
-
-[build-system]
-requires = ["poetry-core>=1.0.0"]
-build-backend = "poetry.core.masonry.api"
diff --git a/requirements.txt b/requirements.txt
index 220b8df2bcb3d25822ef6588b4a910b781b6d11c..b8a42a33b7b0df313a84955baedf2d41047d749e 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,33 +1,15 @@
-attrs==22.1.0; python_version >= "3.7"
-certifi==2022.6.15; python_version >= "3.7" and python_version < "4"
-charset-normalizer==2.1.0; python_version >= "3.7" and python_version < "4" and python_full_version >= "3.6.0"
-click==8.1.3; python_version >= "3.7"
-clickclick==20.10.2; python_version >= "3.6"
-colorama==0.4.5; python_version >= "3.7" and python_full_version < "3.0.0" and platform_system == "Windows" or platform_system == "Windows" and python_version >= "3.7" and python_full_version >= "3.5.0"
-connexion==2.14.0; python_version >= "3.6"
-flask==2.1.3; python_version >= "3.7"
-future-fstrings==1.2.0; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.4.0"
-idna==3.3; python_version >= "3.7" and python_version < "4"
-importlib-metadata==4.12.0; python_version < "3.10" and python_version >= "3.7"
-inflection==0.5.1; python_version >= "3.6"
-itsdangerous==2.1.2; python_version >= "3.7"
-jinja2==3.1.2; python_version >= "3.7"
-joblib==1.1.0; python_version >= "3.6"
-jsonschema==4.8.0; python_version >= "3.7"
-lxml==4.9.1; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0"
-markupsafe==2.1.1; python_version >= "3.7"
-networkx==2.8.5; python_version >= "3.8"
-ordered-set==4.1.0; python_version >= "3.7"
-packaging==21.3; python_version >= "3.6"
-pyecore==0.12.2
-pyparsing==3.0.9; python_full_version >= "3.6.8" and python_version >= "3.6"
-pyrsistent==0.18.1; python_version >= "3.7"
-pyyaml==6.0; python_version >= "3.6"
-requests==2.28.1; python_version >= "3.7" and python_version < "4"
-restrictedpython==5.0
-swagger-ui-bundle==0.0.9; python_version >= "3.6"
-urllib3==1.26.11; python_version >= "3.7" and python_full_version < "3.0.0" and python_version < "4" or python_full_version >= "3.6.0" and python_version < "4" and python_version >= "3.7"
-uwsgi==2.0.20
-werkzeug==2.2.1; python_version >= "3.7"
-z3-solver==4.10.2.0
-zipp==3.8.1; python_version < "3.10" and python_version >= "3.7"
+tabulate
+fastapi
+joblib
+z3-solver==4.11.* # Else it deadlocks the MC somehow
+networkx
+lxml
+pyecore
+piacere-doml-synthesis
+lark
+uvicorn[standard]
+pytest
+pytest-xdist
+pytest-subtests
+jinja2
+requests
diff --git a/tests/doml/CaseStudies/SIMPA_Validation_v2.doml b/tests/doml/CaseStudies/SIMPA_Validation_v2.doml
new file mode 100644
index 0000000000000000000000000000000000000000..e86d7679d5bc6842826f49acf8ac79ddd83bcb7f
--- /dev/null
+++ b/tests/doml/CaseStudies/SIMPA_Validation_v2.doml
@@ -0,0 +1,84 @@
+doml nio3_test_exec_env
+
+application app {
+	// To be discussed
+	software_component potainer {
+		source r1 {
+			
+		}
+	}
+
+	software_component nio3_git {
+		source r1 {
+			entry "ansible/provision.yml"
+			backend "ansible"
+			properties {
+				nexus_docker_registry_user = "***";
+				nexus_docker_registry_password = "***";
+			}
+		}
+	}
+	
+}
+
+infrastructure infra {
+
+	container co1 {
+		host vm1
+	}
+
+	vm vm1 {
+		os "CentOS-7-2111"
+		cpu_count 2
+		mem_mb 8192.0
+		iface i1 {
+			address "10.0.0.1"
+			belongs_to net1
+		}
+	}
+
+	net net1 {
+		// cidr "/24" -> WRONG
+		// cidr "[10.0.0.1, 10.0.0.5]" -> WRONG
+		cidr "10.0.0.0/29" // -> 2^3 ips, 10.0.0.1-10.0.0.6
+		protocol "tcp/ip"
+	}
+
+	sto disk0 {
+		label "disk0"
+		size_gb 40
+	}
+}
+
+deployment conf {
+	potainer -> co1,
+	co1 -> vm1
+}
+
+active deployment conf
+
+concretizations {
+	concrete_infrastructure con_infra {
+		provider openstack {
+			properties {}
+
+			vm concrete_vm {
+				properties {
+					vm_flavor = "small-centos";
+				}
+				maps vm1
+			}
+
+			net concrete_net {
+				preexisting true
+				properties {}
+				maps net1
+			}
+
+			storage concrete_disk {
+				maps disk0
+			}
+		}
+	}
+	active con_infra
+}
diff --git a/tests/doml/CaseStudies/SIMPA_Validation_v2.domlx b/tests/doml/CaseStudies/SIMPA_Validation_v2.domlx
new file mode 100644
index 0000000000000000000000000000000000000000..4b96701c3f7b1f25c613a1a7e241c727fb849841
--- /dev/null
+++ b/tests/doml/CaseStudies/SIMPA_Validation_v2.domlx
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="ASCII"?>
+<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" name="nio3_test_exec_env" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0">
+  <application name="app">
+    <components xsi:type="app:SoftwareComponent" name="potainer">
+      <src name="r1"/>
+    </components>
+    <components xsi:type="app:SoftwareComponent" name="nio3_git">
+      <src name="r1" entry="ansible/provision.yml" backend="ansible">
+        <annotations xsi:type="commons:SProperty" key="nexus_docker_registry_user" value="***"/>
+        <annotations xsi:type="commons:SProperty" key="nexus_docker_registry_password" value="***"/>
+      </src>
+    </components>
+  </application>
+  <infrastructure name="infra">
+    <nodes xsi:type="infra:Container" name="co1">
+      <configs host="//@infrastructure/@nodes.1"/>
+    </nodes>
+    <nodes xsi:type="infra:VirtualMachine" name="vm1" os="CentOS-7-2111" memory_mb="8192.0" cpu_count="2">
+      <ifaces name="i1" endPoint="10.0.0.1" belongsTo="//@infrastructure/@networks.0"/>
+    </nodes>
+    <storages name="disk0" label="disk0" size_gb="40"/>
+    <networks name="net1" protocol="tcp/ip" addressRange="10.0.0.0/29" connectedIfaces="//@infrastructure/@nodes.1/@ifaces.0"/>
+  </infrastructure>
+  <concretizations name="con_infra">
+    <providers name="openstack">
+      <vms name="concrete_vm" maps="//@infrastructure/@nodes.1">
+        <annotations xsi:type="commons:SProperty" key="vm_flavor" value="small-centos"/>
+      </vms>
+      <networks name="concrete_net" preexisting="true" maps="//@infrastructure/@networks.0"/>
+      <storages name="concrete_disk" maps="//@infrastructure/@storages.0"/>
+    </providers>
+  </concretizations>
+  <configurations name="conf">
+    <deployments component="//@application/@components.0" node="//@infrastructure/@nodes.0"/>
+    <deployments component="//@infrastructure/@nodes.0" node="//@infrastructure/@nodes.1"/>
+  </configurations>
+</commons:DOMLModel>
diff --git a/tests/doml/CaseStudies/nio3_test_exec_env.doml b/tests/doml/CaseStudies/nio3_test_exec_env.doml
new file mode 100644
index 0000000000000000000000000000000000000000..6c7bf3716a8435d31ad37dc3b375be0e00459cee
--- /dev/null
+++ b/tests/doml/CaseStudies/nio3_test_exec_env.doml
@@ -0,0 +1,144 @@
+doml nio3_test_exec_env
+
+application app {
+
+	software_component nio3 {
+		properties {}
+	}
+}
+
+infrastructure infra {
+	
+	net net1 {
+		cidr "/24"
+		protocol "tcp/ip"
+		gateway g1 {
+			address "10.83.18.65"
+		}
+	}
+
+	user_pass ssh_pass {
+		user "root"
+		pass "pa$$w0rd"
+	}
+
+	key_pair ssh_key {
+		keyfile "/home/rmandal/.ssh/id_rsa.pub"
+	}
+	
+	vm_image img {
+		generates vm1, vm2
+	}
+	
+	vm vm1 {
+		os "centos7_64Guest"
+		cpu_count 2
+		mem_mb 1024.0
+		iface i1 {
+			address "10.83.18.92"
+			belongs_to net1
+		}
+		credentials ssh_pass
+	}
+	
+	vm vm2 {
+		os "centos7_64Guest"
+		cpu_count 2
+		mem_mb 1024.0
+		iface i1 {
+			address "10.83.18.88"
+			belongs_to net1
+		}
+		credentials ssh_pass
+	}
+	
+	sto disk0 {
+		label "disk0"
+		size_gb 100
+	}
+}
+
+deployment conf {
+	nio3 -> vm1, nio3 -> vm2
+}
+
+active deployment conf
+
+concretizations {
+	concrete_infrastructure con_infra {
+		provider vsphere {
+			properties {
+				username = "vc_username";
+				password = "vc_password";
+				vsphere_server = "psvc10000002.cd.sigov.si";
+				allow_unverified_ssl = true;
+			}
+			
+			generic_resource dc {
+				preexisting true
+				type 'vsphere_datacenter'
+				gname 'MB'
+			}
+
+			generic_resource cl {
+				preexisting true
+				refs_to dc
+				type 'vsphere_compute_cluster'
+				gname 'MB-PIAC-NIC-1'
+			}
+
+			generic_resource pool {
+				preexisting true
+				refs_to dc
+				type 'vsphere_resource_pool'
+				gname 'PIAC'
+			}
+			
+			vm_image template {
+				preexisting true
+				refs_to dc
+				properties {
+					vsphere_virtual_machine_name = "Centos7_PIAC";
+				}
+				maps img
+			}
+			
+			storage datastore {
+				preexisting true
+				refs_to dc
+				properties {
+					vsphere_datastore_name = 'VNX01-0200-NIC-TA-PIAC-DRO-VMW-P';
+				}
+				maps disk0
+			}
+
+			net network {
+				preexisting true
+				refs_to dc
+				properties {
+					vsphere_network_name = "DRO-MB-P-BG001-2098";
+				}
+				maps net1
+			}
+
+			vm con_vm1 {
+				refs_to pool, datastore
+				properties {
+					host_name = "piac-0";
+					domain    = "ad.sigov.si";
+				}
+				maps vm1
+			}
+
+			vm con_vm2 {
+				refs_to pool, datastore
+				properties {
+					host_name = "piac-1";
+					domain    = "ad.sigov.si";
+				}
+				maps vm2
+			}
+		}
+	}
+	active con_infra
+}
diff --git a/tests/doml/CaseStudies/nio3_test_exec_env.domlx b/tests/doml/CaseStudies/nio3_test_exec_env.domlx
new file mode 100644
index 0000000000000000000000000000000000000000..99050ef905dfb1bb4bfe4d7daa55ca1c6e66e910
--- /dev/null
+++ b/tests/doml/CaseStudies/nio3_test_exec_env.domlx
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="ASCII"?>
+<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" name="nio3_test_exec_env" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0">
+  <application name="app">
+    <components xsi:type="app:SoftwareComponent" name="nio3"/>
+  </application>
+  <infrastructure name="infra">
+    <nodes xsi:type="infra:VirtualMachine" name="vm1" os="centos7_64Guest" memory_mb="1024.0" cpu_count="2" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.0">
+      <ifaces name="i1" endPoint="10.83.18.92" belongsTo="//@infrastructure/@networks.0"/>
+    </nodes>
+    <nodes xsi:type="infra:VirtualMachine" name="vm2" os="centos7_64Guest" memory_mb="1024.0" cpu_count="2" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.0">
+      <ifaces name="i1" endPoint="10.83.18.88" belongsTo="//@infrastructure/@networks.0"/>
+    </nodes>
+    <generators xsi:type="infra:VMImage" name="img" generatedVMs="//@infrastructure/@nodes.0 //@infrastructure/@nodes.1"/>
+    <storages name="disk0" label="disk0" size_gb="100"/>
+    <credentials xsi:type="commons:UserPass" name="ssh_pass" username="root" password="pa$$w0rd"/>
+    <credentials xsi:type="commons:KeyPair" name="ssh_key" keyfile="/home/rmandal/.ssh/id_rsa.pub"/>
+    <networks name="net1" protocol="tcp/ip" addressRange="/24" connectedIfaces="//@infrastructure/@nodes.0/@ifaces.0 //@infrastructure/@nodes.1/@ifaces.0">
+      <gateways name="g1" address="10.83.18.65"/>
+    </networks>
+  </infrastructure>
+  <concretizations name="con_infra">
+    <providers name="vsphere">
+      <annotations xsi:type="commons:SProperty" key="username" value="vc_username"/>
+      <annotations xsi:type="commons:SProperty" key="password" value="vc_password"/>
+      <annotations xsi:type="commons:SProperty" key="vsphere_server" value="psvc10000002.cd.sigov.si"/>
+      <annotations xsi:type="commons:BProperty" key="allow_unverified_ssl" value="true"/>
+      <resources name="dc" preexisting="true" type="vsphere_datacenter" gname="MB"/>
+      <resources name="cl" preexisting="true" refs="//@concretizations.0/@providers.0/@resources.0" type="vsphere_compute_cluster" gname="MB-PIAC-NIC-1"/>
+      <resources name="pool" preexisting="true" refs="//@concretizations.0/@providers.0/@resources.0" type="vsphere_resource_pool" gname="PIAC"/>
+      <vms name="con_vm1" refs="//@concretizations.0/@providers.0/@resources.2 //@concretizations.0/@providers.0/@storages.0" maps="//@infrastructure/@nodes.0">
+        <annotations xsi:type="commons:SProperty" key="host_name" value="piac-0"/>
+        <annotations xsi:type="commons:SProperty" key="domain" value="ad.sigov.si"/>
+      </vms>
+      <vms name="con_vm2" refs="//@concretizations.0/@providers.0/@resources.2 //@concretizations.0/@providers.0/@storages.0" maps="//@infrastructure/@nodes.1">
+        <annotations xsi:type="commons:SProperty" key="host_name" value="piac-1"/>
+        <annotations xsi:type="commons:SProperty" key="domain" value="ad.sigov.si"/>
+      </vms>
+      <vmImages name="template" preexisting="true" refs="//@concretizations.0/@providers.0/@resources.0" maps="//@infrastructure/@generators.0">
+        <annotations xsi:type="commons:SProperty" key="vsphere_virtual_machine_name" value="Centos7_PIAC"/>
+      </vmImages>
+      <networks name="network" preexisting="true" refs="//@concretizations.0/@providers.0/@resources.0" maps="//@infrastructure/@networks.0">
+        <annotations xsi:type="commons:SProperty" key="vsphere_network_name" value="DRO-MB-P-BG001-2098"/>
+      </networks>
+      <storages name="datastore" preexisting="true" refs="//@concretizations.0/@providers.0/@resources.0" maps="//@infrastructure/@storages.0">
+        <annotations xsi:type="commons:SProperty" key="vsphere_datastore_name" value="VNX01-0200-NIC-TA-PIAC-DRO-VMW-P"/>
+      </storages>
+    </providers>
+  </concretizations>
+  <configurations name="conf">
+    <deployments component="//@application/@components.0" node="//@infrastructure/@nodes.0"/>
+    <deployments component="//@application/@components.0" node="//@infrastructure/@nodes.1"/>
+  </configurations>
+</commons:DOMLModel>
diff --git a/tests/doml/CaseStudies/posidonia.doml b/tests/doml/CaseStudies/posidonia.doml
new file mode 100644
index 0000000000000000000000000000000000000000..82ba8c453ec2914d198850e91922055af4b68a65
--- /dev/null
+++ b/tests/doml/CaseStudies/posidonia.doml
@@ -0,0 +1,258 @@
+doml posidonia
+properties {
+	entorno="pre";
+	proyecto="baleares";
+}
+
+// Application Definition
+application posidonia {
+	software_component Gestaut {
+		provides { http https }
+		consumes { dbAccess, search }
+	}
+	software_component ElasticSearch {
+		provides { search }
+		consumes { dbAccess }
+	}
+	software_component Edi {
+		provides { edi }
+		consumes { dbAccess }
+	}
+	dbms Database {
+		provides {
+			dbAccess
+		}
+	}
+}
+
+infrastructure abstractInfra {
+	// Networks
+	net vpc {
+		cidr "/16"
+		protocol "tcp/ip"
+		subnet subnet1 {
+			cidr "/24"
+			protocol "tcp/ip"
+		}
+		subnet subnet2 {
+			cidr "/24"
+			protocol "tcp/ip"
+		}
+		subnet subnet3 {
+			cidr "/24"
+			protocol "tcp/ip"
+		}
+	}
+	// Credentials
+	// TODO: key file?
+	key_pair GestautKeyName {
+		algorithm "RSA"
+		bits 4096
+	}
+	key_pair ESKeyName {
+		algorithm "RSA"
+		bits 4096
+	}
+	key_pair EdiKeyName {
+		algorithm "RSA"
+		bits 4096
+	}
+	user_pass dbCredentials {
+		user "***"
+		pass "***"
+	}
+	
+	// Nodes
+	vm OracleDB {
+		iface db1 {
+			belongs_to subnet1
+		}
+		iface db2 {
+			belongs_to subnet2
+		}
+		iface db3 {
+			belongs_to subnet3
+		}
+		sto "20"
+		credentials dbCredentials
+	}
+	
+	vm_image posidonia_image {
+		generates gestaut_vm, elasticsearch_vm, edi_vm
+		image "ami-02a6bfdcf8224bd77"
+	}
+	
+	autoscale_group gestaut_asg {
+		// TODO: Shouldn't vm live outside the group leaving a reference here? vm might also be referenced by other components.
+		// It also applies to the following vms in other groups.
+		vm gestaut_vm {
+			credentials GestautKeyName
+		}
+		min 1
+		max 1 // Using AutoScaleGroup as a way to automatically reboot a machine in case of error
+	}
+	
+	autoscale_group elasticsearch_asg {
+		// TODO
+		vm elasticsearch_vm {
+			credentials ESKeyName
+		}
+		min 1
+		max 1 // Using AutoScaleGroup as a way to automatically reboot a machine in case of error
+	}
+	
+	autoscale_group edi_asg {
+		// TODO
+		vm edi_vm {
+			credentials EdiKeyName
+		}
+		min 1
+		max 1 // Using AutoScaleGroup as a way to automatically reboot a machine in case of error
+	}
+	
+	security_group sg {
+		// TODO: the following vms should have the associated interfaces (ifaces) in the security group?
+		//nodes gestaut_vm, elasticsearch_vm, edi_vm
+		egress salida {
+			protocol "-1"
+			from_port 0
+			to_port 0
+			cidr ["0.0.0.0/0"]
+		}
+		ingress lb {
+			protocol "tcp"
+			from_port 80
+			to_port 80
+			cidr ["10.100.1.0/24", "10.100.2.0/24", "10.100.3.0/24"]
+		}
+		ingress es {
+			protocol "tcp"
+			from_port 9200
+			to_port 9200
+			cidr ["10.100.1.0/24", "10.100.2.0/24", "10.100.3.0/24"]
+		}
+		ingress monitor {
+			protocol "tcp"
+			from_port 6556
+			to_port 6556
+			cidr ["54.217.119.81/32"]
+		}
+
+		// TODO: ftp (20/21) or ssh (22)?
+		ingress ftp {
+			protocol "tcp"
+			from_port 22
+			to_port 22
+			cidr ["213.96.27.139/32", "37.187.173.88/32", "51.89.40.59/32", "195.53.242.200/32"]
+		}
+	}
+	
+	security_group dbsg {
+		// TODO: the associated vms and ifaces?
+		egress salida {
+			protocol "-1"
+			from_port 0
+			to_port 0
+			cidr ["0.0.0.0/0"]
+		}
+		ingress ora {
+			protocol "tcp"
+			from_port 1521
+			to_port 1521
+			cidr ["10.100.1.0/24", "10.100.2.0/24", "10.100.3.0/24", "84.124.78.66/32"]
+		}
+	}
+	
+	security_group elbsg {
+		// TODO: the associated vms and ifaces?
+		egress salida {
+			protocol "-1"
+			from_port 0
+			to_port 0
+			cidr ["0.0.0.0/0"]
+		}
+		ingress http {
+			protocol "tcp"
+			from_port 80
+			to_port 80
+			cidr ["0.0.0.0/0", "::/0"]
+		}
+		ingress https {
+			protocol "tcp"
+			from_port 443
+			to_port 443
+			cidr ["0.0.0.0/0", "::/0"]
+		}
+		ingress es {
+			protocol "tcp"
+			from_port 9200
+			to_port 9200
+			cidr ["10.100.1.0/24", "10.100.2.0/24", "10.100.3.0/24"]
+		}
+	}
+	
+	security_group checkmk {
+		// TODO: the associated vms and ifaces?
+		egress salida {
+			protocol "-1"
+			from_port 0
+			to_port 0
+			cidr ["0.0.0.0/0"]
+		}
+		ingress http {
+			protocol "tcp"
+			from_port 80
+			to_port 80
+			cidr ["84.124.78.66/32"]
+		}
+		ingress https {
+			protocol "tcp"
+			from_port 443
+			to_port 443
+			cidr ["84.124.78.66/32"]
+		}
+
+		// TODO: ftp (20/21) or ssh (22)?
+		ingress ftp {
+			protocol "tcp"
+			from_port 22
+			to_port 22
+			cidr ["84.124.78.66/32"]
+		}
+	}
+	
+}
+deployment dep {
+	Gestaut -> gestaut_vm,
+	ElasticSearch -> elasticsearch_vm,
+	Edi -> edi_vm,
+	Database -> OracleDB
+	
+}
+active deployment dep
+
+// Concretization to AWS
+concretizations {
+	concrete_infrastructure dev {
+		provider aws {
+			autoscale_group asg1 {
+				maps elasticsearch_asg
+			}
+			autoscale_group asg2 {
+				maps edi_asg
+			}
+			autoscale_group asg3 {
+				maps gestaut_asg
+			}
+		}
+	}
+	
+//	concrete_infrastructure pro {
+//		provider aws {
+//			
+//		}
+//	}
+	
+	active dev
+}
+
diff --git a/tests/doml/CaseStudies/posidonia.domlx b/tests/doml/CaseStudies/posidonia.domlx
new file mode 100644
index 0000000000000000000000000000000000000000..151646f5ebddfe27c508f59e55a7879ad0b9b1f5
--- /dev/null
+++ b/tests/doml/CaseStudies/posidonia.domlx
@@ -0,0 +1,126 @@
+<?xml version="1.0" encoding="ASCII"?>
+<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" name="posidonia" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0">
+  <annotations xsi:type="commons:SProperty" key="entorno" value="pre"/>
+  <annotations xsi:type="commons:SProperty" key="proyecto" value="baleares"/>
+  <application name="posidonia">
+    <components xsi:type="app:SoftwareComponent" name="Gestaut" consumedInterfaces="//@application/@components.3/@exposedInterfaces.0 //@application/@components.1/@exposedInterfaces.0">
+      <exposedInterfaces name="http"/>
+      <exposedInterfaces name="https"/>
+    </components>
+    <components xsi:type="app:SoftwareComponent" name="ElasticSearch" consumedInterfaces="//@application/@components.3/@exposedInterfaces.0">
+      <exposedInterfaces name="search"/>
+    </components>
+    <components xsi:type="app:SoftwareComponent" name="Edi" consumedInterfaces="//@application/@components.3/@exposedInterfaces.0">
+      <exposedInterfaces name="edi"/>
+    </components>
+    <components xsi:type="app:DBMS" name="Database">
+      <exposedInterfaces name="dbAccess"/>
+    </components>
+  </application>
+  <infrastructure name="abstractInfra">
+    <nodes xsi:type="infra:VirtualMachine" name="OracleDB" storage="20" credentials="//@infrastructure/@credentials.3">
+      <ifaces name="db1" belongsTo="//@infrastructure/@networks.0/@subnets.0"/>
+      <ifaces name="db2" belongsTo="//@infrastructure/@networks.0/@subnets.1"/>
+      <ifaces name="db3" belongsTo="//@infrastructure/@networks.0/@subnets.2"/>
+    </nodes>
+    <generators xsi:type="infra:VMImage" name="posidonia_image" uri="ami-02a6bfdcf8224bd77" kind="IMAGE" generatedVMs="//@infrastructure/@groups.0/@machineDefinition //@infrastructure/@groups.1/@machineDefinition //@infrastructure/@groups.2/@machineDefinition"/>
+    <credentials xsi:type="commons:KeyPair" name="GestautKeyName" algorithm="RSA" bits="4096"/>
+    <credentials xsi:type="commons:KeyPair" name="ESKeyName" algorithm="RSA" bits="4096"/>
+    <credentials xsi:type="commons:KeyPair" name="EdiKeyName" algorithm="RSA" bits="4096"/>
+    <credentials xsi:type="commons:UserPass" name="dbCredentials" username="***" password="***"/>
+    <groups xsi:type="infra:AutoScalingGroup" name="gestaut_asg">
+      <machineDefinition name="gestaut_vm" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.0"/>
+    </groups>
+    <groups xsi:type="infra:AutoScalingGroup" name="elasticsearch_asg">
+      <machineDefinition name="elasticsearch_vm" credentials="//@infrastructure/@credentials.1" generatedFrom="//@infrastructure/@generators.0"/>
+    </groups>
+    <groups xsi:type="infra:AutoScalingGroup" name="edi_asg">
+      <machineDefinition name="edi_vm" credentials="//@infrastructure/@credentials.2" generatedFrom="//@infrastructure/@generators.0"/>
+    </groups>
+    <securityGroups name="sg">
+      <rules name="salida" protocol="-1" fromPort="0" toPort="0">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="lb" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80">
+        <cidr>10.100.1.0/24</cidr>
+        <cidr>10.100.2.0/24</cidr>
+        <cidr>10.100.3.0/24</cidr>
+      </rules>
+      <rules name="es" kind="INGRESS" protocol="tcp" fromPort="9200" toPort="9200">
+        <cidr>10.100.1.0/24</cidr>
+        <cidr>10.100.2.0/24</cidr>
+        <cidr>10.100.3.0/24</cidr>
+      </rules>
+      <rules name="monitor" kind="INGRESS" protocol="tcp" fromPort="6556" toPort="6556">
+        <cidr>54.217.119.81/32</cidr>
+      </rules>
+      <rules name="ftp" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22">
+        <cidr>213.96.27.139/32</cidr>
+        <cidr>37.187.173.88/32</cidr>
+        <cidr>51.89.40.59/32</cidr>
+        <cidr>195.53.242.200/32</cidr>
+      </rules>
+    </securityGroups>
+    <securityGroups name="dbsg">
+      <rules name="salida" protocol="-1" fromPort="0" toPort="0">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="ora" kind="INGRESS" protocol="tcp" fromPort="1521" toPort="1521">
+        <cidr>10.100.1.0/24</cidr>
+        <cidr>10.100.2.0/24</cidr>
+        <cidr>10.100.3.0/24</cidr>
+        <cidr>84.124.78.66/32</cidr>
+      </rules>
+    </securityGroups>
+    <securityGroups name="elbsg">
+      <rules name="salida" protocol="-1" fromPort="0" toPort="0">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80">
+        <cidr>0.0.0.0/0</cidr>
+        <cidr>::/0</cidr>
+      </rules>
+      <rules name="https" kind="INGRESS" protocol="tcp" fromPort="443" toPort="443">
+        <cidr>0.0.0.0/0</cidr>
+        <cidr>::/0</cidr>
+      </rules>
+      <rules name="es" kind="INGRESS" protocol="tcp" fromPort="9200" toPort="9200">
+        <cidr>10.100.1.0/24</cidr>
+        <cidr>10.100.2.0/24</cidr>
+        <cidr>10.100.3.0/24</cidr>
+      </rules>
+    </securityGroups>
+    <securityGroups name="checkmk">
+      <rules name="salida" protocol="-1" fromPort="0" toPort="0">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80">
+        <cidr>84.124.78.66/32</cidr>
+      </rules>
+      <rules name="https" kind="INGRESS" protocol="tcp" fromPort="443" toPort="443">
+        <cidr>84.124.78.66/32</cidr>
+      </rules>
+      <rules name="ftp" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22">
+        <cidr>84.124.78.66/32</cidr>
+      </rules>
+    </securityGroups>
+    <networks name="vpc" protocol="tcp/ip" addressRange="/16">
+      <subnets name="subnet1" protocol="tcp/ip" addressRange="/24" connectedIfaces="//@infrastructure/@nodes.0/@ifaces.0"/>
+      <subnets name="subnet2" protocol="tcp/ip" addressRange="/24" connectedIfaces="//@infrastructure/@nodes.0/@ifaces.1"/>
+      <subnets name="subnet3" protocol="tcp/ip" addressRange="/24" connectedIfaces="//@infrastructure/@nodes.0/@ifaces.2"/>
+    </networks>
+  </infrastructure>
+  <concretizations name="dev">
+    <providers name="aws">
+      <group name="asg1" maps="//@infrastructure/@groups.1"/>
+      <group name="asg2" maps="//@infrastructure/@groups.2"/>
+      <group name="asg3" maps="//@infrastructure/@groups.0"/>
+    </providers>
+  </concretizations>
+  <configurations name="dep">
+    <deployments component="//@application/@components.0" node="//@infrastructure/@groups.0/@machineDefinition"/>
+    <deployments component="//@application/@components.1" node="//@infrastructure/@groups.1/@machineDefinition"/>
+    <deployments component="//@application/@components.2" node="//@infrastructure/@groups.2/@machineDefinition"/>
+    <deployments component="//@application/@components.3" node="//@infrastructure/@nodes.0"/>
+  </configurations>
+</commons:DOMLModel>
diff --git a/tests/doml/CaseStudies/posidonia_IOP.doml b/tests/doml/CaseStudies/posidonia_IOP.doml
new file mode 100644
index 0000000000000000000000000000000000000000..e441982f154cd863612c9ba5b01c174d95498c3c
--- /dev/null
+++ b/tests/doml/CaseStudies/posidonia_IOP.doml
@@ -0,0 +1,307 @@
+doml posidonia
+properties {
+	entorno="pre";
+	proyecto="baleares";
+}
+
+// Application Definition
+application posidonia {
+	software_component Gestaut {
+		// Interfaces should be separated by commas, but the IDE needs to be fixed
+		provides { http https }
+		consumes { dbAccess, search }
+	}
+	software_component ElasticSearch {
+		provides { search }
+		consumes { dbAccess }
+	}
+	software_component Edi {
+		provides { edi }
+		consumes { dbAccess }
+	}
+	dbms Database {
+		provides {
+			dbAccess
+		}
+	}
+}
+
+infrastructure abstractInfra {
+	// Networks
+	net vpc {
+		// In DOML 2.1, you can specify an address before the length of the subnet mask
+		// Actually it should also work in DOML 2.2 for ICG
+		cidr "/16"
+		protocol "TCP/IP"
+		subnet subnet1 {
+			// We have to check whether this address (which was copy-pasted from the
+			// security group rules cidr) actually was the one intended for the subnet
+			cidr "10.100.1.0/24"
+			protocol "TCP/IP"
+		}
+		subnet subnet2 {
+			cidr "/24"
+			protocol "TCP/IP"
+		}
+		subnet subnet3 {
+			cidr "/24"
+			protocol "TCP/IP"
+		}
+	}
+	// Credentials
+	// TODO: key file?
+	key_pair GestautKeyName {
+		// We're here specifying the key through the keyfile attribute instead of using it for specifying the keyfile path.
+		user "..."
+		keyfile "not the path, but currently the key itself"
+		algorithm "RSA"
+		bits 4096
+	}
+	key_pair ESKeyName {
+		user "..."
+		keyfile "not the path, but currently the key itself"
+		algorithm "RSA"
+		bits 4096
+	}
+	key_pair EdiKeyName {
+		user "..."
+		keyfile "not the path, but currently the key itself"
+		algorithm "RSA"
+		bits 4096
+	}
+	user_pass dbCredentials {
+		user "***"
+		pass "***"
+	}
+	
+	// Nodes
+	vm OracleDB {
+		// It can be updated by specifying the VM characteristics through the usage of attributes
+		iface db1 {
+			belongs_to subnet1
+			// We can define the security group associated to the interface either by using the
+			// security attribute here or specifying the name of the interface in the
+			// ifaces attribute of the security group itself
+			security dbsg
+		}
+		iface db2 {
+			belongs_to subnet2
+		}
+		iface db3 {
+			belongs_to subnet3
+		}
+		// We have to specify GB or ...
+		sto "20"
+		credentials dbCredentials
+	}
+	
+	/* 
+	 * We currently don't use images, but specify properties through VM attributes definition
+	 	vm_image posidonia_image {
+		generates gestaut_vm, elasticsearch_vm, edi_vm
+		image "ami-02a6bfdcf8224bd77"
+		}
+	*/
+
+	
+	autoscale_group gestaut_asg {
+		// TODO: Shouldn't vm live outside the group leaving a reference here? vm might also be referenced by other components.
+		// It also applies to the following vms in other groups.
+		vm gestaut_vm {
+			credentials GestautKeyName
+		}
+		min 1
+		max 1 // Using AutoScaleGroup as a way to automatically reboot a machine in case of error
+		
+		/*
+		 * In order to specify the sg for the three VMs defined for the AGs, we can
+		 * use the security attribute of the autoscale_group class.
+		 * We have to define a new security group inside the autoscale_group
+		 * when using such attribute.
+		 */
+	}
+	
+	autoscale_group elasticsearch_asg {
+		// TODO
+		vm elasticsearch_vm {
+			credentials ESKeyName
+		}
+		min 1
+		max 1 // Using AutoScaleGroup as a way to automatically reboot a machine in case of error
+	}
+	
+	autoscale_group edi_asg {
+		// TODO
+		vm edi_vm {
+			credentials EdiKeyName
+		}
+		min 1
+		max 1 // Using AutoScaleGroup as a way to automatically reboot a machine in case of error
+	}
+	
+	security_group sg {
+		// TODO: the following vms should have the associated interfaces (ifaces) in the security group?
+		//nodes gestaut_vm, elasticsearch_vm, edi_vm
+		egress salida {
+			protocol "-1"
+			from_port 0
+			to_port 0
+			cidr ["0.0.0.0/0"]
+		}
+		ingress lb {
+			protocol "TCP"
+			from_port 80
+			to_port 80
+			cidr ["10.100.1.0/24", "10.100.2.0/24", "10.100.3.0/24"]
+		}
+		ingress es {
+			protocol "TCP"
+			from_port 9200
+			to_port 9200
+			cidr ["10.100.1.0/24", "10.100.2.0/24", "10.100.3.0/24"]
+		}
+		ingress monitor {
+			protocol "TCP"
+			from_port 6556
+			to_port 6556
+			cidr ["54.217.119.81/32"]
+		}
+
+		// TODO: ftp (20/21) or ssh (22)?
+		ingress ftp {
+			protocol "TCP"
+			from_port 22
+			to_port 22
+			cidr ["213.96.27.139/32", "37.187.173.88/32", "51.89.40.59/32", "195.53.242.200/32"]
+		}
+	}
+	
+	/*
+	 * TODO: We have to define interfaces or check which interfaces/AGs belong to each sg
+	 */
+	security_group dbsg {
+		egress salida {
+			protocol "-1"
+			from_port 0
+			to_port 0
+			cidr ["0.0.0.0/0"]
+		}
+		ingress ora {
+			protocol "TCP"
+			from_port 1521
+			to_port 1521
+			cidr ["10.100.1.0/24", "10.100.2.0/24", "10.100.3.0/24", "84.124.78.66/32"]
+		}
+		
+		// As discussed above, here is provided the other way to specify the sg
+		// associated to interfaces
+		ifaces db1, db2, db3
+	}
+	
+	security_group elbsg {
+		egress salida {
+			protocol "-1"
+			from_port 0
+			to_port 0
+			cidr ["0.0.0.0/0"]
+		}
+		ingress http {
+			protocol "TCP"
+			from_port 80
+			to_port 80
+			cidr ["0.0.0.0/0", "::/0"]
+		}
+		ingress https {
+			protocol "TCP"
+			from_port 443
+			to_port 443
+			cidr ["0.0.0.0/0", "::/0"]
+		}
+		ingress es {
+			protocol "TCP"
+			from_port 9200
+			to_port 9200
+			cidr ["10.100.1.0/24", "10.100.2.0/24", "10.100.3.0/24"]
+		}
+	}
+	
+	security_group checkmk {
+		egress salida {
+			protocol "-1"
+			from_port 0
+			to_port 0
+			cidr ["0.0.0.0/0"]
+		}
+		ingress http {
+			protocol "TCP"
+			from_port 80
+			to_port 80
+			cidr ["84.124.78.66/32"]
+		}
+		ingress https {
+			protocol "TCP"
+			from_port 443
+			to_port 443
+			cidr ["84.124.78.66/32"]
+		}
+
+		// TODO: ftp (20/21) or ssh (22)?
+		ingress ftp {
+			protocol "TCP"
+			from_port 22
+			to_port 22
+			cidr ["84.124.78.66/32"]
+		}
+	}
+	
+}
+deployment dep {
+	Gestaut -> gestaut_vm,
+	ElasticSearch -> elasticsearch_vm,
+	Edi -> edi_vm,
+	Database -> OracleDB
+	
+}
+active deployment dep
+
+// Concretization to AWS
+concretizations {
+	concrete_infrastructure dev {
+		provider aws {
+			net concrete_vpc {
+				maps vpc
+			}
+			vm concrete_oracleDB {
+				maps OracleDB
+			}
+			autoscale_group asg1 {
+				maps elasticsearch_asg
+			}
+			autoscale_group asg2 {
+				maps edi_asg
+			}
+			autoscale_group asg3 {
+				maps gestaut_asg
+			}
+		}
+	}
+	
+//	concrete_infrastructure pro {
+//		provider aws {
+//			
+//		}
+//	}
+	
+	active dev
+}
+
+optimization opt {
+	objectives {
+		"cost" => min
+		"availability" => max
+	}
+	nonfunctional_requirements {
+		req1 "Cost <= 70.0" max 70.0 => "cost";
+		req2 "Availability >= 66.5%" min 66.5 => "availability";
+	}
+}
diff --git a/tests/doml/CaseStudies/posidonia_IOP.domlx b/tests/doml/CaseStudies/posidonia_IOP.domlx
new file mode 100644
index 0000000000000000000000000000000000000000..e1bd8a0d55a7915a9f9f4a2deff579127894e452
--- /dev/null
+++ b/tests/doml/CaseStudies/posidonia_IOP.domlx
@@ -0,0 +1,132 @@
+<?xml version="1.0" encoding="ASCII"?>
+<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" xmlns:optimization="http://www.piacere-project.eu/doml/optimization" name="posidonia" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0">
+  <annotations xsi:type="commons:SProperty" key="entorno" value="pre"/>
+  <annotations xsi:type="commons:SProperty" key="proyecto" value="baleares"/>
+  <application name="posidonia">
+    <components xsi:type="app:SoftwareComponent" name="Gestaut" consumedInterfaces="//@application/@components.3/@exposedInterfaces.0 //@application/@components.1/@exposedInterfaces.0">
+      <exposedInterfaces name="http"/>
+      <exposedInterfaces name="https"/>
+    </components>
+    <components xsi:type="app:SoftwareComponent" name="ElasticSearch" consumedInterfaces="//@application/@components.3/@exposedInterfaces.0">
+      <exposedInterfaces name="search"/>
+    </components>
+    <components xsi:type="app:SoftwareComponent" name="Edi" consumedInterfaces="//@application/@components.3/@exposedInterfaces.0">
+      <exposedInterfaces name="edi"/>
+    </components>
+    <components xsi:type="app:DBMS" name="Database">
+      <exposedInterfaces name="dbAccess"/>
+    </components>
+  </application>
+  <infrastructure name="abstractInfra">
+    <nodes xsi:type="infra:VirtualMachine" name="OracleDB" storage="20" credentials="//@infrastructure/@credentials.3">
+      <ifaces name="db1" belongsTo="//@infrastructure/@networks.0/@subnets.0"/>
+      <ifaces name="db2" belongsTo="//@infrastructure/@networks.0/@subnets.1"/>
+      <ifaces name="db3" belongsTo="//@infrastructure/@networks.0/@subnets.2"/>
+    </nodes>
+    <generators xsi:type="infra:VMImage" name="posidonia_image" uri="ami-02a6bfdcf8224bd77" kind="IMAGE" generatedVMs="//@infrastructure/@groups.0/@machineDefinition //@infrastructure/@groups.1/@machineDefinition //@infrastructure/@groups.2/@machineDefinition"/>
+    <credentials xsi:type="commons:KeyPair" name="GestautKeyName" algorithm="RSA" bits="4096"/>
+    <credentials xsi:type="commons:KeyPair" name="ESKeyName" algorithm="RSA" bits="4096"/>
+    <credentials xsi:type="commons:KeyPair" name="EdiKeyName" algorithm="RSA" bits="4096"/>
+    <credentials xsi:type="commons:UserPass" name="dbCredentials" username="***" password="***"/>
+    <groups xsi:type="infra:AutoScalingGroup" name="gestaut_asg">
+      <machineDefinition name="gestaut_vm" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.0"/>
+    </groups>
+    <groups xsi:type="infra:AutoScalingGroup" name="elasticsearch_asg">
+      <machineDefinition name="elasticsearch_vm" credentials="//@infrastructure/@credentials.1" generatedFrom="//@infrastructure/@generators.0"/>
+    </groups>
+    <groups xsi:type="infra:AutoScalingGroup" name="edi_asg">
+      <machineDefinition name="edi_vm" credentials="//@infrastructure/@credentials.2" generatedFrom="//@infrastructure/@generators.0"/>
+    </groups>
+    <securityGroups name="sg">
+      <rules name="salida" protocol="-1" fromPort="0" toPort="0">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="lb" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80">
+        <cidr>10.100.1.0/24</cidr>
+        <cidr>10.100.2.0/24</cidr>
+        <cidr>10.100.3.0/24</cidr>
+      </rules>
+      <rules name="es" kind="INGRESS" protocol="tcp" fromPort="9200" toPort="9200">
+        <cidr>10.100.1.0/24</cidr>
+        <cidr>10.100.2.0/24</cidr>
+        <cidr>10.100.3.0/24</cidr>
+      </rules>
+      <rules name="monitor" kind="INGRESS" protocol="tcp" fromPort="6556" toPort="6556">
+        <cidr>54.217.119.81/32</cidr>
+      </rules>
+      <rules name="ftp" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22">
+        <cidr>213.96.27.139/32</cidr>
+        <cidr>37.187.173.88/32</cidr>
+        <cidr>51.89.40.59/32</cidr>
+        <cidr>195.53.242.200/32</cidr>
+      </rules>
+    </securityGroups>
+    <securityGroups name="dbsg">
+      <rules name="salida" protocol="-1" fromPort="0" toPort="0">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="ora" kind="INGRESS" protocol="tcp" fromPort="1521" toPort="1521">
+        <cidr>10.100.1.0/24</cidr>
+        <cidr>10.100.2.0/24</cidr>
+        <cidr>10.100.3.0/24</cidr>
+        <cidr>84.124.78.66/32</cidr>
+      </rules>
+    </securityGroups>
+    <securityGroups name="elbsg">
+      <rules name="salida" protocol="-1" fromPort="0" toPort="0">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80">
+        <cidr>0.0.0.0/0</cidr>
+        <cidr>::/0</cidr>
+      </rules>
+      <rules name="https" kind="INGRESS" protocol="tcp" fromPort="443" toPort="443">
+        <cidr>0.0.0.0/0</cidr>
+        <cidr>::/0</cidr>
+      </rules>
+      <rules name="es" kind="INGRESS" protocol="tcp" fromPort="9200" toPort="9200">
+        <cidr>10.100.1.0/24</cidr>
+        <cidr>10.100.2.0/24</cidr>
+        <cidr>10.100.3.0/24</cidr>
+      </rules>
+    </securityGroups>
+    <securityGroups name="checkmk">
+      <rules name="salida" protocol="-1" fromPort="0" toPort="0">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80">
+        <cidr>84.124.78.66/32</cidr>
+      </rules>
+      <rules name="https" kind="INGRESS" protocol="tcp" fromPort="443" toPort="443">
+        <cidr>84.124.78.66/32</cidr>
+      </rules>
+      <rules name="ftp" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22">
+        <cidr>84.124.78.66/32</cidr>
+      </rules>
+    </securityGroups>
+    <networks name="vpc" protocol="tcp/ip" addressRange="/16">
+      <subnets name="subnet1" protocol="tcp/ip" addressRange="/24" connectedIfaces="//@infrastructure/@nodes.0/@ifaces.0"/>
+      <subnets name="subnet2" protocol="tcp/ip" addressRange="/24" connectedIfaces="//@infrastructure/@nodes.0/@ifaces.1"/>
+      <subnets name="subnet3" protocol="tcp/ip" addressRange="/24" connectedIfaces="//@infrastructure/@nodes.0/@ifaces.2"/>
+    </networks>
+  </infrastructure>
+  <concretizations name="dev">
+    <providers name="aws">
+      <group name="asg1" maps="//@infrastructure/@groups.1"/>
+      <group name="asg2" maps="//@infrastructure/@groups.2"/>
+      <group name="asg3" maps="//@infrastructure/@groups.0"/>
+    </providers>
+  </concretizations>
+  <optimization name="opt">
+    <objectives xsi:type="optimization:MeasurableObjective" kind="min" property="cost"/>
+    <objectives xsi:type="optimization:MeasurableObjective" kind="max" property="availability"/>
+    <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req1" description="Cost &lt;= 70.0" property="cost" max="70.0"/>
+    <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req2" description="Availability >= 66.5%" property="availability" min="66.5"/>
+  </optimization>
+  <configurations name="dep">
+    <deployments component="//@application/@components.0" node="//@infrastructure/@groups.0/@machineDefinition"/>
+    <deployments component="//@application/@components.1" node="//@infrastructure/@groups.1/@machineDefinition"/>
+    <deployments component="//@application/@components.2" node="//@infrastructure/@groups.2/@machineDefinition"/>
+    <deployments component="//@application/@components.3" node="//@infrastructure/@nodes.0"/>
+  </configurations>
+</commons:DOMLModel>
diff --git a/tests/doml/CaseStudies/uc3-openstack_v2.doml b/tests/doml/CaseStudies/uc3-openstack_v2.doml
new file mode 100644
index 0000000000000000000000000000000000000000..f4feede7555e3fa203cb8269391481cc23ec39bb
--- /dev/null
+++ b/tests/doml/CaseStudies/uc3-openstack_v2.doml
@@ -0,0 +1,246 @@
+doml uc3_openstack
+
+application app {
+
+// need to define all sw components of the project this is a placeholder
+// need to understand what is really needed in this spec
+// need to specify all provides/consumes
+	software_component iwg {
+		provides { net_info }
+	}
+	software_component osint {
+		provides { osint_info }
+		consumes { net_info, get_twitter, ewcf_rest_interface }
+	}
+	software_component ewcf {
+		provides { ewcf_rest_interface }
+		// ??? consumes { get_firebase }
+	}
+	saas external_twitter {
+		provides { get_twitter @ "https://twitter_api/get" }
+	}
+
+}
+
+
+infrastructure infra {
+
+	vm_image v_img1 {
+		generates osint_vm
+	}
+
+	container c {
+		host osint_vm {
+			container_port 80
+			vm_port 8080
+			iface osint_igw_port
+			properties {
+				env_var1 = "value1";
+			}
+		}
+	}
+
+	cont_image c_img {
+		generates c
+		image "web-app:0.1.0" // needs to be replaced and other containers added
+	}
+
+
+	vm_image v_img2 {
+		generates igw_vm
+	}
+
+	vm_image v_img3 {
+		generates ewcf_vm
+	}
+
+	net net1 {
+		cidr "/24"
+		protocol "tcp/ip"
+	}
+	net net2 {
+		cidr "/24"
+		protocol "tcp/ip"
+	}
+	net net3 {
+		cidr "/24"
+		protocol "tcp/ip"
+	}
+	net oam {
+		cidr "/24"
+		protocol "tcp/ip"
+	}
+
+
+// security group is left as originally defined needs to be updated
+	security_group sg {
+		egress icmp {
+			from_port -1
+			to_port -1
+			protocol "icmp"
+			cidr ["0.0.0.0/0"]
+		}
+		ingress http {
+			from_port 80
+			to_port 80
+			protocol "tcp"
+			cidr ["0.0.0.0/0"]
+		}
+		ingress https {
+			from_port 443
+			to_port 443
+			protocol "tcp"
+			cidr ["0.0.0.0/0"]
+		}
+		ingress ssh {
+			from_port 22
+			to_port 22
+			protocol "tcp"
+			cidr ["0.0.0.0/0"]
+		}
+	}
+
+	key_pair ssh_key {
+		user "ubuntu"
+		keyfile "/home/user1/.ssh/openstack.key"
+		algorithm "RSA"
+		bits 4096
+	}
+	autoscale_group osint_ag { 
+		vm osint_vm {
+			os "ubuntu-20.04.3"
+			credentials ssh_key
+			iface osint_vm_net1 {
+				belongs_to net1
+			}
+			iface osint_vm_oam {
+				belongs_to oam
+			}
+
+			iface osint_igw_port{
+				belongs_to net1
+			}	
+		}
+	}
+
+	autoscale_group igw_ag { 
+		vm igw_vm {
+			os "ubuntu-20.04.3"
+			credentials ssh_key
+			iface igw_vm_net2 {
+				belongs_to net2
+			}
+			iface igw_vm_oam {
+				belongs_to oam
+			}
+		}
+	}
+	autoscale_group ewcf_ag { 
+		vm ewcf_vm {
+			os "ubuntu-20.04.3"
+			credentials ssh_key
+			iface ewcf_vm_net3 {
+				belongs_to net3
+			}
+			iface ewcf_vm_oam {
+				belongs_to oam
+			}
+		}
+	}
+}
+
+deployment conf {
+	osint -> osint_vm,
+	iwg -> igw_vm,
+	ewcf -> ewcf_vm
+}
+
+active deployment conf
+
+concretizations {
+	concrete_infrastructure con_infra {
+		provider openstack {
+			vm concrete_osint_vm {
+				properties {
+					vm_name = "osint";
+					vm_flavor = "small";
+					vm_key_name = "user1";
+				}
+				maps osint_vm
+			}
+			vm concrete_igw_vm {
+				properties {
+					vm_name = "igw";
+					vm_flavor = "small";
+					vm_key_name = "user1";
+				}
+				maps igw_vm
+			}
+			vm concrete_ewcf_vm {
+				properties {
+					vm_name = "ewcf";
+					vm_flavor = "small";
+					vm_key_name = "user1";
+				}
+				maps ewcf_vm
+			}
+
+			vm_image concrete_vm_image1 {
+				properties {
+					name = "ubuntu-20.04.3";
+				}
+				maps v_img1
+			}
+			
+			vm_image concrete_vm_image2{
+				properties {
+					name = "ubuntu-20.04.3";
+				}
+				maps v_img2
+			}
+			
+			vm_image concrete_vm_image3 {
+				properties {
+					name = "ubuntu-20.04.3";
+				}
+				maps v_img3
+			}
+
+			net concrete_net1 {
+				properties {
+					name = "uc3_net1";
+				}
+				maps net1
+			}			
+			net concrete_net2 {
+				properties {
+					name = "uc3_net2";
+				}
+				maps net2
+			}
+			net concrete_net3 {
+				properties {
+					name = "uc3_net3";
+				}
+				maps net3
+			}
+			net concrete_net4 {
+				properties {
+					name = "uc3_net4";
+				}
+				maps oam
+			}			
+		}
+	}
+	active con_infra
+}
+
+optimization opt {
+	objectives {
+		"cost" => min
+	}
+	nonfunctional_requirements {
+		req1 "Cost <= 200" max 200.0 => "cost";
+		req2 "Provider" values "AMAZ" => "provider";
+	}
+}
diff --git a/tests/doml/CaseStudies/uc3-openstack_v2.domlx b/tests/doml/CaseStudies/uc3-openstack_v2.domlx
new file mode 100644
index 0000000000000000000000000000000000000000..c5c4b51099d8b6e1cfb883b9ceba253c58ddbae7
--- /dev/null
+++ b/tests/doml/CaseStudies/uc3-openstack_v2.domlx
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="ASCII"?>
+<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" xmlns:optimization="http://www.piacere-project.eu/doml/optimization" name="uc3_openstack" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0">
+  <application name="app">
+    <components xsi:type="app:SoftwareComponent" name="iwg">
+      <exposedInterfaces name="net_info"/>
+    </components>
+    <components xsi:type="app:SoftwareComponent" name="osint" consumedInterfaces="//@application/@components.0/@exposedInterfaces.0 //@application/@components.3/@exposedInterfaces.0 //@application/@components.2/@exposedInterfaces.0">
+      <exposedInterfaces name="osint_info"/>
+    </components>
+    <components xsi:type="app:SoftwareComponent" name="ewcf">
+      <exposedInterfaces name="ewcf_rest_interface"/>
+    </components>
+    <components xsi:type="app:SaaS" name="external_twitter">
+      <exposedInterfaces name="get_twitter" endPoint="https://twitter_api/get"/>
+    </components>
+  </application>
+  <infrastructure name="infra">
+    <nodes xsi:type="infra:Container" name="c" generatedFrom="//@infrastructure/@generators.1">
+      <configs container_port="80" vm_port="8080" host="//@infrastructure/@groups.0/@machineDefinition" iface="//@infrastructure/@groups.0/@machineDefinition/@ifaces.2">
+        <annotations xsi:type="commons:SProperty" key="env_var1" value="value1"/>
+      </configs>
+    </nodes>
+    <generators xsi:type="infra:VMImage" name="v_img1" generatedVMs="//@infrastructure/@groups.0/@machineDefinition"/>
+    <generators xsi:type="infra:ContainerImage" name="c_img" uri="web-app:0.1.0" kind="IMAGE" generatedContainers="//@infrastructure/@nodes.0"/>
+    <generators xsi:type="infra:VMImage" name="v_img2" generatedVMs="//@infrastructure/@groups.1/@machineDefinition"/>
+    <generators xsi:type="infra:VMImage" name="v_img3" generatedVMs="//@infrastructure/@groups.2/@machineDefinition"/>
+    <credentials xsi:type="commons:KeyPair" name="ssh_key" user="ubuntu" keyfile="/home/user1/.ssh/openstack.key" algorithm="RSA" bits="4096"/>
+    <groups xsi:type="infra:AutoScalingGroup" name="osint_ag">
+      <machineDefinition name="osint_vm" os="ubuntu-20.04.3" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.0">
+        <ifaces name="osint_vm_net1" belongsTo="//@infrastructure/@networks.0"/>
+        <ifaces name="osint_vm_oam" belongsTo="//@infrastructure/@networks.3"/>
+        <ifaces name="osint_igw_port" belongsTo="//@infrastructure/@networks.0"/>
+      </machineDefinition>
+    </groups>
+    <groups xsi:type="infra:AutoScalingGroup" name="igw_ag">
+      <machineDefinition name="igw_vm" os="ubuntu-20.04.3" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.2">
+        <ifaces name="igw_vm_net2" belongsTo="//@infrastructure/@networks.1"/>
+        <ifaces name="igw_vm_oam" belongsTo="//@infrastructure/@networks.3"/>
+      </machineDefinition>
+    </groups>
+    <groups xsi:type="infra:AutoScalingGroup" name="ewcf_ag">
+      <machineDefinition name="ewcf_vm" os="ubuntu-20.04.3" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.3">
+        <ifaces name="ewcf_vm_net3" belongsTo="//@infrastructure/@networks.2"/>
+        <ifaces name="ewcf_vm_oam" belongsTo="//@infrastructure/@networks.3"/>
+      </machineDefinition>
+    </groups>
+    <securityGroups name="sg">
+      <rules name="icmp" protocol="icmp" fromPort="-1" toPort="-1">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="https" kind="INGRESS" protocol="tcp" fromPort="443" toPort="443">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="ssh" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+    </securityGroups>
+    <networks name="net1" protocol="tcp/ip" addressRange="/24" connectedIfaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0 //@infrastructure/@groups.0/@machineDefinition/@ifaces.2"/>
+    <networks name="net2" protocol="tcp/ip" addressRange="/24" connectedIfaces="//@infrastructure/@groups.1/@machineDefinition/@ifaces.0"/>
+    <networks name="net3" protocol="tcp/ip" addressRange="/24" connectedIfaces="//@infrastructure/@groups.2/@machineDefinition/@ifaces.0"/>
+    <networks name="oam" protocol="tcp/ip" addressRange="/24" connectedIfaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.1 //@infrastructure/@groups.1/@machineDefinition/@ifaces.1 //@infrastructure/@groups.2/@machineDefinition/@ifaces.1"/>
+  </infrastructure>
+  <concretizations name="con_infra">
+    <providers name="openstack">
+      <vms name="concrete_osint_vm" maps="//@infrastructure/@groups.0/@machineDefinition">
+        <annotations xsi:type="commons:SProperty" key="vm_name" value="osint"/>
+        <annotations xsi:type="commons:SProperty" key="vm_flavor" value="small"/>
+        <annotations xsi:type="commons:SProperty" key="vm_key_name" value="user1"/>
+      </vms>
+      <vms name="concrete_igw_vm" maps="//@infrastructure/@groups.1/@machineDefinition">
+        <annotations xsi:type="commons:SProperty" key="vm_name" value="igw"/>
+        <annotations xsi:type="commons:SProperty" key="vm_flavor" value="small"/>
+        <annotations xsi:type="commons:SProperty" key="vm_key_name" value="user1"/>
+      </vms>
+      <vms name="concrete_ewcf_vm" maps="//@infrastructure/@groups.2/@machineDefinition">
+        <annotations xsi:type="commons:SProperty" key="vm_name" value="ewcf"/>
+        <annotations xsi:type="commons:SProperty" key="vm_flavor" value="small"/>
+        <annotations xsi:type="commons:SProperty" key="vm_key_name" value="user1"/>
+      </vms>
+      <vmImages name="concrete_vm_image1" maps="//@infrastructure/@generators.0">
+        <annotations xsi:type="commons:SProperty" key="name" value="ubuntu-20.04.3"/>
+      </vmImages>
+      <vmImages name="concrete_vm_image2" maps="//@infrastructure/@generators.2">
+        <annotations xsi:type="commons:SProperty" key="name" value="ubuntu-20.04.3"/>
+      </vmImages>
+      <vmImages name="concrete_vm_image3" maps="//@infrastructure/@generators.3">
+        <annotations xsi:type="commons:SProperty" key="name" value="ubuntu-20.04.3"/>
+      </vmImages>
+      <networks name="concrete_net1" maps="//@infrastructure/@networks.0">
+        <annotations xsi:type="commons:SProperty" key="name" value="uc3_net1"/>
+      </networks>
+      <networks name="concrete_net2" maps="//@infrastructure/@networks.1">
+        <annotations xsi:type="commons:SProperty" key="name" value="uc3_net2"/>
+      </networks>
+      <networks name="concrete_net3" maps="//@infrastructure/@networks.2">
+        <annotations xsi:type="commons:SProperty" key="name" value="uc3_net3"/>
+      </networks>
+      <networks name="concrete_net4" maps="//@infrastructure/@networks.3">
+        <annotations xsi:type="commons:SProperty" key="name" value="uc3_net4"/>
+      </networks>
+    </providers>
+  </concretizations>
+  <optimization name="opt">
+    <objectives xsi:type="optimization:MeasurableObjective" kind="min" property="cost"/>
+    <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req1" description="Cost &lt;= 200" property="cost" max="200.0"/>
+    <nonfunctionalRequirements xsi:type="commons:EnumeratedRequirement" name="req2" description="Provider" property="provider">
+      <values>AMAZ</values>
+    </nonfunctionalRequirements>
+  </optimization>
+  <configurations name="conf">
+    <deployments component="//@application/@components.1" node="//@infrastructure/@groups.0/@machineDefinition"/>
+    <deployments component="//@application/@components.0" node="//@infrastructure/@groups.1/@machineDefinition"/>
+    <deployments component="//@application/@components.2" node="//@infrastructure/@groups.2/@machineDefinition"/>
+  </configurations>
+</commons:DOMLModel>
diff --git a/tests/doml/faas.domlx b/tests/doml/v2.0/faas.domlx
similarity index 93%
rename from tests/doml/faas.domlx
rename to tests/doml/v2.0/faas.domlx
index 50fafa4299dd28908012940b90411b7c45f032f5..762211b480b4c11552bc30c093fd458419d63465 100644
--- a/tests/doml/faas.domlx
+++ b/tests/doml/v2.0/faas.domlx
@@ -19,21 +19,18 @@
     </components>
   </application>
   <infrastructure name="infra">
-    <nodes xsi:type="infra:VirtualMachine" name="vm1" credentials="//@infrastructure/@credentials.0" group="//@infrastructure/@groups.0" generatedFrom="//@infrastructure/@generators.0">
-      <ifaces name="i1" endPoint="10.0.0.1" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@groups.0"/>
+    <nodes xsi:type="infra:VirtualMachine" name="vm1" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.0">
+      <ifaces name="i1" endPoint="10.0.0.1" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/>
       <location region="eu-central-1"/>
     </nodes>
     <nodes xsi:type="infra:Container" name="c" generatedFrom="//@infrastructure/@generators.1" hosts="//@infrastructure/@nodes.0"/>
-    <networks name="vpc" protocol="tcp/ip" addressRange="10.0.0.0/24" connectedIfaces="//@infrastructure/@nodes.0/@ifaces.0">
-      <subnets name="vpc_subnet" protocol="tcp/ip" addressRange="10.0.0.0/24"/>
-    </networks>
     <generators xsi:type="infra:VMImage" name="v_img" uri="ami-xxxxxxxxxxxxxxxxx" kind="IMAGE" generatedVMs="//@infrastructure/@nodes.0"/>
     <generators xsi:type="infra:ContainerImage" name="c_img" uri="web-app:0.1.0" kind="IMAGE" generatedContainers="//@infrastructure/@nodes.1"/>
     <storages name="st1"/>
     <storages name="st2"/>
     <faas name="f"/>
     <credentials xsi:type="infra:KeyPair" name="ssh_key" user="ec2-user" keyfile="/tmp/ssh_key_file" algorithm="RSA" bits="4096"/>
-    <groups xsi:type="infra:SecurityGroup" name="sg" groupedNodes="//@infrastructure/@nodes.0" ifaces="//@infrastructure/@nodes.0/@ifaces.0">
+    <securityGroups name="sg" ifaces="//@infrastructure/@nodes.0/@ifaces.0">
       <rules name="icmp" protocol="icmp" fromPort="-1" toPort="-1">
         <cidr>0.0.0.0/0</cidr>
       </rules>
@@ -46,7 +43,10 @@
       <rules name="ssh" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22">
         <cidr>0.0.0.0/0</cidr>
       </rules>
-    </groups>
+    </securityGroups>
+    <networks name="vpc" protocol="tcp/ip" addressRange="10.0.0.0/24" connectedIfaces="//@infrastructure/@nodes.0/@ifaces.0">
+      <subnets name="vpc_subnet" protocol="tcp/ip" addressRange="10.0.0.0/24"/>
+    </networks>
   </infrastructure>
   <concretizations name="con_infra">
     <providers name="aws">
diff --git a/tests/doml/nginx-openstack_v2.domlx b/tests/doml/v2.0/nginx-openstack_v2.0.domlx
similarity index 80%
rename from tests/doml/nginx-openstack_v2.domlx
rename to tests/doml/v2.0/nginx-openstack_v2.0.domlx
index e10fe0e6891f622a91b3b530fe9f82aa4e7e6d03..dbce61fd3084fc01aef2d6d9faefa59222867824 100644
--- a/tests/doml/nginx-openstack_v2.domlx
+++ b/tests/doml/v2.0/nginx-openstack_v2.0.domlx
@@ -6,15 +6,14 @@
     </components>
   </application>
   <infrastructure name="infra">
-    <nodes xsi:type="infra:AutoScalingGroup" name="ag" deploymentNetwork="//@infrastructure/@networks.0">
-      <machineDefinition name="vm1" os="ubuntu-20.04.3" credentials="//@infrastructure/@credentials.0" group="//@infrastructure/@groups.0" generatedFrom="//@infrastructure/@generators.0">
-        <ifaces name="i1" endPoint="16.0.0.1" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@groups.0"/>
-      </machineDefinition>
-    </nodes>
-    <networks name="net1" protocol="tcp/ip" addressRange="16.0.0.0/24" connectedIfaces="//@infrastructure/@nodes.0/@machineDefinition/@ifaces.0"/>
-    <generators xsi:type="infra:VMImage" name="v_img" generatedVMs="//@infrastructure/@nodes.0/@machineDefinition"/>
+    <generators xsi:type="infra:VMImage" name="v_img" generatedVMs="//@infrastructure/@groups.0/@machineDefinition"/>
     <credentials xsi:type="infra:KeyPair" name="ssh_key" user="ubuntu" keyfile="/home/user1/.ssh/openstack.key" algorithm="RSA" bits="4096"/>
-    <groups xsi:type="infra:SecurityGroup" name="sg" groupedNodes="//@infrastructure/@nodes.0/@machineDefinition" ifaces="//@infrastructure/@nodes.0/@machineDefinition/@ifaces.0">
+    <groups xsi:type="infra:AutoScalingGroup" name="ag" deploymentNetwork="//@infrastructure/@networks.0">
+      <machineDefinition name="vm1" os="ubuntu-20.04.3" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.0">
+        <ifaces name="i1" endPoint="16.0.0.1" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/>
+      </machineDefinition>
+    </groups>
+    <securityGroups name="sg" ifaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0">
       <rules name="icmp" protocol="icmp" fromPort="-1" toPort="-1">
         <cidr>0.0.0.0/0</cidr>
       </rules>
@@ -27,11 +26,12 @@
       <rules name="ssh" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22">
         <cidr>0.0.0.0/0</cidr>
       </rules>
-    </groups>
+    </securityGroups>
+    <networks name="net1" protocol="tcp/ip" addressRange="16.0.0.0/24" connectedIfaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0"/>
   </infrastructure>
   <concretizations name="con_infra">
     <providers name="openstack">
-      <vms name="concrete_vm" maps="//@infrastructure/@nodes.0/@machineDefinition">
+      <vms name="concrete_vm" maps="//@infrastructure/@groups.0/@machineDefinition">
         <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/>
         <annotations xsi:type="commons:SProperty" key="vm_flavor" value="small"/>
         <annotations xsi:type="commons:SProperty" key="vm_key_name" value="user1"/>
@@ -52,6 +52,6 @@
     </nonfunctionalRequirements>
   </optimization>
   <configurations name="config">
-    <deployments component="//@application/@components.0" node="//@infrastructure/@nodes.0/@machineDefinition"/>
+    <deployments component="//@application/@components.0" node="//@infrastructure/@groups.0/@machineDefinition"/>
   </configurations>
 </commons:DOMLModel>
diff --git a/tests/doml/v2.0/nginx-openstack_v2.0_valid_mem_req.domlx b/tests/doml/v2.0/nginx-openstack_v2.0_valid_mem_req.domlx
new file mode 100644
index 0000000000000000000000000000000000000000..79ba8b959d36aa642f1b3515e830e80af943e4aa
--- /dev/null
+++ b/tests/doml/v2.0/nginx-openstack_v2.0_valid_mem_req.domlx
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="ASCII"?>
+<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" xmlns:optimization="http://www.piacere-project.eu/doml/optimization" name="nginx_openstack" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0">
+  <application name="app">
+    <components xsi:type="app:SoftwareComponent" name="nginx">
+      <annotations xsi:type="commons:SProperty" key="source_code" value="/usr/share/nginx/html/index.html"/>
+    </components>
+  </application>
+  <infrastructure name="infra">
+    <generators xsi:type="infra:VMImage" name="v_img" generatedVMs="//@infrastructure/@groups.0/@machineDefinition"/>
+    <credentials xsi:type="infra:KeyPair" name="ssh_key" user="ubuntu" keyfile="/home/user1/.ssh/openstack.key" algorithm="RSA" bits="4096"/>
+    <groups xsi:type="infra:AutoScalingGroup" name="ag" deploymentNetwork="//@infrastructure/@networks.0">
+      <machineDefinition name="vm1" os="ubuntu-20.04.3" memory_mb="512.0" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.0">
+        <ifaces name="i1" endPoint="16.0.0.1" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/>
+      </machineDefinition>
+    </groups>
+    <securityGroups name="sg" ifaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0">
+      <rules name="icmp" protocol="icmp" fromPort="-1" toPort="-1">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="https" kind="INGRESS" protocol="tcp" fromPort="443" toPort="443">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="ssh" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+    </securityGroups>
+    <networks name="net1" protocol="tcp/ip" addressRange="16.0.0.0/24" connectedIfaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0"/>
+  </infrastructure>
+  <concretizations name="con_infra">
+    <providers name="openstack">
+      <vms name="concrete_vm" maps="//@infrastructure/@groups.0/@machineDefinition">
+        <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/>
+        <annotations xsi:type="commons:SProperty" key="vm_flavor" value="small"/>
+        <annotations xsi:type="commons:SProperty" key="vm_key_name" value="user1"/>
+      </vms>
+      <vmImages name="concrete_vm_image" maps="//@infrastructure/@generators.0">
+        <annotations xsi:type="commons:SProperty" key="name" value="ubuntu-20.04.3"/>
+      </vmImages>
+      <networks name="concrete_net" maps="//@infrastructure/@networks.0">
+        <annotations xsi:type="commons:SProperty" key="name" value="ostack2"/>
+      </networks>
+    </providers>
+  </concretizations>
+  <optimization name="opt">
+    <objectives xsi:type="optimization:MeasurableObjective" kind="min" property="cost"/>
+    <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req1" description="Cost &lt;= 200" property="cost" max="200.0"/>
+    <nonfunctionalRequirements xsi:type="commons:EnumeratedRequirement" name="req2" description="Provider" property="provider">
+      <values>AMAZ</values>
+    </nonfunctionalRequirements>
+  </optimization>
+  <configurations name="config">
+    <deployments component="//@application/@components.0" node="//@infrastructure/@groups.0/@machineDefinition"/>
+  </configurations>
+</commons:DOMLModel>
diff --git a/tests/doml/v2.0/nginx-openstack_v2.0_wrong_all_concrete_map_something.doml b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_all_concrete_map_something.doml
new file mode 100644
index 0000000000000000000000000000000000000000..9e8898179af5adc749f9e926ef31bc37cd1fa1c7
--- /dev/null
+++ b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_all_concrete_map_something.doml
@@ -0,0 +1,116 @@
+doml nginx_openstack
+
+application app {
+
+	software_component nginx {
+		properties {
+			source_code="/usr/share/nginx/html/index.html";
+		}
+	}
+}
+
+infrastructure infra {
+
+	vm_image v_img {
+		generates vm1
+	}
+
+	net net1 {
+		address "16.0.0.0/24"
+		protocol "tcp/ip"
+	}
+
+	security_group sg {
+		egress icmp {
+			from_port -1
+			to_port -1
+			protocol "icmp"
+			cidr ["0.0.0.0/0"]
+		}
+		ingress http {
+			from_port 80
+			to_port 80
+			protocol "tcp"
+			cidr ["0.0.0.0/0"]
+		}
+		ingress https {
+			from_port 443
+			to_port 443
+			protocol "tcp"
+			cidr ["0.0.0.0/0"]
+		}
+		ingress ssh {
+			from_port 22
+			to_port 22
+			protocol "tcp"
+			cidr ["0.0.0.0/0"]
+		}
+		ifaces i1
+	}
+
+	key_pair ssh_key {
+		user "ubuntu"
+		keyfile "/home/user1/.ssh/openstack.key"
+		algorithm "RSA"
+		bits 4096
+	}
+
+	autoscale_group ag { 
+		vm vm1 {
+			os "ubuntu-20.04.3"
+			iface i1 {
+				address "16.0.0.1"
+				belongs_to net1
+				security sg
+			}
+			credentials ssh_key
+		}
+		network net1
+	}
+}
+
+deployment config {
+	nginx -> vm1
+}
+
+active deployment config
+
+concretizations {
+	concrete_infrastructure con_infra {
+		provider openstack {
+			vm concrete_vm {
+				properties {
+					vm_name = "nginx-host";
+					vm_flavor = "small";
+					vm_key_name = "user1";
+				}
+				maps vm1
+			}
+
+			vm_image concrete_vm_image {
+				properties {
+					name = "ubuntu-20.04.3";
+				}
+//				maps v_img
+			}
+
+			net concrete_net {
+				properties {
+					name = "ostack2";
+				}
+				maps net1
+			}
+		}
+	}
+	active con_infra
+}
+
+optimization opt {
+	objectives {
+		"cost" => min
+	}
+	nonfunctional_requirements {
+		req1 "Cost <= 200" max 200.0 => "cost";
+		req2 "Provider" values "AMAZ" => "provider";
+	}
+}
diff --git a/tests/doml/v2.0/nginx-openstack_v2.0_wrong_all_concrete_map_something.domlx b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_all_concrete_map_something.domlx
new file mode 100644
index 0000000000000000000000000000000000000000..1aa558215b46ed384d83fc238e6965a1ca8e4915
--- /dev/null
+++ b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_all_concrete_map_something.domlx
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="ASCII"?>
+<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" xmlns:optimization="http://www.piacere-project.eu/doml/optimization" name="nginx_openstack" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0">
+  <application name="app">
+    <components xsi:type="app:SoftwareComponent" name="nginx">
+      <annotations xsi:type="commons:SProperty" key="source_code" value="/usr/share/nginx/html/index.html"/>
+    </components>
+  </application>
+  <infrastructure name="infra">
+    <generators xsi:type="infra:VMImage" name="v_img" generatedVMs="//@infrastructure/@groups.0/@machineDefinition"/>
+    <credentials xsi:type="infra:KeyPair" name="ssh_key" user="ubuntu" keyfile="/home/user1/.ssh/openstack.key" algorithm="RSA" bits="4096"/>
+    <groups xsi:type="infra:AutoScalingGroup" name="ag" deploymentNetwork="//@infrastructure/@networks.0">
+      <machineDefinition name="vm1" os="ubuntu-20.04.3" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.0">
+        <ifaces name="i1" endPoint="16.0.0.1" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/>
+      </machineDefinition>
+    </groups>
+    <securityGroups name="sg" ifaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0">
+      <rules name="icmp" protocol="icmp" fromPort="-1" toPort="-1">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="https" kind="INGRESS" protocol="tcp" fromPort="443" toPort="443">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="ssh" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+    </securityGroups>
+    <networks name="net1" protocol="tcp/ip" addressRange="16.0.0.0/24" connectedIfaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0"/>
+  </infrastructure>
+  <concretizations name="con_infra">
+    <providers name="openstack">
+      <vms name="concrete_vm" maps="//@infrastructure/@groups.0/@machineDefinition">
+        <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/>
+        <annotations xsi:type="commons:SProperty" key="vm_flavor" value="small"/>
+        <annotations xsi:type="commons:SProperty" key="vm_key_name" value="user1"/>
+      </vms>
+      <vmImages name="concrete_vm_image">
+        <annotations xsi:type="commons:SProperty" key="name" value="ubuntu-20.04.3"/>
+      </vmImages>
+      <networks name="concrete_net" maps="//@infrastructure/@networks.0">
+        <annotations xsi:type="commons:SProperty" key="name" value="ostack2"/>
+      </networks>
+    </providers>
+  </concretizations>
+  <optimization name="opt">
+    <objectives xsi:type="optimization:MeasurableObjective" kind="min" property="cost"/>
+    <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req1" description="Cost &lt;= 200" property="cost" max="200.0"/>
+    <nonfunctionalRequirements xsi:type="commons:EnumeratedRequirement" name="req2" description="Provider" property="provider">
+      <values>AMAZ</values>
+    </nonfunctionalRequirements>
+  </optimization>
+  <configurations name="config">
+    <deployments component="//@application/@components.0" node="//@infrastructure/@groups.0/@machineDefinition"/>
+  </configurations>
+</commons:DOMLModel>
diff --git a/tests/doml/v2.0/nginx-openstack_v2.0_wrong_all_infrastructure_elements_deployed.doml b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_all_infrastructure_elements_deployed.doml
new file mode 100644
index 0000000000000000000000000000000000000000..a5b2c726487f97700696ed9b9b2d0f5a2eac3611
--- /dev/null
+++ b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_all_infrastructure_elements_deployed.doml
@@ -0,0 +1,109 @@
+doml nginx_openstack
+
+application app {
+
+	software_component nginx {
+		properties {
+			source_code="/usr/share/nginx/html/index.html";
+		}
+	}
+}
+
+infrastructure infra {
+
+	vm_image v_img {
+		generates vm1
+	}
+
+	net net1 {
+		address "16.0.0.0/24"
+		protocol "tcp/ip"
+	}
+
+	security_group sg {
+		egress icmp {
+			from_port -1
+			to_port -1
+			protocol "icmp"
+			cidr ["0.0.0.0/0"]
+		}
+		ingress http {
+			from_port 80
+			to_port 80
+			protocol "tcp"
+			cidr ["0.0.0.0/0"]
+		}
+		ingress https {
+			from_port 443
+			to_port 443
+			protocol "tcp"
+			cidr ["0.0.0.0/0"]
+		}
+		ingress ssh {
+			from_port 22
+			to_port 22
+			protocol "tcp"
+			cidr ["0.0.0.0/0"]
+		}
+		ifaces i1
+	}
+
+	key_pair ssh_key {
+		user "ubuntu"
+		keyfile "/home/user1/.ssh/openstack.key"
+		algorithm "RSA"
+		bits 4096
+	}
+
+	autoscale_group ag { 
+		vm vm1 {
+			os "ubuntu-20.04.3"
+			iface i1 {
+				address "16.0.0.1"
+				belongs_to net1
+				security sg
+			}
+			credentials ssh_key
+		}
+		network net1
+	}
+}
+
+deployment config {
+	nginx -> vm1
+}
+
+active deployment config
+
+concretizations {
+	concrete_infrastructure con_infra {
+		provider openstack {
+			vm concrete_vm {
+				properties {
+					vm_name = "nginx-host";
+					vm_flavor = "small";
+					vm_key_name = "user1";
+				}
+				maps vm1
+			}
+
+			vm_image concrete_vm_image {
+				properties {
+					name = "ubuntu-20.04.3";
+				}
+				maps v_img
+			}
+		}
+	}
+	active con_infra
+}
+
+optimization opt {
+	objectives {
+		"cost" => min
+	}
+	nonfunctional_requirements {
+		req1 "Cost <= 200" max 200.0 => "cost";
+		req2 "Provider" values "AMAZ" => "provider";
+	}
+}
diff --git a/tests/doml/v2.0/nginx-openstack_v2.0_wrong_all_infrastructure_elements_deployed.domlx b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_all_infrastructure_elements_deployed.domlx
new file mode 100644
index 0000000000000000000000000000000000000000..fdcdb0aaf97924d9cad2e601d85b55bf64db8e28
--- /dev/null
+++ b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_all_infrastructure_elements_deployed.domlx
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="ASCII"?>
+<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" xmlns:optimization="http://www.piacere-project.eu/doml/optimization" name="nginx_openstack" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0">
+  <application name="app">
+    <components xsi:type="app:SoftwareComponent" name="nginx">
+      <annotations xsi:type="commons:SProperty" key="source_code" value="/usr/share/nginx/html/index.html"/>
+    </components>
+  </application>
+  <infrastructure name="infra">
+    <generators xsi:type="infra:VMImage" name="v_img" generatedVMs="//@infrastructure/@groups.0/@machineDefinition"/>
+    <credentials xsi:type="infra:KeyPair" name="ssh_key" user="ubuntu" keyfile="/home/user1/.ssh/openstack.key" algorithm="RSA" bits="4096"/>
+    <groups xsi:type="infra:AutoScalingGroup" name="ag" deploymentNetwork="//@infrastructure/@networks.0">
+      <machineDefinition name="vm1" os="ubuntu-20.04.3" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.0">
+        <ifaces name="i1" endPoint="16.0.0.1" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/>
+      </machineDefinition>
+    </groups>
+    <securityGroups name="sg" ifaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0">
+      <rules name="icmp" protocol="icmp" fromPort="-1" toPort="-1">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="https" kind="INGRESS" protocol="tcp" fromPort="443" toPort="443">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="ssh" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+    </securityGroups>
+    <networks name="net1" protocol="tcp/ip" addressRange="16.0.0.0/24" connectedIfaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0"/>
+  </infrastructure>
+  <concretizations name="con_infra">
+    <providers name="openstack">
+      <vms name="concrete_vm" maps="//@infrastructure/@groups.0/@machineDefinition">
+        <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/>
+        <annotations xsi:type="commons:SProperty" key="vm_flavor" value="small"/>
+        <annotations xsi:type="commons:SProperty" key="vm_key_name" value="user1"/>
+      </vms>
+      <vmImages name="concrete_vm_image" maps="//@infrastructure/@generators.0">
+        <annotations xsi:type="commons:SProperty" key="name" value="ubuntu-20.04.3"/>
+      </vmImages>
+    </providers>
+  </concretizations>
+  <optimization name="opt">
+    <objectives xsi:type="optimization:MeasurableObjective" kind="min" property="cost"/>
+    <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req1" description="Cost &lt;= 200" property="cost" max="200.0"/>
+    <nonfunctionalRequirements xsi:type="commons:EnumeratedRequirement" name="req2" description="Provider" property="provider">
+      <values>AMAZ</values>
+    </nonfunctionalRequirements>
+  </optimization>
+  <configurations name="config">
+    <deployments component="//@application/@components.0" node="//@infrastructure/@groups.0/@machineDefinition"/>
+  </configurations>
+</commons:DOMLModel>
diff --git a/tests/doml/v2.0/nginx-openstack_v2.0_wrong_all_software_components_deployed.doml b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_all_software_components_deployed.doml
new file mode 100644
index 0000000000000000000000000000000000000000..5a904e851e1adbd9574b6901877eae93c31cab36
--- /dev/null
+++ b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_all_software_components_deployed.doml
@@ -0,0 +1,115 @@
+doml nginx_openstack
+
+application app {
+
+	software_component nginx {
+		properties {
+			source_code="/usr/share/nginx/html/index.html";
+		}
+	}
+}
+
+infrastructure infra {
+
+	vm_image v_img {
+		generates vm1
+	}
+
+	net net1 {
+		address "16.0.0.0/24"
+		protocol "tcp/ip"
+	}
+
+	security_group sg {
+		egress icmp {
+			from_port -1
+			to_port -1
+			protocol "icmp"
+			cidr ["0.0.0.0/0"]
+		}
+		ingress http {
+			from_port 80
+			to_port 80
+			protocol "tcp"
+			cidr ["0.0.0.0/0"]
+		}
+		ingress https {
+			from_port 443
+			to_port 443
+			protocol "tcp"
+			cidr ["0.0.0.0/0"]
+		}
+		ingress ssh {
+			from_port 22
+			to_port 22
+			protocol "tcp"
+			cidr ["0.0.0.0/0"]
+		}
+		ifaces i1
+	}
+
+	key_pair ssh_key {
+		user "ubuntu"
+		keyfile "/home/user1/.ssh/openstack.key"
+		algorithm "RSA"
+		bits 4096
+	}
+
+	autoscale_group ag { 
+		vm vm1 {
+			os "ubuntu-20.04.3"
+			iface i1 {
+				address "16.0.0.1"
+				belongs_to net1
+				security sg
+			}
+			credentials ssh_key
+		}
+		network net1
+	}
+}
+
+deployment config {
+}
+
+active deployment config
+
+concretizations {
+	concrete_infrastructure con_infra {
+		provider openstack {
+			vm concrete_vm {
+				properties {
+					vm_name = "nginx-host";
+					vm_flavor = "small";
+					vm_key_name = "user1";
+				}
+				maps vm1
+			}
+
+			vm_image concrete_vm_image {
+				properties {
+					name = "ubuntu-20.04.3";
+				}
+				maps v_img
+			}
+
+			net concrete_net {
+				properties {
+					name = "ostack2";
+				}
+				maps net1
+			}
+		}
+	}
+	active con_infra
+}
+
+optimization opt {
+	objectives {
+		"cost" => min
+	}
+	nonfunctional_requirements {
+		req1 "Cost <= 200" max 200.0 => "cost";
+		req2 "Provider" values "AMAZ" => "provider";
+	}
+}
diff --git a/tests/doml/v2.0/nginx-openstack_v2.0_wrong_all_software_components_deployed.domlx b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_all_software_components_deployed.domlx
new file mode 100644
index 0000000000000000000000000000000000000000..4aef2e31e11bd523bc5c7afd94aa0f8d4ffeaea0
--- /dev/null
+++ b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_all_software_components_deployed.domlx
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="ASCII"?>
+<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" xmlns:optimization="http://www.piacere-project.eu/doml/optimization" name="nginx_openstack" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0">
+  <application name="app">
+    <components xsi:type="app:SoftwareComponent" name="nginx">
+      <annotations xsi:type="commons:SProperty" key="source_code" value="/usr/share/nginx/html/index.html"/>
+    </components>
+  </application>
+  <infrastructure name="infra">
+    <generators xsi:type="infra:VMImage" name="v_img" generatedVMs="//@infrastructure/@groups.0/@machineDefinition"/>
+    <credentials xsi:type="infra:KeyPair" name="ssh_key" user="ubuntu" keyfile="/home/user1/.ssh/openstack.key" algorithm="RSA" bits="4096"/>
+    <groups xsi:type="infra:AutoScalingGroup" name="ag" deploymentNetwork="//@infrastructure/@networks.0">
+      <machineDefinition name="vm1" os="ubuntu-20.04.3" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.0">
+        <ifaces name="i1" endPoint="16.0.0.1" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/>
+      </machineDefinition>
+    </groups>
+    <securityGroups name="sg" ifaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0">
+      <rules name="icmp" protocol="icmp" fromPort="-1" toPort="-1">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="https" kind="INGRESS" protocol="tcp" fromPort="443" toPort="443">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="ssh" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+    </securityGroups>
+    <networks name="net1" protocol="tcp/ip" addressRange="16.0.0.0/24" connectedIfaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0"/>
+  </infrastructure>
+  <concretizations name="con_infra">
+    <providers name="openstack">
+      <vms name="concrete_vm" maps="//@infrastructure/@groups.0/@machineDefinition">
+        <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/>
+        <annotations xsi:type="commons:SProperty" key="vm_flavor" value="small"/>
+        <annotations xsi:type="commons:SProperty" key="vm_key_name" value="user1"/>
+      </vms>
+      <vmImages name="concrete_vm_image" maps="//@infrastructure/@generators.0">
+        <annotations xsi:type="commons:SProperty" key="name" value="ubuntu-20.04.3"/>
+      </vmImages>
+      <networks name="concrete_net" maps="//@infrastructure/@networks.0">
+        <annotations xsi:type="commons:SProperty" key="name" value="ostack2"/>
+      </networks>
+    </providers>
+  </concretizations>
+  <optimization name="opt">
+    <objectives xsi:type="optimization:MeasurableObjective" kind="min" property="cost"/>
+    <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req1" description="Cost &lt;= 200" property="cost" max="200.0"/>
+    <nonfunctionalRequirements xsi:type="commons:EnumeratedRequirement" name="req2" description="Provider" property="provider">
+      <values>AMAZ</values>
+    </nonfunctionalRequirements>
+  </optimization>
+  <configurations name="config"/>
+</commons:DOMLModel>
diff --git a/tests/doml/v2.0/nginx-openstack_v2.0_wrong_iface_uniq.doml b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_iface_uniq.doml
new file mode 100644
index 0000000000000000000000000000000000000000..669563db1b6d2b52750af12312c973938f968d6a
--- /dev/null
+++ b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_iface_uniq.doml
@@ -0,0 +1,135 @@
+doml nginx_openstack
+
+application app {
+
+	software_component nginx {
+		properties {
+			source_code="/usr/share/nginx/html/index.html";
+		}
+	}
+}
+
+infrastructure infra {
+
+	vm_image v_img {
+		generates vm1
+	}
+
+	net net1 {
+		address "16.0.0.0/24"
+		protocol "tcp/ip"
+	}
+
+	security_group sg {
+		egress icmp {
+			from_port -1
+			to_port -1
+			protocol "icmp"
+			cidr ["0.0.0.0/0"]
+		}
+		ingress http {
+			from_port 80
+			to_port 80
+			protocol "tcp"
+			cidr ["0.0.0.0/0"]
+		}
+		ingress https {
+			from_port 443
+			to_port 443
+			protocol "tcp"
+			cidr ["0.0.0.0/0"]
+		}
+		ingress ssh {
+			from_port 22
+			to_port 22
+			protocol "tcp"
+			cidr ["0.0.0.0/0"]
+		}
+		ifaces i1
+	}
+
+	key_pair ssh_key {
+		user "ubuntu"
+		keyfile "/home/user1/.ssh/openstack.key"
+		algorithm "RSA"
+		bits 4096
+	}
+
+	autoscale_group ag { 
+		vm vm1 {
+			os "ubuntu-20.04.3"
+			iface i1 {
+				address "16.0.0.1"
+				belongs_to net1
+				security sg
+			}
+			credentials ssh_key
+		}
+		network net1
+	}
+	
+	vm vm2 {
+		os "ubuntu-20.04.3"
+		iface i1 {
+			address "16.0.0.1"
+			belongs_to net1
+			security sg
+		}
+		credentials ssh_key
+	}
+}
+
+deployment config {
+	nginx -> vm1
+}
+
+active deployment config
+
+concretizations {
+	concrete_infrastructure con_infra {
+		provider openstack {
+			vm concrete_vm {
+				properties {
+					vm_name = "nginx-host";
+					vm_flavor = "small";
+					vm_key_name = "user1";
+				}
+				maps vm1
+			}
+			
+			vm concrete_vm2 {
+				properties {
+					vm_name = "nginx-host";
+					vm_flavor = "small";
+					vm_key_name = "user1";
+				}
+				maps vm2
+			}
+
+			vm_image concrete_vm_image {
+				properties {
+					name = "ubuntu-20.04.3";
+				}
+				maps v_img
+			}
+
+			net concrete_net {
+				properties {
+					name = "ostack2";
+				}
+				maps net1
+			}
+		}
+	}
+	active con_infra
+}
+
+optimization opt {
+	objectives {
+		"cost" => min
+	}
+	nonfunctional_requirements {
+		req1 "Cost <= 200" max 200.0 => "cost";
+		req2 "Provider" values "AMAZ" => "provider";
+	}
+}
diff --git a/tests/doml/v2.0/nginx-openstack_v2.0_wrong_iface_uniq.domlx b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_iface_uniq.domlx
new file mode 100644
index 0000000000000000000000000000000000000000..4d081ae996497723513f7fe380b4ebf1cc6fe652
--- /dev/null
+++ b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_iface_uniq.domlx
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="ASCII"?>
+<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" xmlns:optimization="http://www.piacere-project.eu/doml/optimization" name="nginx_openstack" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0">
+  <application name="app">
+    <components xsi:type="app:SoftwareComponent" name="nginx">
+      <annotations xsi:type="commons:SProperty" key="source_code" value="/usr/share/nginx/html/index.html"/>
+    </components>
+  </application>
+  <infrastructure name="infra">
+    <nodes xsi:type="infra:VirtualMachine" name="vm2" os="ubuntu-20.04.3" credentials="//@infrastructure/@credentials.0">
+      <ifaces name="i1" endPoint="16.0.0.1" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/>
+    </nodes>
+    <generators xsi:type="infra:VMImage" name="v_img" generatedVMs="//@infrastructure/@groups.0/@machineDefinition"/>
+    <credentials xsi:type="infra:KeyPair" name="ssh_key" user="ubuntu" keyfile="/home/user1/.ssh/openstack.key" algorithm="RSA" bits="4096"/>
+    <groups xsi:type="infra:AutoScalingGroup" name="ag" deploymentNetwork="//@infrastructure/@networks.0">
+      <machineDefinition name="vm1" os="ubuntu-20.04.3" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.0">
+        <ifaces name="i1" endPoint="16.0.0.1" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/>
+      </machineDefinition>
+    </groups>
+    <securityGroups name="sg" ifaces="//@infrastructure/@nodes.0/@ifaces.0 //@infrastructure/@groups.0/@machineDefinition/@ifaces.0">
+      <rules name="icmp" protocol="icmp" fromPort="-1" toPort="-1">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="https" kind="INGRESS" protocol="tcp" fromPort="443" toPort="443">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="ssh" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+    </securityGroups>
+    <networks name="net1" protocol="tcp/ip" addressRange="16.0.0.0/24" connectedIfaces="//@infrastructure/@nodes.0/@ifaces.0 //@infrastructure/@groups.0/@machineDefinition/@ifaces.0"/>
+  </infrastructure>
+  <concretizations name="con_infra">
+    <providers name="openstack">
+      <vms name="concrete_vm" maps="//@infrastructure/@groups.0/@machineDefinition">
+        <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/>
+        <annotations xsi:type="commons:SProperty" key="vm_flavor" value="small"/>
+        <annotations xsi:type="commons:SProperty" key="vm_key_name" value="user1"/>
+      </vms>
+      <vms name="concrete_vm2" maps="//@infrastructure/@nodes.0">
+        <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/>
+        <annotations xsi:type="commons:SProperty" key="vm_flavor" value="small"/>
+        <annotations xsi:type="commons:SProperty" key="vm_key_name" value="user1"/>
+      </vms>
+      <vmImages name="concrete_vm_image" maps="//@infrastructure/@generators.0">
+        <annotations xsi:type="commons:SProperty" key="name" value="ubuntu-20.04.3"/>
+      </vmImages>
+      <networks name="concrete_net" maps="//@infrastructure/@networks.0">
+        <annotations xsi:type="commons:SProperty" key="name" value="ostack2"/>
+      </networks>
+    </providers>
+  </concretizations>
+  <optimization name="opt">
+    <objectives xsi:type="optimization:MeasurableObjective" kind="min" property="cost"/>
+    <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req1" description="Cost &lt;= 200" property="cost" max="200.0"/>
+    <nonfunctionalRequirements xsi:type="commons:EnumeratedRequirement" name="req2" description="Provider" property="provider">
+      <values>AMAZ</values>
+    </nonfunctionalRequirements>
+  </optimization>
+  <configurations name="config">
+    <deployments component="//@application/@components.0" node="//@infrastructure/@groups.0/@machineDefinition"/>
+  </configurations>
+</commons:DOMLModel>
diff --git a/tests/doml/v2.0/nginx-openstack_v2.0_wrong_nginx_source_code.domlx b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_nginx_source_code.domlx
new file mode 100644
index 0000000000000000000000000000000000000000..455b90f55300e3a4d61b4c5d726a1224fa9d81dc
--- /dev/null
+++ b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_nginx_source_code.domlx
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="ASCII"?>
+<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" xmlns:optimization="http://www.piacere-project.eu/doml/optimization" name="nginx_openstack" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0">
+  <application name="app">
+    <components xsi:type="app:SoftwareComponent" name="nginx"/>
+  </application>
+  <infrastructure name="infra">
+    <generators xsi:type="infra:VMImage" name="v_img" generatedVMs="//@infrastructure/@groups.0/@machineDefinition"/>
+    <credentials xsi:type="infra:KeyPair" name="ssh_key" user="ubuntu" keyfile="/home/user1/.ssh/openstack.key" algorithm="RSA" bits="4096"/>
+    <groups xsi:type="infra:AutoScalingGroup" name="ag" deploymentNetwork="//@infrastructure/@networks.0">
+      <machineDefinition name="vm1" os="ubuntu-20.04.3" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.0">
+        <ifaces name="i1" endPoint="16.0.0.1" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/>
+      </machineDefinition>
+    </groups>
+    <securityGroups name="sg" ifaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0">
+      <rules name="icmp" protocol="icmp" fromPort="-1" toPort="-1">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="https" kind="INGRESS" protocol="tcp" fromPort="443" toPort="443">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="ssh" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+    </securityGroups>
+    <networks name="net1" protocol="tcp/ip" addressRange="16.0.0.0/24" connectedIfaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0"/>
+  </infrastructure>
+  <concretizations name="con_infra">
+    <providers name="openstack">
+      <vms name="concrete_vm" maps="//@infrastructure/@groups.0/@machineDefinition">
+        <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/>
+        <annotations xsi:type="commons:SProperty" key="vm_flavor" value="small"/>
+        <annotations xsi:type="commons:SProperty" key="vm_key_name" value="user1"/>
+      </vms>
+      <vmImages name="concrete_vm_image" maps="//@infrastructure/@generators.0">
+        <annotations xsi:type="commons:SProperty" key="name" value="ubuntu-20.04.3"/>
+      </vmImages>
+      <networks name="concrete_net" maps="//@infrastructure/@networks.0">
+        <annotations xsi:type="commons:SProperty" key="name" value="ostack2"/>
+      </networks>
+    </providers>
+  </concretizations>
+  <optimization name="opt">
+    <objectives xsi:type="optimization:MeasurableObjective" kind="min" property="cost"/>
+    <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req1" description="Cost &lt;= 200" property="cost" max="200.0"/>
+    <nonfunctionalRequirements xsi:type="commons:EnumeratedRequirement" name="req2" description="Provider" property="provider">
+      <values>AMAZ</values>
+    </nonfunctionalRequirements>
+  </optimization>
+  <configurations name="config">
+    <deployments component="//@application/@components.0" node="//@infrastructure/@groups.0/@machineDefinition"/>
+  </configurations>
+</commons:DOMLModel>
diff --git a/tests/doml/v2.0/nginx-openstack_v2.0_wrong_software_package_iface_net.doml b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_software_package_iface_net.doml
new file mode 100644
index 0000000000000000000000000000000000000000..916648c526658e199be3fb448bbf69ebdf5ec49e
--- /dev/null
+++ b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_software_package_iface_net.doml
@@ -0,0 +1,157 @@
+doml nginx_openstack
+
+application app {
+
+	software_component nginx {
+		properties {
+			source_code="/usr/share/nginx/html/index.html";
+		}
+		consumes {
+			database
+		}
+	}
+	
+	software_component db {
+		provides {
+			database
+		}
+	}
+}
+
+infrastructure infra {
+
+	vm_image v_img {
+		generates vm1
+	}
+
+	net net1 {
+		address "16.0.0.0/24"
+		protocol "tcp/ip"
+	}
+	
+	net net2 {
+		address "17.0.0.0/24"
+		protocol "tcp/ip"
+	}
+
+	security_group sg {
+		egress icmp {
+			from_port -1
+			to_port -1
+			protocol "icmp"
+			cidr ["0.0.0.0/0"]
+		}
+		ingress http {
+			from_port 80
+			to_port 80
+			protocol "tcp"
+			cidr ["0.0.0.0/0"]
+		}
+		ingress https {
+			from_port 443
+			to_port 443
+			protocol "tcp"
+			cidr ["0.0.0.0/0"]
+		}
+		ingress ssh {
+			from_port 22
+			to_port 22
+			protocol "tcp"
+			cidr ["0.0.0.0/0"]
+		}
+		ifaces i1
+	}
+
+	key_pair ssh_key {
+		user "ubuntu"
+		keyfile "/home/user1/.ssh/openstack.key"
+		algorithm "RSA"
+		bits 4096
+	}
+
+	autoscale_group ag { 
+		vm vm1 {
+			os "ubuntu-20.04.3"
+			iface i1 {
+				address "16.0.0.1"
+				belongs_to net1
+				security sg
+			}
+			credentials ssh_key
+		}
+		network net1
+	}
+	
+	vm vm2 {
+		os "ubuntu-20.04.3"
+		iface i2 {
+			address "17.0.0.1"
+			belongs_to net2
+			security sg
+		}
+		credentials ssh_key
+	}
+}
+
+deployment config {
+	nginx -> vm1,
+	db -> vm2
+}
+
+active deployment config
+
+concretizations {
+	concrete_infrastructure con_infra {
+		provider openstack {
+			vm concrete_vm {
+				properties {
+					vm_name = "nginx-host";
+					vm_flavor = "small";
+					vm_key_name = "user1";
+				}
+				maps vm1
+			}
+			
+			vm concrete_vm2 {
+				properties {
+					vm_name = "nginx-host";
+					vm_flavor = "small";
+					vm_key_name = "user1";
+				}
+				maps vm2
+			}
+
+			vm_image concrete_vm_image {
+				properties {
+					name = "ubuntu-20.04.3";
+				}
+				maps v_img
+			}
+
+			net concrete_net {
+				properties {
+					name = "ostack2";
+				}
+				maps net1
+			}
+			
+			net concrete_net2 {
+				properties {
+					name = "ostack2";
+				}
+				maps net2
+			}
+		}
+	}
+	active con_infra
+}
+
+optimization opt {
+	objectives {
+		"cost" => min
+	}
+	nonfunctional_requirements {
+		req1 "Cost <= 200" max 200.0 => "cost";
+		req2 "Provider" values "AMAZ" => "provider";
+	}
+}
diff --git a/tests/doml/v2.0/nginx-openstack_v2.0_wrong_software_package_iface_net.domlx b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_software_package_iface_net.domlx
new file mode 100644
index 0000000000000000000000000000000000000000..26cd394b6527fb9a4f8c71b8b2c51f9c340c6199
--- /dev/null
+++ b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_software_package_iface_net.domlx
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="ASCII"?>
+<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" xmlns:optimization="http://www.piacere-project.eu/doml/optimization" name="nginx_openstack" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0">
+  <application name="app">
+    <components xsi:type="app:SoftwareComponent" name="nginx" consumedInterfaces="//@application/@components.1/@exposedInterfaces.0">
+      <annotations xsi:type="commons:SProperty" key="source_code" value="/usr/share/nginx/html/index.html"/>
+    </components>
+    <components xsi:type="app:SoftwareComponent" name="db">
+      <exposedInterfaces name="database"/>
+    </components>
+  </application>
+  <infrastructure name="infra">
+    <nodes xsi:type="infra:VirtualMachine" name="vm2" os="ubuntu-20.04.3" credentials="//@infrastructure/@credentials.0">
+      <ifaces name="i2" endPoint="17.0.0.1" belongsTo="//@infrastructure/@networks.1" associated="//@infrastructure/@securityGroups.0"/>
+    </nodes>
+    <generators xsi:type="infra:VMImage" name="v_img" generatedVMs="//@infrastructure/@groups.0/@machineDefinition"/>
+    <credentials xsi:type="infra:KeyPair" name="ssh_key" user="ubuntu" keyfile="/home/user1/.ssh/openstack.key" algorithm="RSA" bits="4096"/>
+    <groups xsi:type="infra:AutoScalingGroup" name="ag" deploymentNetwork="//@infrastructure/@networks.0">
+      <machineDefinition name="vm1" os="ubuntu-20.04.3" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.0">
+        <ifaces name="i1" endPoint="16.0.0.1" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/>
+      </machineDefinition>
+    </groups>
+    <securityGroups name="sg" ifaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0 //@infrastructure/@nodes.0/@ifaces.0">
+      <rules name="icmp" protocol="icmp" fromPort="-1" toPort="-1">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="https" kind="INGRESS" protocol="tcp" fromPort="443" toPort="443">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="ssh" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+    </securityGroups>
+    <networks name="net1" protocol="tcp/ip" addressRange="16.0.0.0/24" connectedIfaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0"/>
+    <networks name="net2" protocol="tcp/ip" addressRange="17.0.0.0/24" connectedIfaces="//@infrastructure/@nodes.0/@ifaces.0"/>
+  </infrastructure>
+  <concretizations name="con_infra">
+    <providers name="openstack">
+      <vms name="concrete_vm" maps="//@infrastructure/@groups.0/@machineDefinition">
+        <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/>
+        <annotations xsi:type="commons:SProperty" key="vm_flavor" value="small"/>
+        <annotations xsi:type="commons:SProperty" key="vm_key_name" value="user1"/>
+      </vms>
+      <vms name="concrete_vm2" maps="//@infrastructure/@nodes.0">
+        <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/>
+        <annotations xsi:type="commons:SProperty" key="vm_flavor" value="small"/>
+        <annotations xsi:type="commons:SProperty" key="vm_key_name" value="user1"/>
+      </vms>
+      <vmImages name="concrete_vm_image" maps="//@infrastructure/@generators.0">
+        <annotations xsi:type="commons:SProperty" key="name" value="ubuntu-20.04.3"/>
+      </vmImages>
+      <networks name="concrete_net" maps="//@infrastructure/@networks.0">
+        <annotations xsi:type="commons:SProperty" key="name" value="ostack2"/>
+      </networks>
+      <networks name="concrete_net2" maps="//@infrastructure/@networks.1">
+        <annotations xsi:type="commons:SProperty" key="name" value="ostack2"/>
+      </networks>
+    </providers>
+  </concretizations>
+  <optimization name="opt">
+    <objectives xsi:type="optimization:MeasurableObjective" kind="min" property="cost"/>
+    <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req1" description="Cost &lt;= 200" property="cost" max="200.0"/>
+    <nonfunctionalRequirements xsi:type="commons:EnumeratedRequirement" name="req2" description="Provider" property="provider">
+      <values>AMAZ</values>
+    </nonfunctionalRequirements>
+  </optimization>
+  <configurations name="config">
+    <deployments component="//@application/@components.0" node="//@infrastructure/@groups.0/@machineDefinition"/>
+    <deployments component="//@application/@components.1" node="//@infrastructure/@nodes.0"/>
+  </configurations>
+</commons:DOMLModel>
diff --git a/tests/doml/v2.0/nginx-openstack_v2.0_wrong_vm_has_iface.doml b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_vm_has_iface.doml
new file mode 100644
index 0000000000000000000000000000000000000000..bee1b4b2227817294296440aae24675ca076c687
--- /dev/null
+++ b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_vm_has_iface.doml
@@ -0,0 +1,110 @@
+doml nginx_openstack
+
+application app {
+
+	software_component nginx {
+		properties {
+			source_code="/usr/share/nginx/html/index.html";
+		}
+	}
+}
+
+infrastructure infra {
+
+	vm_image v_img {
+		generates vm1
+	}
+
+	net net1 {
+		address "16.0.0.0/24"
+		protocol "tcp/ip"
+	}
+
+	security_group sg {
+		egress icmp {
+			from_port -1
+			to_port -1
+			protocol "icmp"
+			cidr ["0.0.0.0/0"]
+		}
+		ingress http {
+			from_port 80
+			to_port 80
+			protocol "tcp"
+			cidr ["0.0.0.0/0"]
+		}
+		ingress https {
+			from_port 443
+			to_port 443
+			protocol "tcp"
+			cidr ["0.0.0.0/0"]
+		}
+		ingress ssh {
+			from_port 22
+			to_port 22
+			protocol "tcp"
+			cidr ["0.0.0.0/0"]
+		}
+	}
+
+	key_pair ssh_key {
+		user "ubuntu"
+		keyfile "/home/user1/.ssh/openstack.key"
+		algorithm "RSA"
+		bits 4096
+	}
+
+	autoscale_group ag { 
+		vm vm1 {
+			os "ubuntu-20.04.3"
+			credentials ssh_key
+		}
+		network net1
+	}
+}
+
+deployment config {
+	nginx -> vm1
+}
+
+active deployment config
+
+concretizations {
+	concrete_infrastructure con_infra {
+		provider openstack {
+			vm concrete_vm {
+				properties {
+					vm_name = "nginx-host";
+					vm_flavor = "small";
+					vm_key_name = "user1";
+				}
+				maps vm1
+			}
+
+			vm_image concrete_vm_image {
+				properties {
+					name = "ubuntu-20.04.3";
+				}
+				maps v_img
+			}
+
+			net concrete_net {
+				properties {
+					name = "ostack2";
+				}
+				maps net1
+			}
+		}
+	}
+	active con_infra
+}
+
+optimization opt {
+	objectives {
+		"cost" => min
+	}
+	nonfunctional_requirements {
+		req1 "Cost <= 200" max 200.0 => "cost";
+		req2 "Provider" values "AMAZ" => "provider";
+	}
+}
diff --git a/tests/doml/nginx-openstack_v2_wrong.domlx b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_vm_has_iface.domlx
similarity index 83%
rename from tests/doml/nginx-openstack_v2_wrong.domlx
rename to tests/doml/v2.0/nginx-openstack_v2.0_wrong_vm_has_iface.domlx
index 433c9f83dcc5d07d1b1ddd148bd4b42860c4d3f2..05401324bdba29fec01d5c144cb71df93225e492 100644
--- a/tests/doml/nginx-openstack_v2_wrong.domlx
+++ b/tests/doml/v2.0/nginx-openstack_v2.0_wrong_vm_has_iface.domlx
@@ -6,13 +6,12 @@
     </components>
   </application>
   <infrastructure name="infra">
-    <nodes xsi:type="infra:AutoScalingGroup" name="ag" deploymentNetwork="//@infrastructure/@networks.0">
-      <machineDefinition name="vm1" os="ubuntu-20.04.3" credentials="//@infrastructure/@credentials.0" group="//@infrastructure/@groups.0" generatedFrom="//@infrastructure/@generators.0"/>
-    </nodes>
-    <networks name="net1" protocol="tcp/ip" addressRange="16.0.0.0/24"/>
-    <generators xsi:type="infra:VMImage" name="v_img" generatedVMs="//@infrastructure/@nodes.0/@machineDefinition"/>
+    <generators xsi:type="infra:VMImage" name="v_img" generatedVMs="//@infrastructure/@groups.0/@machineDefinition"/>
     <credentials xsi:type="infra:KeyPair" name="ssh_key" user="ubuntu" keyfile="/home/user1/.ssh/openstack.key" algorithm="RSA" bits="4096"/>
-    <groups xsi:type="infra:SecurityGroup" name="sg" groupedNodes="//@infrastructure/@nodes.0/@machineDefinition">
+    <groups xsi:type="infra:AutoScalingGroup" name="ag" deploymentNetwork="//@infrastructure/@networks.0">
+      <machineDefinition name="vm1" os="ubuntu-20.04.3" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.0"/>
+    </groups>
+    <securityGroups name="sg">
       <rules name="icmp" protocol="icmp" fromPort="-1" toPort="-1">
         <cidr>0.0.0.0/0</cidr>
       </rules>
@@ -25,11 +24,12 @@
       <rules name="ssh" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22">
         <cidr>0.0.0.0/0</cidr>
       </rules>
-    </groups>
+    </securityGroups>
+    <networks name="net1" protocol="tcp/ip" addressRange="16.0.0.0/24"/>
   </infrastructure>
   <concretizations name="con_infra">
     <providers name="openstack">
-      <vms name="concrete_vm" maps="//@infrastructure/@nodes.0/@machineDefinition">
+      <vms name="concrete_vm" maps="//@infrastructure/@groups.0/@machineDefinition">
         <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/>
         <annotations xsi:type="commons:SProperty" key="vm_flavor" value="small"/>
         <annotations xsi:type="commons:SProperty" key="vm_key_name" value="user1"/>
@@ -46,10 +46,10 @@
     <objectives xsi:type="optimization:MeasurableObjective" kind="min" property="cost"/>
     <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req1" description="Cost &lt;= 200" property="cost" max="200.0"/>
     <nonfunctionalRequirements xsi:type="commons:EnumeratedRequirement" name="req2" description="Provider" property="provider">
-      <values>OPEN</values>
+      <values>AMAZ</values>
     </nonfunctionalRequirements>
   </optimization>
   <configurations name="config">
-    <deployments component="//@application/@components.0" node="//@infrastructure/@nodes.0/@machineDefinition"/>
+    <deployments component="//@application/@components.0" node="//@infrastructure/@groups.0/@machineDefinition"/>
   </configurations>
 </commons:DOMLModel>
diff --git a/tests/doml/v2.0/openstack_template.domlx b/tests/doml/v2.0/openstack_template.domlx
new file mode 100644
index 0000000000000000000000000000000000000000..514308a5a88e83ed0173b8af5b5d698bc00744ff
--- /dev/null
+++ b/tests/doml/v2.0/openstack_template.domlx
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="ASCII"?>
+<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" xmlns:optimization="http://www.piacere-project.eu/doml/optimization" name="nginx_openstack" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0">
+  <application name="app">
+    <components xsi:type="app:SoftwareComponent" name="nginx">
+      <annotations xsi:type="commons:SProperty" key="source_code" value="/usr/share/nginx/html/index.html"/>
+    </components>
+  </application>
+  <infrastructure name="infra">
+    <nodes xsi:type="infra:VirtualMachine" name="vm1" os="ubuntu-20.04.3"/>
+  </infrastructure>
+  <concretizations name="con_infra">
+    <providers name="openstack">
+      <vms name="concrete_vm" maps="//@infrastructure/@nodes.0">
+        <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/>
+        <annotations xsi:type="commons:SProperty" key="vm_flavor" value="small"/>
+        <annotations xsi:type="commons:SProperty" key="vm_key_name" value="user1"/>
+      </vms>
+    </providers>
+  </concretizations>
+  <optimization name="opt">
+    <objectives xsi:type="optimization:MeasurableObjective" kind="min" property="cost"/>
+  </optimization>
+  <configurations name="config">
+    <deployments component="//@application/@components.0" node="//@infrastructure/@nodes.0"/>
+  </configurations>
+</commons:DOMLModel>
diff --git a/tests/doml/v2.0/saas.domlx b/tests/doml/v2.0/saas.domlx
new file mode 100644
index 0000000000000000000000000000000000000000..bdfa1f32b00544dc4215557ea74c98884e61e693
--- /dev/null
+++ b/tests/doml/v2.0/saas.domlx
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="ASCII"?>
+<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" xmlns:optimization="http://www.piacere-project.eu/doml/optimization" name="iot_simple_app" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0">
+  <application name="iot_simple_app">
+    <components xsi:type="app:DBMS" name="oracle">
+      <exposedInterfaces name="sql_interface"/>
+    </components>
+    <components xsi:type="app:SoftwareComponent" name="web_server" consumedInterfaces="//@application/@components.0/@exposedInterfaces.0 //@application/@components.3/@exposedInterfaces.0">
+      <exposedInterfaces name="sensor_info"/>
+    </components>
+    <components xsi:type="app:SoftwareComponent" name="iot_provider" consumedInterfaces="//@application/@components.1/@exposedInterfaces.0"/>
+    <components xsi:type="app:SaaS" name="external_meteo">
+      <exposedInterfaces name="get_weather" endPoint="https://api.mymeteo.com/get"/>
+    </components>
+  </application>
+  <infrastructure name="infra">
+    <nodes xsi:type="infra:VirtualMachine" name="vm1">
+      <ifaces name="i1" endPoint="10.0.0.2" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/>
+    </nodes>
+    <nodes xsi:type="infra:VirtualMachine" name="vm2">
+      <ifaces name="i1" endPoint="10.0.0.3" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/>
+    </nodes>
+    <nodes xsi:type="infra:PhysicalComputingNode" name="iot_device1">
+      <ifaces name="i1" endPoint="10.0.0.4" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/>
+    </nodes>
+    <nodes xsi:type="infra:PhysicalComputingNode" name="iot_device2">
+      <ifaces name="i1" endPoint="10.0.0.5" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/>
+    </nodes>
+    <credentials xsi:type="infra:KeyPair" name="ssh_key" user="ubuntu" keyfile="/home/user1/.ssh/openstack.key" algorithm="RSA" bits="4096"/>
+    <securityGroups name="sg1" ifaces="//@infrastructure/@nodes.0/@ifaces.0 //@infrastructure/@nodes.1/@ifaces.0 //@infrastructure/@nodes.2/@ifaces.0 //@infrastructure/@nodes.3/@ifaces.0">
+      <rules name="icmp" protocol="icmp" fromPort="-1" toPort="-1">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="https" kind="INGRESS" protocol="tcp" fromPort="443" toPort="443">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="ssh" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+    </securityGroups>
+    <networks name="net1" protocol="tcp/ip" addressRange="10.0.0.0/24" connectedIfaces="//@infrastructure/@nodes.0/@ifaces.0 //@infrastructure/@nodes.1/@ifaces.0 //@infrastructure/@nodes.2/@ifaces.0 //@infrastructure/@nodes.3/@ifaces.0"/>
+  </infrastructure>
+  <concretizations name="con_infra1">
+    <providers name="aws">
+      <vms name="concrete_vm1" maps="//@infrastructure/@nodes.0">
+        <annotations xsi:type="commons:SProperty" key="instance_type" value="t2.micro"/>
+      </vms>
+      <vms name="concrete_vm2" maps="//@infrastructure/@nodes.1"/>
+      <networks name="concrete_net1" maps="//@infrastructure/@networks.0"/>
+    </providers>
+  </concretizations>
+  <optimization name="opt">
+    <objectives xsi:type="optimization:MeasurableObjective" kind="min" property="cost"/>
+    <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req1" description="Cost &lt;= 200" property="cost" max="200.0"/>
+    <nonfunctionalRequirements xsi:type="commons:EnumeratedRequirement" name="req2" description="Provider" property="provider">
+      <values>AMAZ</values>
+    </nonfunctionalRequirements>
+  </optimization>
+  <configurations name="config1">
+    <deployments component="//@application/@components.0" node="//@infrastructure/@nodes.0"/>
+    <deployments component="//@application/@components.1" node="//@infrastructure/@nodes.1"/>
+    <deployments component="//@application/@components.2" node="//@infrastructure/@nodes.2"/>
+    <deployments component="//@application/@components.2" node="//@infrastructure/@nodes.3"/>
+  </configurations>
+</commons:DOMLModel>
diff --git a/tests/doml/v2.0/saas_https_no_attrs.domlx b/tests/doml/v2.0/saas_https_no_attrs.domlx
new file mode 100644
index 0000000000000000000000000000000000000000..38cf851c241d1de8d8d970c58117e7e5c9f026e3
--- /dev/null
+++ b/tests/doml/v2.0/saas_https_no_attrs.domlx
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="ASCII"?>
+<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" xmlns:optimization="http://www.piacere-project.eu/doml/optimization" name="iot_simple_app" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0">
+  <application name="iot_simple_app">
+    <components xsi:type="app:DBMS" name="oracle">
+      <exposedInterfaces name="sql_interface"/>
+    </components>
+    <components xsi:type="app:SoftwareComponent" name="web_server" consumedInterfaces="//@application/@components.0/@exposedInterfaces.0 //@application/@components.3/@exposedInterfaces.0">
+      <exposedInterfaces name="sensor_info"/>
+    </components>
+    <components xsi:type="app:SoftwareComponent" name="iot_provider" consumedInterfaces="//@application/@components.1/@exposedInterfaces.0"/>
+    <components xsi:type="app:SaaS" name="external_meteo">
+      <exposedInterfaces name="get_weather" endPoint="https://api.mymeteo.com/get"/>
+    </components>
+  </application>
+  <infrastructure name="infra">
+    <nodes xsi:type="infra:VirtualMachine" name="vm1">
+      <ifaces name="i1" endPoint="10.0.0.2" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/>
+    </nodes>
+    <nodes xsi:type="infra:VirtualMachine" name="vm2">
+      <ifaces name="i1" endPoint="10.0.0.3" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/>
+    </nodes>
+    <nodes xsi:type="infra:PhysicalComputingNode" name="iot_device1">
+      <ifaces name="i1" endPoint="10.0.0.4" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/>
+    </nodes>
+    <nodes xsi:type="infra:PhysicalComputingNode" name="iot_device2">
+      <ifaces name="i1" endPoint="10.0.0.5" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/>
+    </nodes>
+    <credentials xsi:type="infra:KeyPair" name="ssh_key" user="ubuntu" keyfile="/home/user1/.ssh/openstack.key" algorithm="RSA" bits="4096"/>
+    <securityGroups name="sg1" ifaces="//@infrastructure/@nodes.0/@ifaces.0 //@infrastructure/@nodes.1/@ifaces.0 //@infrastructure/@nodes.2/@ifaces.0 //@infrastructure/@nodes.3/@ifaces.0">
+      <rules name="icmp" protocol="icmp" fromPort="-1" toPort="-1">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="https" kind="INGRESS"/>
+      <rules name="ssh" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+    </securityGroups>
+    <networks name="net1" protocol="tcp/ip" addressRange="10.0.0.0/24" connectedIfaces="//@infrastructure/@nodes.0/@ifaces.0 //@infrastructure/@nodes.1/@ifaces.0 //@infrastructure/@nodes.2/@ifaces.0 //@infrastructure/@nodes.3/@ifaces.0"/>
+  </infrastructure>
+  <concretizations name="con_infra1">
+    <providers name="aws">
+      <vms name="concrete_vm1" maps="//@infrastructure/@nodes.0">
+        <annotations xsi:type="commons:SProperty" key="instance_type" value="t2.micro"/>
+      </vms>
+      <vms name="concrete_vm2" maps="//@infrastructure/@nodes.1"/>
+      <networks name="concrete_net1" maps="//@infrastructure/@networks.0"/>
+    </providers>
+  </concretizations>
+  <optimization name="opt">
+    <objectives xsi:type="optimization:MeasurableObjective" kind="min" property="cost"/>
+    <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req1" description="Cost &lt;= 200" property="cost" max="200.0"/>
+    <nonfunctionalRequirements xsi:type="commons:EnumeratedRequirement" name="req2" description="Provider" property="provider">
+      <values>AMAZ</values>
+    </nonfunctionalRequirements>
+  </optimization>
+  <configurations name="config1">
+    <deployments component="//@application/@components.0" node="//@infrastructure/@nodes.0"/>
+    <deployments component="//@application/@components.1" node="//@infrastructure/@nodes.1"/>
+    <deployments component="//@application/@components.2" node="//@infrastructure/@nodes.2"/>
+    <deployments component="//@application/@components.2" node="//@infrastructure/@nodes.3"/>
+  </configurations>
+</commons:DOMLModel>
diff --git a/tests/doml/v2.0/saas_no_https_rule.domlx b/tests/doml/v2.0/saas_no_https_rule.domlx
new file mode 100644
index 0000000000000000000000000000000000000000..8d824c6679283729984ceec8bc4ff0c4a313729f
--- /dev/null
+++ b/tests/doml/v2.0/saas_no_https_rule.domlx
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="ASCII"?>
+<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" xmlns:optimization="http://www.piacere-project.eu/doml/optimization" name="iot_simple_app" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0">
+  <application name="iot_simple_app">
+    <components xsi:type="app:DBMS" name="oracle">
+      <exposedInterfaces name="sql_interface"/>
+    </components>
+    <components xsi:type="app:SoftwareComponent" name="web_server" consumedInterfaces="//@application/@components.0/@exposedInterfaces.0 //@application/@components.3/@exposedInterfaces.0">
+      <exposedInterfaces name="sensor_info"/>
+    </components>
+    <components xsi:type="app:SoftwareComponent" name="iot_provider" consumedInterfaces="//@application/@components.1/@exposedInterfaces.0"/>
+    <components xsi:type="app:SaaS" name="external_meteo">
+      <exposedInterfaces name="get_weather" endPoint="https://api.mymeteo.com/get"/>
+    </components>
+  </application>
+  <infrastructure name="infra">
+    <nodes xsi:type="infra:VirtualMachine" name="vm1">
+      <ifaces name="i1" endPoint="10.0.0.2" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/>
+    </nodes>
+    <nodes xsi:type="infra:VirtualMachine" name="vm2">
+      <ifaces name="i1" endPoint="10.0.0.3" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/>
+    </nodes>
+    <nodes xsi:type="infra:PhysicalComputingNode" name="iot_device1">
+      <ifaces name="i1" endPoint="10.0.0.4" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/>
+    </nodes>
+    <nodes xsi:type="infra:PhysicalComputingNode" name="iot_device2">
+      <ifaces name="i1" endPoint="10.0.0.5" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/>
+    </nodes>
+    <credentials xsi:type="infra:KeyPair" name="ssh_key" user="ubuntu" keyfile="/home/user1/.ssh/openstack.key" algorithm="RSA" bits="4096"/>
+    <securityGroups name="sg1" ifaces="//@infrastructure/@nodes.0/@ifaces.0 //@infrastructure/@nodes.1/@ifaces.0 //@infrastructure/@nodes.2/@ifaces.0 //@infrastructure/@nodes.3/@ifaces.0">
+      <rules name="icmp" protocol="icmp" fromPort="-1" toPort="-1">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="ssh" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+    </securityGroups>
+    <networks name="net1" protocol="tcp/ip" addressRange="10.0.0.0/24" connectedIfaces="//@infrastructure/@nodes.0/@ifaces.0 //@infrastructure/@nodes.1/@ifaces.0 //@infrastructure/@nodes.2/@ifaces.0 //@infrastructure/@nodes.3/@ifaces.0"/>
+  </infrastructure>
+  <concretizations name="con_infra1">
+    <providers name="aws">
+      <vms name="concrete_vm1" maps="//@infrastructure/@nodes.0">
+        <annotations xsi:type="commons:SProperty" key="instance_type" value="t2.micro"/>
+      </vms>
+      <vms name="concrete_vm2" maps="//@infrastructure/@nodes.1"/>
+      <networks name="concrete_net1" maps="//@infrastructure/@networks.0"/>
+    </providers>
+  </concretizations>
+  <optimization name="opt">
+    <objectives xsi:type="optimization:MeasurableObjective" kind="min" property="cost"/>
+    <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req1" description="Cost &lt;= 200" property="cost" max="200.0"/>
+    <nonfunctionalRequirements xsi:type="commons:EnumeratedRequirement" name="req2" description="Provider" property="provider">
+      <values>AMAZ</values>
+    </nonfunctionalRequirements>
+  </optimization>
+  <configurations name="config1">
+    <deployments component="//@application/@components.0" node="//@infrastructure/@nodes.0"/>
+    <deployments component="//@application/@components.1" node="//@infrastructure/@nodes.1"/>
+    <deployments component="//@application/@components.2" node="//@infrastructure/@nodes.2"/>
+    <deployments component="//@application/@components.2" node="//@infrastructure/@nodes.3"/>
+  </configurations>
+</commons:DOMLModel>
diff --git a/tests/doml/v2.0/saas_wrong_no_iface_sg.domlx b/tests/doml/v2.0/saas_wrong_no_iface_sg.domlx
new file mode 100644
index 0000000000000000000000000000000000000000..be6aaffdf2eda69c3eef4d1ebbf936ae2b5afdbe
--- /dev/null
+++ b/tests/doml/v2.0/saas_wrong_no_iface_sg.domlx
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="ASCII"?>
+<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" xmlns:optimization="http://www.piacere-project.eu/doml/optimization" name="iot_simple_app" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0">
+  <application name="iot_simple_app">
+    <components xsi:type="app:DBMS" name="oracle">
+      <exposedInterfaces name="sql_interface"/>
+    </components>
+    <components xsi:type="app:SoftwareComponent" name="web_server" consumedInterfaces="//@application/@components.0/@exposedInterfaces.0 //@application/@components.3/@exposedInterfaces.0">
+      <exposedInterfaces name="sensor_info"/>
+    </components>
+    <components xsi:type="app:SoftwareComponent" name="iot_provider" consumedInterfaces="//@application/@components.1/@exposedInterfaces.0"/>
+    <components xsi:type="app:SaaS" name="external_meteo">
+      <exposedInterfaces name="get_weather" endPoint="https://api.mymeteo.com/get"/>
+    </components>
+  </application>
+  <infrastructure name="infra">
+    <nodes xsi:type="infra:VirtualMachine" name="vm1">
+      <ifaces name="i1" endPoint="10.0.0.2" belongsTo="//@infrastructure/@networks.0"/>
+    </nodes>
+    <nodes xsi:type="infra:VirtualMachine" name="vm2">
+      <ifaces name="i1" endPoint="10.0.0.3" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/>
+    </nodes>
+    <nodes xsi:type="infra:PhysicalComputingNode" name="iot_device1">
+      <ifaces name="i1" endPoint="10.0.0.4" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/>
+    </nodes>
+    <nodes xsi:type="infra:PhysicalComputingNode" name="iot_device2">
+      <ifaces name="i1" endPoint="10.0.0.5" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/>
+    </nodes>
+    <credentials xsi:type="infra:KeyPair" name="ssh_key" user="ubuntu" keyfile="/home/user1/.ssh/openstack.key" algorithm="RSA" bits="4096"/>
+    <securityGroups name="sg1" ifaces="//@infrastructure/@nodes.1/@ifaces.0 //@infrastructure/@nodes.2/@ifaces.0 //@infrastructure/@nodes.3/@ifaces.0">
+      <rules name="icmp" protocol="icmp" fromPort="-1" toPort="-1">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="https" kind="INGRESS" protocol="tcp" fromPort="443" toPort="443">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="ssh" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+    </securityGroups>
+    <networks name="net1" protocol="tcp/ip" addressRange="10.0.0.0/24" connectedIfaces="//@infrastructure/@nodes.0/@ifaces.0 //@infrastructure/@nodes.1/@ifaces.0 //@infrastructure/@nodes.2/@ifaces.0 //@infrastructure/@nodes.3/@ifaces.0"/>
+  </infrastructure>
+  <concretizations name="con_infra1">
+    <providers name="aws">
+      <vms name="concrete_vm1" maps="//@infrastructure/@nodes.0">
+        <annotations xsi:type="commons:SProperty" key="instance_type" value="t2.micro"/>
+      </vms>
+      <vms name="concrete_vm2" maps="//@infrastructure/@nodes.1"/>
+      <networks name="concrete_net1" maps="//@infrastructure/@networks.0"/>
+    </providers>
+  </concretizations>
+  <optimization name="opt">
+    <objectives xsi:type="optimization:MeasurableObjective" kind="min" property="cost"/>
+    <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req1" description="Cost &lt;= 200" property="cost" max="200.0"/>
+    <nonfunctionalRequirements xsi:type="commons:EnumeratedRequirement" name="req2" description="Provider" property="provider">
+      <values>AMAZ</values>
+    </nonfunctionalRequirements>
+  </optimization>
+  <configurations name="config1">
+    <deployments component="//@application/@components.0" node="//@infrastructure/@nodes.0"/>
+    <deployments component="//@application/@components.1" node="//@infrastructure/@nodes.1"/>
+    <deployments component="//@application/@components.2" node="//@infrastructure/@nodes.2"/>
+    <deployments component="//@application/@components.2" node="//@infrastructure/@nodes.3"/>
+  </configurations>
+</commons:DOMLModel>
diff --git a/tests/doml/v2.1/faas.domlx b/tests/doml/v2.1/faas.domlx
new file mode 100644
index 0000000000000000000000000000000000000000..51dc9826cba0430f1fa4cb1da3ba4cc94b9515fc
--- /dev/null
+++ b/tests/doml/v2.1/faas.domlx
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="ASCII"?>
+<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" name="faas_app" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0"  version="v2.1">
+  <application name="ImageResizeApp">
+    <components xsi:type="app:SoftwareComponent" name="image_resize" consumedInterfaces="//@application/@components.1/@exposedInterfaces.0 //@application/@components.1/@exposedInterfaces.1 //@application/@components.2/@exposedInterfaces.1">
+      <annotations xsi:type="commons:SProperty" key="source_code" value="path/lambda/function/image_resize.py"/>
+      <exposedInterfaces name="handle_image"/>
+    </components>
+    <components xsi:type="app:SaaS" name="s1">
+      <exposedInterfaces name="storage_interface"/>
+      <exposedInterfaces name="bucket_in"/>
+    </components>
+    <components xsi:type="app:SaaS" name="s2">
+      <exposedInterfaces name="storage_interface"/>
+      <exposedInterfaces name="bucket_out"/>
+    </components>
+    <components xsi:type="app:SoftwareComponent" name="notification" consumedInterfaces="//@application/@components.0/@exposedInterfaces.0 //@application/@components.1/@exposedInterfaces.1"/>
+    <components xsi:type="app:SoftwareComponent" name="web" consumedInterfaces="//@application/@components.1/@exposedInterfaces.0 //@application/@components.2/@exposedInterfaces.1">
+      <annotations xsi:type="commons:SProperty" key="source_code" value="path/web_app"/>
+    </components>
+  </application>
+  <infrastructure name="infra">
+    <nodes xsi:type="infra:VirtualMachine" name="vm1" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.0">
+      <ifaces name="i1" endPoint="10.0.0.1" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/>
+      <location region="eu-central-1"/>
+    </nodes>
+    <nodes xsi:type="infra:Container" name="c" generatedFrom="//@infrastructure/@generators.1">
+      <configs host="//@infrastructure/@nodes.0"/>
+    </nodes>
+    <generators xsi:type="infra:VMImage" name="v_img" uri="ami-xxxxxxxxxxxxxxxxx" kind="IMAGE" generatedVMs="//@infrastructure/@nodes.0"/>
+    <generators xsi:type="infra:ContainerImage" name="c_img" uri="web-app:0.1.0" kind="IMAGE" generatedContainers="//@infrastructure/@nodes.1"/>
+    <storages name="st1"/>
+    <storages name="st2"/>
+    <faas name="f"/>
+    <credentials xsi:type="infra:KeyPair" name="ssh_key" user="ec2-user" keyfile="/tmp/ssh_key_file" algorithm="RSA" bits="4096"/>
+    <securityGroups name="sg" ifaces="//@infrastructure/@nodes.0/@ifaces.0">
+      <rules name="icmp" protocol="icmp" fromPort="-1" toPort="-1">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="https" kind="INGRESS" protocol="tcp" fromPort="443" toPort="443">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="ssh" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+    </securityGroups>
+    <networks name="vpc" protocol="tcp/ip" addressRange="/24" connectedIfaces="//@infrastructure/@nodes.0/@ifaces.0">
+      <subnets name="vpc_subnet" protocol="tcp/ip" addressRange="/24"/>
+    </networks>
+  </infrastructure>
+  <concretizations name="con_infra">
+    <providers name="aws">
+      <vms name="concrete_vm" maps="//@infrastructure/@nodes.0">
+        <annotations xsi:type="commons:SProperty" key="instance_type" value="t2.micro"/>
+        <annotations xsi:type="commons:SProperty" key="ssh_key_name" value="demo-key"/>
+        <annotations xsi:type="commons:SProperty" key="ec2_role_name" value="demo-ec2-role"/>
+      </vms>
+      <networks name="concrete_net" maps="//@infrastructure/@networks.0"/>
+      <storages name="s3_bucket_in" maps="//@infrastructure/@storages.0">
+        <annotations xsi:type="commons:SProperty" key="bucket_name" value="bucket_in"/>
+      </storages>
+      <storages name="s3_bucket_out" maps="//@infrastructure/@storages.1">
+        <annotations xsi:type="commons:SProperty" key="bucket_name" value="bucket_out"/>
+      </storages>
+      <faas name="concrete_f" maps="//@infrastructure/@faas.0">
+        <annotations xsi:type="commons:SProperty" key="lambda_role_name" value="DemoLambdaRole"/>
+        <annotations xsi:type="commons:SProperty" key="lambda_runtime" value="python3.8"/>
+        <annotations xsi:type="commons:SProperty" key="lambda_handler" value="image_resize.lambda_handler"/>
+        <annotations xsi:type="commons:IProperty" key="lambda_timeout" value="5"/>
+        <annotations xsi:type="commons:IProperty" key="lambda_memory" value="128"/>
+      </faas>
+    </providers>
+  </concretizations>
+  <configurations name="config1">
+    <deployments component="//@application/@components.0" node="//@infrastructure/@faas.0"/>
+    <deployments component="//@application/@components.4" node="//@infrastructure/@nodes.1"/>
+    <deployments component="//@application/@components.1" node="//@infrastructure/@storages.0"/>
+    <deployments component="//@application/@components.2" node="//@infrastructure/@storages.1"/>
+  </configurations>
+</commons:DOMLModel>
diff --git a/tests/doml/v2.1/nginx-aws-ec2.domlx b/tests/doml/v2.1/nginx-aws-ec2.domlx
new file mode 100644
index 0000000000000000000000000000000000000000..67ae86db7c8893d91437bd11fe715b7dfd857b4b
--- /dev/null
+++ b/tests/doml/v2.1/nginx-aws-ec2.domlx
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="ASCII"?>
+<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" xmlns:optimization="http://www.piacere-project.eu/doml/optimization" name="nginx_aws_ec2" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0" version="v2.1">
+  <application name="app">
+    <components xsi:type="app:SoftwareComponent" name="nginx">
+      <annotations xsi:type="commons:SProperty" key="source_code" value="/usr/share/nginx/html/index.html"/>
+    </components>
+  </application>
+  <infrastructure name="infra">
+    <generators xsi:type="infra:VMImage" name="vm_img" uri="ami-xxxxxxxxxxxxxxxxx" kind="IMAGE" generatedVMs="//@infrastructure/@groups.0/@machineDefinition"/>
+    <credentials xsi:type="infra:KeyPair" name="ssh_key" user="ec2-user" keyfile="/tmp/ssh_key_file" algorithm="RSA" bits="4096"/>
+    <groups xsi:type="infra:AutoScalingGroup" name="ag">
+      <machineDefinition name="vm1" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.0">
+        <ifaces name="i1" endPoint="10.0.0.1" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/>
+        <location region="eu-central-1"/>
+      </machineDefinition>
+    </groups>
+    <securityGroups name="sg" ifaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0">
+      <rules name="icmp" protocol="icmp" fromPort="-1" toPort="-1">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="https" kind="INGRESS" protocol="tcp" fromPort="443" toPort="443">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="ssh" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+    </securityGroups>
+    <networks name="vpc" protocol="tcp/ip" addressRange="0.0.0.0/24" connectedIfaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0">
+      <subnets name="vpc_subnet" protocol="tcp/ip" addressRange="0.0.0.0/24"/>
+    </networks>
+  </infrastructure>
+  <concretizations name="con_infra">
+    <providers name="aws">
+      <vms name="ec2_vm" maps="//@infrastructure/@groups.0/@machineDefinition">
+        <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/>
+        <annotations xsi:type="commons:SProperty" key="instance_type" value="t2.micro"/>
+        <annotations xsi:type="commons:SProperty" key="ssh_key_name" value="demo-key"/>
+        <annotations xsi:type="commons:SProperty" key="ec2_role_name" value="demo-ec2-role"/>
+      </vms>
+      <vmImages name="concrete_vm_image" maps="//@infrastructure/@generators.0"/>
+      <networks name="concrete_net" maps="//@infrastructure/@networks.0">
+        <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/>
+      </networks>
+    </providers>
+  </concretizations>
+  <optimization name="opt">
+    <objectives xsi:type="optimization:MeasurableObjective" kind="min" property="cost"/>
+    <objectives xsi:type="optimization:MeasurableObjective" kind="max" property="availability"/>
+    <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req1" description="Cost &lt;= 70.0" property="cost" max="70.0"/>
+    <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req2" description="Availability >= 66.5%" property="availability" min="66.5"/>
+  </optimization>
+  <configurations name="config">
+    <deployments component="//@application/@components.0" node="//@infrastructure/@groups.0/@machineDefinition"/>
+  </configurations>
+</commons:DOMLModel>
diff --git a/tests/doml/v2.2/.project b/tests/doml/v2.2/.project
new file mode 100644
index 0000000000000000000000000000000000000000..96bcdb7a1076c114a39e5046f8f7d8a1b7c96daa
--- /dev/null
+++ b/tests/doml/v2.2/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>domlTests</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.xtext.ui.shared.xtextBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.xtext.ui.shared.xtextNature</nature>
+	</natures>
+</projectDescription>
diff --git a/tests/doml/v2.2/faas.doml b/tests/doml/v2.2/faas.doml
new file mode 100644
index 0000000000000000000000000000000000000000..9345cc7d776cafd80d1a0af2553202e6f8ea112d
--- /dev/null
+++ b/tests/doml/v2.2/faas.doml
@@ -0,0 +1,177 @@
+doml faas_app
+
+application ImageResizeApp {
+
+	software_component image_resize {
+		provides {
+			handle_image
+		}
+		consumes {
+			storage_interface,
+			bucket_in,
+			bucket_out
+		}
+		properties {
+			source_code = "path/lambda/function/image_resize.py";
+		}
+	}
+
+	saas s1 {
+		provides {
+			storage_interface
+			bucket_in
+		}
+	}
+
+	saas s2 {
+		provides {
+			storage_interface
+			bucket_out
+		}
+	}
+
+	software_component notification {
+		consumes {
+			handle_image,
+			bucket_in
+		}
+	}
+
+	software_component web {
+		consumes {
+			storage_interface,
+			bucket_out
+		}
+		properties {
+			source_code = "path/web_app";
+		}
+	}
+}
+
+infrastructure infra {
+	vm vm1 {
+		iface i1 {
+			address "10.0.0.1"
+			belongs_to vpc
+			security sg
+		}
+		credentials ssh_key
+		loc {
+			region "eu-central-1"
+		}
+	}
+
+	vm_image v_img {
+		generates vm1
+		image "ami-xxxxxxxxxxxxxxxxx"
+	}
+
+	container c {
+		host vm1
+	}
+
+	cont_image c_img {
+		generates c
+		image "web-app:0.1.0"
+	}
+
+	faas f { }
+
+	sto st1 { }
+
+	sto st2 { }
+
+	net vpc {
+		cidr "/24"
+		protocol "tcp/ip"
+		subnet vpc_subnet {
+			cidr "/24"
+			protocol "tcp/ip"
+		}
+	}
+
+	security_group sg {
+		egress icmp {
+			from_port -1
+			to_port -1
+			protocol "icmp"
+			cidr ["0.0.0.0/0"]
+		}
+		ingress http {
+			from_port 80
+			to_port 80
+			protocol "tcp"
+			cidr ["0.0.0.0/0"]
+		}
+		ingress https {
+			from_port 443
+			to_port 443
+			protocol "tcp"
+			cidr ["0.0.0.0/0"]
+		}
+		ingress ssh {
+			from_port 22
+			to_port 22
+			protocol "tcp"
+			cidr ["0.0.0.0/0"]
+		}
+		ifaces i1
+	}
+
+	key_pair ssh_key {
+		user "ec2-user"
+		keyfile "/tmp/ssh_key_file"
+		algorithm "RSA"
+		bits 4096
+	}
+}
+
+deployment config1 {
+	image_resize -> f,
+	web -> c,
+	s1 -> st1,
+	s2 -> st2
+}
+
+active deployment config1
+
+concretizations {
+	concrete_infrastructure con_infra {
+		provider aws {
+			vm concrete_vm {
+				properties {
+					instance_type = "t2.micro";
+					ssh_key_name = "demo-key";
+					ec2_role_name = "demo-ec2-role";
+				}
+				maps vm1
+			}
+			faas concrete_f {
+				properties {
+					lambda_role_name = "DemoLambdaRole";
+					lambda_runtime = "python3.8";
+					lambda_handler = "image_resize.lambda_handler";
+					lambda_timeout = 5;
+					lambda_memory = 128;
+				}
+				maps f
+			}
+			storage s3_bucket_in {
+				properties {
+					bucket_name = "bucket_in";
+				}
+				maps st1
+			}
+			storage s3_bucket_out {
+				properties {
+					bucket_name = "bucket_out";
+				}
+				maps st2
+			}
+			net concrete_net {
+				maps vpc
+			}
+		}
+	}
+	active con_infra
+}
\ No newline at end of file
diff --git a/tests/doml/v2.2/faas.domlx b/tests/doml/v2.2/faas.domlx
new file mode 100644
index 0000000000000000000000000000000000000000..dc83d7135253786f5e7d1fbb9180c0ab1da9e2ca
--- /dev/null
+++ b/tests/doml/v2.2/faas.domlx
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="ASCII"?>
+<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" name="faas_app" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0">
+  <application name="ImageResizeApp">
+    <components xsi:type="app:SoftwareComponent" name="image_resize" consumedInterfaces="//@application/@components.1/@exposedInterfaces.0 //@application/@components.1/@exposedInterfaces.1 //@application/@components.2/@exposedInterfaces.1">
+      <annotations xsi:type="commons:SProperty" key="source_code" value="path/lambda/function/image_resize.py"/>
+      <exposedInterfaces name="handle_image"/>
+    </components>
+    <components xsi:type="app:SaaS" name="s1">
+      <exposedInterfaces name="storage_interface"/>
+      <exposedInterfaces name="bucket_in"/>
+    </components>
+    <components xsi:type="app:SaaS" name="s2">
+      <exposedInterfaces name="storage_interface"/>
+      <exposedInterfaces name="bucket_out"/>
+    </components>
+    <components xsi:type="app:SoftwareComponent" name="notification" consumedInterfaces="//@application/@components.0/@exposedInterfaces.0 //@application/@components.1/@exposedInterfaces.1"/>
+    <components xsi:type="app:SoftwareComponent" name="web" consumedInterfaces="//@application/@components.1/@exposedInterfaces.0 //@application/@components.2/@exposedInterfaces.1">
+      <annotations xsi:type="commons:SProperty" key="source_code" value="path/web_app"/>
+    </components>
+  </application>
+  <infrastructure name="infra">
+    <nodes xsi:type="infra:VirtualMachine" name="vm1" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.0">
+      <ifaces name="i1" endPoint="10.0.0.1" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/>
+      <location region="eu-central-1"/>
+    </nodes>
+    <nodes xsi:type="infra:Container" name="c" generatedFrom="//@infrastructure/@generators.1">
+      <configs host="//@infrastructure/@nodes.0"/>
+    </nodes>
+    <generators xsi:type="infra:VMImage" name="v_img" uri="ami-xxxxxxxxxxxxxxxxx" kind="IMAGE" generatedVMs="//@infrastructure/@nodes.0"/>
+    <generators xsi:type="infra:ContainerImage" name="c_img" uri="web-app:0.1.0" kind="IMAGE" generatedContainers="//@infrastructure/@nodes.1"/>
+    <storages name="st1"/>
+    <storages name="st2"/>
+    <faas name="f"/>
+    <credentials xsi:type="commons:KeyPair" name="ssh_key" user="ec2-user" keyfile="/tmp/ssh_key_file" algorithm="RSA" bits="4096"/>
+    <securityGroups name="sg" ifaces="//@infrastructure/@nodes.0/@ifaces.0">
+      <rules name="icmp" protocol="icmp" fromPort="-1" toPort="-1">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="https" kind="INGRESS" protocol="tcp" fromPort="443" toPort="443">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="ssh" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+    </securityGroups>
+    <networks name="vpc" protocol="tcp/ip" addressRange="/24" connectedIfaces="//@infrastructure/@nodes.0/@ifaces.0">
+      <subnets name="vpc_subnet" protocol="tcp/ip" addressRange="/24"/>
+    </networks>
+  </infrastructure>
+  <concretizations name="con_infra">
+    <providers name="aws">
+      <vms name="concrete_vm" maps="//@infrastructure/@nodes.0">
+        <annotations xsi:type="commons:SProperty" key="instance_type" value="t2.micro"/>
+        <annotations xsi:type="commons:SProperty" key="ssh_key_name" value="demo-key"/>
+        <annotations xsi:type="commons:SProperty" key="ec2_role_name" value="demo-ec2-role"/>
+      </vms>
+      <networks name="concrete_net" maps="//@infrastructure/@networks.0"/>
+      <storages name="s3_bucket_in" maps="//@infrastructure/@storages.0">
+        <annotations xsi:type="commons:SProperty" key="bucket_name" value="bucket_in"/>
+      </storages>
+      <storages name="s3_bucket_out" maps="//@infrastructure/@storages.1">
+        <annotations xsi:type="commons:SProperty" key="bucket_name" value="bucket_out"/>
+      </storages>
+      <faas name="concrete_f" maps="//@infrastructure/@faas.0">
+        <annotations xsi:type="commons:SProperty" key="lambda_role_name" value="DemoLambdaRole"/>
+        <annotations xsi:type="commons:SProperty" key="lambda_runtime" value="python3.8"/>
+        <annotations xsi:type="commons:SProperty" key="lambda_handler" value="image_resize.lambda_handler"/>
+        <annotations xsi:type="commons:IProperty" key="lambda_timeout" value="5"/>
+        <annotations xsi:type="commons:IProperty" key="lambda_memory" value="128"/>
+      </faas>
+    </providers>
+  </concretizations>
+  <configurations name="config1">
+    <deployments component="//@application/@components.0" node="//@infrastructure/@faas.0"/>
+    <deployments component="//@application/@components.4" node="//@infrastructure/@nodes.1"/>
+    <deployments component="//@application/@components.1" node="//@infrastructure/@storages.0"/>
+    <deployments component="//@application/@components.2" node="//@infrastructure/@storages.1"/>
+  </configurations>
+</commons:DOMLModel>
diff --git a/tests/doml/v2.2/iot_simple_app.doml b/tests/doml/v2.2/iot_simple_app.doml
new file mode 100644
index 0000000000000000000000000000000000000000..4dca09ac6ec52afa070731e6942535354b8eb5b4
--- /dev/null
+++ b/tests/doml/v2.2/iot_simple_app.doml
@@ -0,0 +1,52 @@
+doml iot_simple_app
+
+application iot_simple_app {
+	dbms oracle {
+		provides { sql_interface }
+	}
+
+	software_component web_server {
+		provides { sensor_info }
+		consumes { sql_interface, get_weather }
+	}
+
+	software_component iot_provider {
+		consumes { sensor_info }
+	}
+
+	saas external_meteo {
+		provides { get_weather @ "https://api.mymeteo.com/get" }
+	}
+}
+
+infrastructure infra {
+	vm vm1 {}
+	vm vm2 {}
+	node iot_device1 {}
+	node iot_device2 {}
+}
+
+deployment config1 {
+	oracle -> vm1,
+	web_server -> vm2,
+	iot_provider -> iot_device1,
+	iot_provider -> iot_device2
+}
+
+active deployment config1
+
+concretizations {
+	concrete_infrastructure con_infra1 {
+		provider aws {
+			vm concrete_vm1 {
+				properties { instance_type = "t2.micro"; }
+				maps vm1
+			}
+			vm concrete_vm2 {
+				properties {}
+				maps vm2
+			}
+		}
+	}
+	active con_infra1
+}
\ No newline at end of file
diff --git a/tests/doml/v2.2/iot_simple_app.domlx b/tests/doml/v2.2/iot_simple_app.domlx
new file mode 100644
index 0000000000000000000000000000000000000000..d750eee5e1487c0b0097e48b3a92453dc3da95d2
--- /dev/null
+++ b/tests/doml/v2.2/iot_simple_app.domlx
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="ASCII"?>
+<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" name="iot_simple_app" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0">
+  <application name="iot_simple_app">
+    <components xsi:type="app:DBMS" name="oracle">
+      <exposedInterfaces name="sql_interface"/>
+    </components>
+    <components xsi:type="app:SoftwareComponent" name="web_server" consumedInterfaces="//@application/@components.0/@exposedInterfaces.0 //@application/@components.3/@exposedInterfaces.0">
+      <exposedInterfaces name="sensor_info"/>
+    </components>
+    <components xsi:type="app:SoftwareComponent" name="iot_provider" consumedInterfaces="//@application/@components.1/@exposedInterfaces.0"/>
+    <components xsi:type="app:SaaS" name="external_meteo">
+      <exposedInterfaces name="get_weather" endPoint="https://api.mymeteo.com/get"/>
+    </components>
+  </application>
+  <infrastructure name="infra">
+    <nodes xsi:type="infra:VirtualMachine" name="vm1"/>
+    <nodes xsi:type="infra:VirtualMachine" name="vm2"/>
+    <nodes xsi:type="infra:PhysicalComputingNode" name="iot_device1"/>
+    <nodes xsi:type="infra:PhysicalComputingNode" name="iot_device2"/>
+  </infrastructure>
+  <concretizations name="con_infra1">
+    <providers name="aws">
+      <vms name="concrete_vm1" maps="//@infrastructure/@nodes.0">
+        <annotations xsi:type="commons:SProperty" key="instance_type" value="t2.micro"/>
+      </vms>
+      <vms name="concrete_vm2" maps="//@infrastructure/@nodes.1"/>
+    </providers>
+  </concretizations>
+  <configurations name="config1">
+    <deployments component="//@application/@components.0" node="//@infrastructure/@nodes.0"/>
+    <deployments component="//@application/@components.1" node="//@infrastructure/@nodes.1"/>
+    <deployments component="//@application/@components.2" node="//@infrastructure/@nodes.2"/>
+    <deployments component="//@application/@components.2" node="//@infrastructure/@nodes.3"/>
+  </configurations>
+</commons:DOMLModel>
diff --git a/tests/doml/v2.2/nginx-aws-ec2.doml b/tests/doml/v2.2/nginx-aws-ec2.doml
new file mode 100644
index 0000000000000000000000000000000000000000..8b1f7635abe55981f613ee869c490d364fd236a0
--- /dev/null
+++ b/tests/doml/v2.2/nginx-aws-ec2.doml
@@ -0,0 +1,121 @@
+doml nginx_aws_ec2
+
+application app {
+
+	software_component nginx {
+		properties {
+			source_code="/usr/share/nginx/html/index.html";
+		}
+	}
+}
+
+infrastructure infra {
+
+	vm_image vm_img {
+		generates vm1
+		image "ami-xxxxxxxxxxxxxxxxx"
+	}
+
+	net vpc {
+		cidr "/24"
+		protocol "tcp/ip"
+		subnet vpc_subnet {
+			cidr "/24"
+			protocol "tcp/ip"
+		}
+	}
+
+	security_group sg {
+		egress icmp {
+			from_port -1
+			to_port -1
+			protocol "icmp"
+			cidr ["0.0.0.0/0"]
+		}
+		ingress http {
+			from_port 80
+			to_port 80
+			protocol "tcp"
+			cidr ["0.0.0.0/0"]
+		}
+		ingress https {
+			from_port 443
+			to_port 443
+			protocol "tcp"
+			cidr ["0.0.0.0/0"]
+		}
+		ingress ssh {
+			from_port 22
+			to_port 22
+			protocol "tcp"
+			cidr ["0.0.0.0/0"]
+		}
+		ifaces i1
+	}
+
+	key_pair ssh_key {
+		user "ec2-user"
+		keyfile "/tmp/ssh_key_file"
+		algorithm "RSA"
+		bits 4096
+	}
+
+	autoscale_group ag {
+		vm vm1 {
+			iface i1 {
+				address "10.0.0.1"
+				belongs_to vpc
+				security sg
+			}
+			credentials ssh_key
+			loc {
+				region "eu-central-1"
+			}
+		}
+	}
+}
+
+deployment conf {
+	nginx -> vm1
+}
+
+active deployment conf
+
+concretizations {
+	concrete_infrastructure con_infra {
+		provider aws {
+			vm ec2_vm {
+				properties {
+					vm_name = "nginx-host";
+					instance_type = "t2.micro";
+					ssh_key_name = "demo-key";
+					ec2_role_name = "demo-ec2-role";
+				}
+				maps vm1
+			}
+
+			vm_image concrete_vm_image {
+				maps vm_img
+			}
+
+			net concrete_net {
+				properties {
+					vm_name = "nginx-host";
+				}
+				maps vpc
+			}
+		}
+	}
+	active con_infra
+}
+
+optimization opt {
+	objectives {
+		"cost" => min
+		"availability" => max
+	}
+	nonfunctional_requirements {
+		req1 "Cost <= 70.0" max 70.0 => "cost";
+		req2 "Availability >= 66.5%" min 66.5 => "availability";
+	}
+}
diff --git a/tests/doml/v2.2/nginx-aws-ec2.domlx b/tests/doml/v2.2/nginx-aws-ec2.domlx
new file mode 100644
index 0000000000000000000000000000000000000000..14660f0286d3bb24560cccada553c121e06cd4e9
--- /dev/null
+++ b/tests/doml/v2.2/nginx-aws-ec2.domlx
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="ASCII"?>
+<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" xmlns:optimization="http://www.piacere-project.eu/doml/optimization" name="nginx_aws_ec2" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0">
+  <application name="app">
+    <components xsi:type="app:SoftwareComponent" name="nginx">
+      <annotations xsi:type="commons:SProperty" key="source_code" value="/usr/share/nginx/html/index.html"/>
+    </components>
+  </application>
+  <infrastructure name="infra">
+    <generators xsi:type="infra:VMImage" name="vm_img" uri="ami-xxxxxxxxxxxxxxxxx" kind="IMAGE" generatedVMs="//@infrastructure/@groups.0/@machineDefinition"/>
+    <credentials xsi:type="commons:KeyPair" name="ssh_key" user="ec2-user" keyfile="/tmp/ssh_key_file" algorithm="RSA" bits="4096"/>
+    <groups xsi:type="infra:AutoScalingGroup" name="ag">
+      <machineDefinition name="vm1" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.0">
+        <ifaces name="i1" endPoint="10.0.0.1" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/>
+        <location region="eu-central-1"/>
+      </machineDefinition>
+    </groups>
+    <securityGroups name="sg" ifaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0">
+      <rules name="icmp" protocol="icmp" fromPort="-1" toPort="-1">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="https" kind="INGRESS" protocol="tcp" fromPort="443" toPort="443">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="ssh" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+    </securityGroups>
+    <networks name="vpc" protocol="tcp/ip" addressRange="/24" connectedIfaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0">
+      <subnets name="vpc_subnet" protocol="tcp/ip" addressRange="/24"/>
+    </networks>
+  </infrastructure>
+  <concretizations name="con_infra">
+    <providers name="aws">
+      <vms name="ec2_vm" maps="//@infrastructure/@groups.0/@machineDefinition">
+        <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/>
+        <annotations xsi:type="commons:SProperty" key="instance_type" value="t2.micro"/>
+        <annotations xsi:type="commons:SProperty" key="ssh_key_name" value="demo-key"/>
+        <annotations xsi:type="commons:SProperty" key="ec2_role_name" value="demo-ec2-role"/>
+      </vms>
+      <vmImages name="concrete_vm_image" maps="//@infrastructure/@generators.0"/>
+      <networks name="concrete_net" maps="//@infrastructure/@networks.0">
+        <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/>
+      </networks>
+    </providers>
+  </concretizations>
+  <optimization name="opt">
+    <objectives xsi:type="optimization:MeasurableObjective" kind="min" property="cost"/>
+    <objectives xsi:type="optimization:MeasurableObjective" kind="max" property="availability"/>
+    <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req1" description="Cost &lt;= 70.0" property="cost" max="70.0"/>
+    <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req2" description="Availability >= 66.5%" property="availability" min="66.5"/>
+  </optimization>
+  <configurations name="conf">
+    <deployments component="//@application/@components.0" node="//@infrastructure/@groups.0/@machineDefinition"/>
+  </configurations>
+</commons:DOMLModel>
diff --git a/tests/doml/v2.2/nginx-csp-compatibility-test.doml b/tests/doml/v2.2/nginx-csp-compatibility-test.doml
new file mode 100644
index 0000000000000000000000000000000000000000..5b6d95639a02c7114a1f245150105b38d21579a2
--- /dev/null
+++ b/tests/doml/v2.2/nginx-csp-compatibility-test.doml
@@ -0,0 +1,132 @@
+doml nginx_aws_ec2
+
+application app {
+
+	software_component nginx {
+		properties {
+			source_code="/usr/share/nginx/html/index.html";
+		}
+	}
+}
+
+infrastructure infra {
+
+	vm_image vm_img {
+		generates vm1
+		image "ami-xxxxxxxxxxxxxxxxx"
+	}
+
+	net vpc {
+		cidr "/24"
+		protocol "tcp/ip"
+		subnet vpc_subnet {
+			cidr "/24"
+			protocol "tcp/ip"
+		}
+	}
+
+	security_group sg {
+		egress icmp {
+			from_port -1
+			to_port -1
+			protocol "icmp"
+			cidr ["0.0.0.0/0"]
+		}
+		ingress http {
+			from_port 80
+			to_port 80
+			protocol "tcp"
+			cidr ["0.0.0.0/0"]
+		}
+		ingress https {
+			from_port 443
+			to_port 443
+			protocol "tcp"
+			cidr ["0.0.0.0/0"]
+		}
+		ingress ssh {
+			from_port 22
+			to_port 22
+			protocol "tcp"
+			cidr ["0.0.0.0/0"]
+		}
+		ifaces i1
+	}
+
+	key_pair ssh_key {
+		user "ec2-user"
+		keyfile "/tmp/ssh_key_file"
+		algorithm "RSA"
+		bits 4096
+	}
+	
+	key_pair ed_key {
+		user "ec2-user"
+		keyfile "/tmp/ED25519_key_file"
+		algorithm "ED25519"
+	}
+
+	autoscale_group ag {
+		vm vm1 {
+			arch "x86"
+			os "RHEL"
+			cpu_count 128
+			mem_mb 512000.0
+			
+			iface i1 {
+				address "10.0.0.1"
+				belongs_to vpc
+				security sg
+			}
+			credentials ssh_key
+			loc {
+				region "eu-central-1"
+			}
+		}
+	}
+}
+
+deployment conf {
+	nginx -> vm1
+}
+
+active deployment conf
+
+concretizations {
+	concrete_infrastructure con_infra {
+		provider aws {
+			vm ec2_vm {
+				properties {
+					vm_name = "nginx-host";
+					instance_type = "t2.micro";
+					ssh_key_name = "demo-key";
+					ec2_role_name = "demo-ec2-role";
+				}
+				maps vm1
+			}
+
+			vm_image concrete_vm_image {
+				maps vm_img
+			}
+
+			net concrete_net {
+				properties {
+					vm_name = "nginx-host";
+				}
+				maps vpc
+			}
+		}
+	}
+	active con_infra
+}
+
+optimization opt {
+	objectives {
+		"cost" => min
+		"availability" => max
+	}
+	nonfunctional_requirements {
+		req1 "Cost <= 70.0" max 70.0 => "cost";
+		req2 "Availability >= 66.5%" min 66.5 => "availability";
+	}
+}
diff --git a/tests/doml/v2.2/nginx-csp-compatibility-test.domlx b/tests/doml/v2.2/nginx-csp-compatibility-test.domlx
new file mode 100644
index 0000000000000000000000000000000000000000..a53d27a95dba6e5220fe26fe71d8f72fbe4f5374
--- /dev/null
+++ b/tests/doml/v2.2/nginx-csp-compatibility-test.domlx
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="ASCII"?>
+<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" xmlns:optimization="http://www.piacere-project.eu/doml/optimization" name="nginx_aws_ec2" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0">
+  <application name="app">
+    <components xsi:type="app:SoftwareComponent" name="nginx">
+      <annotations xsi:type="commons:SProperty" key="source_code" value="/usr/share/nginx/html/index.html"/>
+    </components>
+  </application>
+  <infrastructure name="infra">
+    <generators xsi:type="infra:VMImage" name="vm_img" uri="ami-xxxxxxxxxxxxxxxxx" kind="IMAGE" generatedVMs="//@infrastructure/@groups.0/@machineDefinition"/>
+    <credentials xsi:type="commons:KeyPair" name="ssh_key" user="ec2-user" keyfile="/tmp/ssh_key_file" algorithm="RSA" bits="4096"/>
+    <credentials xsi:type="commons:KeyPair" name="ed_key" user="ec2-user" keyfile="/tmp/ED25519_key_file" algorithm="ED25519"/>
+    <groups xsi:type="infra:AutoScalingGroup" name="ag">
+      <machineDefinition name="vm1" architecture="x86" os="RHEL" memory_mb="512000.0" cpu_count="128" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.0">
+        <ifaces name="i1" endPoint="10.0.0.1" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/>
+        <location region="eu-central-1"/>
+      </machineDefinition>
+    </groups>
+    <securityGroups name="sg" ifaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0">
+      <rules name="icmp" protocol="icmp" fromPort="-1" toPort="-1">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="https" kind="INGRESS" protocol="tcp" fromPort="443" toPort="443">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="ssh" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+    </securityGroups>
+    <networks name="vpc" protocol="tcp/ip" addressRange="/24" connectedIfaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0">
+      <subnets name="vpc_subnet" protocol="tcp/ip" addressRange="/24"/>
+    </networks>
+  </infrastructure>
+  <concretizations name="con_infra">
+    <providers name="aws">
+      <vms name="ec2_vm" maps="//@infrastructure/@groups.0/@machineDefinition">
+        <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/>
+        <annotations xsi:type="commons:SProperty" key="instance_type" value="t2.micro"/>
+        <annotations xsi:type="commons:SProperty" key="ssh_key_name" value="demo-key"/>
+        <annotations xsi:type="commons:SProperty" key="ec2_role_name" value="demo-ec2-role"/>
+      </vms>
+      <vmImages name="concrete_vm_image" maps="//@infrastructure/@generators.0"/>
+      <networks name="concrete_net" maps="//@infrastructure/@networks.0">
+        <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/>
+      </networks>
+    </providers>
+  </concretizations>
+  <optimization name="opt">
+    <objectives xsi:type="optimization:MeasurableObjective" kind="min" property="cost"/>
+    <objectives xsi:type="optimization:MeasurableObjective" kind="max" property="availability"/>
+    <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req1" description="Cost &lt;= 70.0" property="cost" max="70.0"/>
+    <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req2" description="Availability >= 66.5%" property="availability" min="66.5"/>
+  </optimization>
+  <configurations name="conf">
+    <deployments component="//@application/@components.0" node="//@infrastructure/@groups.0/@machineDefinition"/>
+  </configurations>
+</commons:DOMLModel>
diff --git a/tests/doml/v2.2/nginx_flags.doml b/tests/doml/v2.2/nginx_flags.doml
new file mode 100644
index 0000000000000000000000000000000000000000..0434ccafbde78f2ab03c62ff6048cd1d512a8f5e
--- /dev/null
+++ b/tests/doml/v2.2/nginx_flags.doml
@@ -0,0 +1,140 @@
+doml nginx_func_req
+version "v2.2"
+
+application app {
+
+	software_component nginx {
+		properties {
+			source_code="/usr/share/nginx/html/index.html";
+		}
+	}
+}
+
+infrastructure infra {
+
+	vm_image vm_img {
+		generates vm1
+		image "ami-xxxxxxxxxxxxxxxxx"
+	}
+
+	net vpc {
+		cidr "/24"
+		protocol "tcp/ip"
+		subnet vpc_subnet {
+			cidr "/24"
+			protocol "tcp/ip"
+		}
+	}
+
+	security_group sg {
+		egress icmp {
+			from_port -1
+			to_port -1
+			protocol "icmp"
+			cidr ["0.0.0.0/0"]
+		}
+		ingress http {
+			from_port 80
+			to_port 80
+			protocol "tcp"
+			cidr ["0.0.0.0/0"]
+		}
+		ingress https {
+			from_port 443
+			to_port 443
+			protocol "tcp"
+			cidr ["0.0.0.0/0"]
+		}
+		ingress ssh {
+			from_port 22
+			to_port 22
+			protocol "tcp"
+			cidr ["0.0.0.0/0"]
+		}
+		ifaces i1
+	}
+
+	key_pair ssh_key {
+		user "ec2-user"
+		keyfile "/tmp/ssh_key_file"
+		algorithm "RSA"
+		bits 4096
+	}
+
+	autoscale_group ag {
+		vm vm1 {
+			iface i1 {
+				address "10.0.0.1"
+				belongs_to vpc
+				security sg
+			}
+			credentials ssh_key
+			loc {
+				region "eu-central-1"
+			}
+		}
+	}
+}
+
+deployment conf {
+	nginx -> vm1
+}
+
+active deployment conf
+
+concretizations {
+	concrete_infrastructure con_infra {
+		provider aws {
+			vm ec2_vm {
+				properties {
+					vm_name = "nginx-host";
+					instance_type = "t2.micro";
+					ssh_key_name = "demo-key";
+					ec2_role_name = "demo-ec2-role";
+				}
+				maps vm1
+			}
+
+			vm_image concrete_vm_image {
+				maps vm_img
+			}
+
+			net concrete_net {
+				properties {
+					vm_name = "nginx-host";
+				}
+				maps vpc
+			}
+		}
+	}
+	active con_infra
+}
+
+optimization opt {
+	objectives {
+		"cost" => min
+		"availability" => max
+	}
+	nonfunctional_requirements {
+		req1 "Cost <= 70.0" max 70.0 => "cost";
+		req2 "Availability >= 66.5%" min 66.5 => "availability";
+	}
+}
+
+functional_requirements {
+req_ext ```
+%IGNORE vm_has_iface
+%CHECK enforce_os_on_vm
+%CSP
+- "VM must have iface and iface is connected to network"
+	vm is class abstract.VirtualMachine
+	and
+	not exists iface, net (
+    	vm has abstract.ComputingNode.ifaces iface
+    	and
+    	iface has abstract.NetworkInterface.belongsTo net
+    
+    )
+ error: "TEST ERROR"
+ 
+ ```;}
diff --git a/tests/doml/v2.2/nginx_flags.domlx b/tests/doml/v2.2/nginx_flags.domlx
new file mode 100644
index 0000000000000000000000000000000000000000..740cac9ced98989998d29b322f5ac446612042f4
--- /dev/null
+++ b/tests/doml/v2.2/nginx_flags.domlx
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="ASCII"?>
+<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" xmlns:optimization="http://www.piacere-project.eu/doml/optimization" name="nginx_func_req" version="v2.2" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0">
+  <application name="app">
+    <components xsi:type="app:SoftwareComponent" name="nginx">
+      <annotations xsi:type="commons:SProperty" key="source_code" value="/usr/share/nginx/html/index.html"/>
+    </components>
+  </application>
+  <infrastructure name="infra">
+    <generators xsi:type="infra:VMImage" name="vm_img" uri="ami-xxxxxxxxxxxxxxxxx" kind="IMAGE" generatedVMs="//@infrastructure/@groups.0/@machineDefinition"/>
+    <credentials xsi:type="commons:KeyPair" name="ssh_key" user="ec2-user" keyfile="/tmp/ssh_key_file" algorithm="RSA" bits="4096"/>
+    <groups xsi:type="infra:AutoScalingGroup" name="ag">
+      <machineDefinition name="vm1" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.0">
+        <ifaces name="i1" endPoint="10.0.0.1" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/>
+        <location region="eu-central-1"/>
+      </machineDefinition>
+    </groups>
+    <securityGroups name="sg" ifaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0">
+      <rules name="icmp" protocol="icmp" fromPort="-1" toPort="-1">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="https" kind="INGRESS" protocol="tcp" fromPort="443" toPort="443">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="ssh" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+    </securityGroups>
+    <networks name="vpc" protocol="tcp/ip" addressRange="/24" connectedIfaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0">
+      <subnets name="vpc_subnet" protocol="tcp/ip" addressRange="/24"/>
+    </networks>
+  </infrastructure>
+  <concretizations name="con_infra">
+    <providers name="aws">
+      <vms name="ec2_vm" maps="//@infrastructure/@groups.0/@machineDefinition">
+        <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/>
+        <annotations xsi:type="commons:SProperty" key="instance_type" value="t2.micro"/>
+        <annotations xsi:type="commons:SProperty" key="ssh_key_name" value="demo-key"/>
+        <annotations xsi:type="commons:SProperty" key="ec2_role_name" value="demo-ec2-role"/>
+      </vms>
+      <vmImages name="concrete_vm_image" maps="//@infrastructure/@generators.0"/>
+      <networks name="concrete_net" maps="//@infrastructure/@networks.0">
+        <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/>
+      </networks>
+    </providers>
+  </concretizations>
+  <optimization name="opt">
+    <objectives xsi:type="optimization:MeasurableObjective" kind="min" property="cost"/>
+    <objectives xsi:type="optimization:MeasurableObjective" kind="max" property="availability"/>
+    <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req1" description="Cost &lt;= 70.0" property="cost" max="70.0"/>
+    <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req2" description="Availability >= 66.5%" property="availability" min="66.5"/>
+  </optimization>
+  <configurations name="conf">
+    <deployments component="//@application/@components.0" node="//@infrastructure/@groups.0/@machineDefinition"/>
+  </configurations>
+  <functionalRequirements name="req_ext" description="```&#xA;%IGNORE vm_has_iface&#xA;%CHECK enforce_os_on_vm&#xA;%CSP&#xA;- &quot;VM must have iface and iface is connected to network&quot;&#xA;&#x9;vm is class abstract.VirtualMachine&#xA;&#x9;and&#xA;&#x9;not exists iface, net (&#xA;    &#x9;vm has abstract.ComputingNode.ifaces iface&#xA;    &#x9;and&#xA;    &#x9;iface has abstract.NetworkInterface.belongsTo net&#xA;    &#xA;    )&#xA; error: &quot;TEST ERROR&quot;&#xA; &#xA; ```"/>
+</commons:DOMLModel>
diff --git a/tests/doml/v2.2/nginx_func_req.doml b/tests/doml/v2.2/nginx_func_req.doml
new file mode 100644
index 0000000000000000000000000000000000000000..3595366211af53d66fead9a293e9a38c69622bbb
--- /dev/null
+++ b/tests/doml/v2.2/nginx_func_req.doml
@@ -0,0 +1,150 @@
+doml nginx_func_req
+version "v2.2"
+
+application app {
+
+	software_component nginx {
+		properties {
+			source_code="/usr/share/nginx/html/index.html";
+		}
+	}
+}
+
+infrastructure infra {
+
+	vm_image vm_img {
+		generates vm1
+		image "ami-xxxxxxxxxxxxxxxxx"
+	}
+
+	net vpc {
+		cidr "/24"
+		protocol "tcp/ip"
+		subnet vpc_subnet {
+			cidr "/24"
+			protocol "tcp/ip"
+		}
+	}
+
+	security_group sg {
+		egress icmp {
+			from_port -1
+			to_port -1
+			protocol "icmp"
+			cidr ["0.0.0.0/0"]
+		}
+		ingress http {
+			from_port 80
+			to_port 80
+			protocol "tcp"
+			cidr ["0.0.0.0/0"]
+		}
+		ingress https {
+			from_port 443
+			to_port 443
+			protocol "tcp"
+			cidr ["0.0.0.0/0"]
+		}
+		ingress ssh {
+			from_port 22
+			to_port 22
+			protocol "tcp"
+			cidr ["0.0.0.0/0"]
+		}
+		ifaces i1
+	}
+
+	key_pair ssh_key {
+		user "ec2-user"
+		keyfile "/tmp/ssh_key_file"
+		algorithm "RSA"
+		bits 4096
+	}
+
+	autoscale_group ag {
+		vm vm1 {
+			iface i1 {
+				address "10.0.0.1"
+				belongs_to vpc
+				security sg
+			}
+			credentials ssh_key
+			loc {
+				region "eu-central-1"
+			}
+		}
+	}
+}
+
+deployment conf {
+	nginx -> vm1
+}
+
+active deployment conf
+
+concretizations {
+	concrete_infrastructure con_infra {
+		provider aws {
+			vm ec2_vm {
+				properties {
+					vm_name = "nginx-host";
+					instance_type = "t2.micro";
+					ssh_key_name = "demo-key";
+					ec2_role_name = "demo-ec2-role";
+				}
+				maps vm1
+			}
+
+			vm_image concrete_vm_image {
+				maps vm_img
+			}
+
+			net concrete_net {
+				properties {
+					vm_name = "nginx-host";
+				}
+				maps vpc
+			}
+		}
+	}
+	active con_infra
+}
+
+optimization opt {
+	objectives {
+		"cost" => min
+		"availability" => max
+	}
+	nonfunctional_requirements {
+		req1 "Cost <= 70.0" max 70.0 => "cost";
+		req2 "Availability >= 66.5%" min 66.5 => "availability";
+	}
+}
+
+functional_requirements {
+req_ext ```
+
+# + "VM must have iface and iface is connected to network"
+# 	forall vm (
+# 		vm is class abstract.VirtualMachine
+#    	implies
+#        (
+#        	vm has abstract.ComputingNode.ifaces iface
+#        	and
+#        	iface has abstract.NetworkInterface.belongsTo net
+#        )
+#    )
+# error: "TEST ERROR"
+
+- "VM must have iface and iface is connected to network"
+	vm is class abstract.VirtualMachine
+	and
+	not exists iface, net (
+    	vm has abstract.ComputingNode.ifaces iface
+    	and
+    	iface has abstract.NetworkInterface.belongsTo net
+    
+    )
+ error: "TEST ERROR"
+ 
+ ```;}
diff --git a/tests/doml/v2.2/nginx_func_req.domlx b/tests/doml/v2.2/nginx_func_req.domlx
new file mode 100644
index 0000000000000000000000000000000000000000..aff808cd870eb85a17785aceb7aa0052c58a2cf2
--- /dev/null
+++ b/tests/doml/v2.2/nginx_func_req.domlx
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="ASCII"?>
+<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" xmlns:optimization="http://www.piacere-project.eu/doml/optimization" name="nginx_func_req" version="v2.2" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0">
+  <application name="app">
+    <components xsi:type="app:SoftwareComponent" name="nginx">
+      <annotations xsi:type="commons:SProperty" key="source_code" value="/usr/share/nginx/html/index.html"/>
+    </components>
+  </application>
+  <infrastructure name="infra">
+    <generators xsi:type="infra:VMImage" name="vm_img" uri="ami-xxxxxxxxxxxxxxxxx" kind="IMAGE" generatedVMs="//@infrastructure/@groups.0/@machineDefinition"/>
+    <credentials xsi:type="commons:KeyPair" name="ssh_key" user="ec2-user" keyfile="/tmp/ssh_key_file" algorithm="RSA" bits="4096"/>
+    <groups xsi:type="infra:AutoScalingGroup" name="ag">
+      <machineDefinition name="vm1" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.0">
+        <ifaces name="i1" endPoint="10.0.0.1" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/>
+        <location region="eu-central-1"/>
+      </machineDefinition>
+    </groups>
+    <securityGroups name="sg" ifaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0">
+      <rules name="icmp" protocol="icmp" fromPort="-1" toPort="-1">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="https" kind="INGRESS" protocol="tcp" fromPort="443" toPort="443">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="ssh" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+    </securityGroups>
+    <networks name="vpc" protocol="tcp/ip" addressRange="/24" connectedIfaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0">
+      <subnets name="vpc_subnet" protocol="tcp/ip" addressRange="/24"/>
+    </networks>
+  </infrastructure>
+  <concretizations name="con_infra">
+    <providers name="aws">
+      <vms name="ec2_vm" maps="//@infrastructure/@groups.0/@machineDefinition">
+        <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/>
+        <annotations xsi:type="commons:SProperty" key="instance_type" value="t2.micro"/>
+        <annotations xsi:type="commons:SProperty" key="ssh_key_name" value="demo-key"/>
+        <annotations xsi:type="commons:SProperty" key="ec2_role_name" value="demo-ec2-role"/>
+      </vms>
+      <vmImages name="concrete_vm_image" maps="//@infrastructure/@generators.0"/>
+      <networks name="concrete_net" maps="//@infrastructure/@networks.0">
+        <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/>
+      </networks>
+    </providers>
+  </concretizations>
+  <optimization name="opt">
+    <objectives xsi:type="optimization:MeasurableObjective" kind="min" property="cost"/>
+    <objectives xsi:type="optimization:MeasurableObjective" kind="max" property="availability"/>
+    <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req1" description="Cost &lt;= 70.0" property="cost" max="70.0"/>
+    <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req2" description="Availability >= 66.5%" property="availability" min="66.5"/>
+  </optimization>
+  <configurations name="conf">
+    <deployments component="//@application/@components.0" node="//@infrastructure/@groups.0/@machineDefinition"/>
+  </configurations>
+  <functionalRequirements name="req_ext" description="```&#xA;&#xA;# + &quot;VM must have iface and iface is connected to network&quot;&#xA;# &#x9;forall vm (&#xA;# &#x9;&#x9;vm is class abstract.VirtualMachine&#xA;#    &#x9;implies&#xA;#        (&#xA;#        &#x9;vm has abstract.ComputingNode.ifaces iface&#xA;#        &#x9;and&#xA;#        &#x9;iface has abstract.NetworkInterface.belongsTo net&#xA;#        )&#xA;#    )&#xA;# error: &quot;TEST ERROR&quot;&#xA;&#xA;- &quot;VM must have iface and iface is connected to network&quot;&#xA;&#x9;vm is class abstract.VirtualMachine&#xA;&#x9;and&#xA;&#x9;not exists iface, net (&#xA;    &#x9;vm has abstract.ComputingNode.ifaces iface&#xA;    &#x9;and&#xA;    &#x9;iface has abstract.NetworkInterface.belongsTo net&#xA;    &#xA;    )&#xA; error: &quot;TEST ERROR&quot;&#xA; &#xA; ```"/>
+</commons:DOMLModel>
diff --git a/tests/doml/v2.2/nginx_func_req2_unsat.domlx b/tests/doml/v2.2/nginx_func_req2_unsat.domlx
new file mode 100644
index 0000000000000000000000000000000000000000..b05aa09b6d9ade8bc2a8a7c3a240c2296b6d76e4
--- /dev/null
+++ b/tests/doml/v2.2/nginx_func_req2_unsat.domlx
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="ASCII"?>
+<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" xmlns:optimization="http://www.piacere-project.eu/doml/optimization" name="nginx_func_req" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0">
+  <application name="app">
+    <components xsi:type="app:SoftwareComponent" name="nginx">
+      <annotations xsi:type="commons:SProperty" key="source_code" value="/usr/share/nginx/html/index.html"/>
+    </components>
+  </application>
+  <infrastructure name="infra">
+    <generators xsi:type="infra:VMImage" name="vm_img" uri="ami-xxxxxxxxxxxxxxxxx" kind="IMAGE" generatedVMs="//@infrastructure/@groups.0/@machineDefinition"/>
+    <credentials xsi:type="commons:KeyPair" name="ssh_key" user="ec2-user" keyfile="/tmp/ssh_key_file" algorithm="RSA" bits="4096"/>
+    <groups xsi:type="infra:AutoScalingGroup" name="ag">
+      <machineDefinition name="vm1" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.0">
+        <ifaces name="i1" endPoint="10.0.0.1" associated="//@infrastructure/@securityGroups.0"/>
+        <location region="eu-central-1"/>
+      </machineDefinition>
+    </groups>
+    <securityGroups name="sg" ifaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0">
+      <rules name="icmp" protocol="icmp" fromPort="-1" toPort="-1">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="https" kind="INGRESS" protocol="tcp" fromPort="443" toPort="443">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="ssh" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+    </securityGroups>
+    <networks name="vpc" protocol="tcp/ip" addressRange="/24">
+      <subnets name="vpc_subnet" protocol="tcp/ip" addressRange="/24"/>
+    </networks>
+  </infrastructure>
+  <concretizations name="con_infra">
+    <providers name="aws">
+      <vms name="ec2_vm" maps="//@infrastructure/@groups.0/@machineDefinition">
+        <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/>
+        <annotations xsi:type="commons:SProperty" key="instance_type" value="t2.micro"/>
+        <annotations xsi:type="commons:SProperty" key="ssh_key_name" value="demo-key"/>
+        <annotations xsi:type="commons:SProperty" key="ec2_role_name" value="demo-ec2-role"/>
+      </vms>
+      <vmImages name="concrete_vm_image" maps="//@infrastructure/@generators.0"/>
+      <networks name="concrete_net" maps="//@infrastructure/@networks.0">
+        <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/>
+      </networks>
+    </providers>
+  </concretizations>
+  <optimization name="opt">
+    <objectives xsi:type="optimization:MeasurableObjective" kind="min" property="cost"/>
+    <objectives xsi:type="optimization:MeasurableObjective" kind="max" property="availability"/>
+    <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req1" description="Cost &lt;= 70.0" property="cost" max="70.0"/>
+    <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req2" description="Availability >= 66.5%" property="availability" min="66.5"/>
+  </optimization>
+  <configurations name="conf">
+    <deployments component="//@application/@components.0" node="//@infrastructure/@groups.0/@machineDefinition"/>
+  </configurations>
+  <functionalRequirements name="req_ext" description="```&#xA;&#xA; + &quot;VM must have iface and iface is connected to network&quot;&#xA; &#x9;forall vm (&#xA; &#x9;&#x9;vm is class abstract.VirtualMachine&#xA;    &#x9;implies&#xA;        (&#xA;        &#x9;vm has abstract.ComputingNode.ifaces iface&#xA;        &#x9;and&#xA;        &#x9;iface has abstract.NetworkInterface.belongsTo net&#xA;        )&#xA;    )&#xA; error: &quot;TEST ERROR {vm}&quot;&#xA; &#xA; ```"/>
+</commons:DOMLModel>
diff --git a/tests/doml/v2.2/nginx_func_req2_unsat_neg.domlx b/tests/doml/v2.2/nginx_func_req2_unsat_neg.domlx
new file mode 100644
index 0000000000000000000000000000000000000000..e577a79eccc03adce5be21f56ce4495894f39b2d
--- /dev/null
+++ b/tests/doml/v2.2/nginx_func_req2_unsat_neg.domlx
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="ASCII"?>
+<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" xmlns:optimization="http://www.piacere-project.eu/doml/optimization" name="nginx_func_req" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0">
+  <application name="app">
+    <components xsi:type="app:SoftwareComponent" name="nginx">
+      <annotations xsi:type="commons:SProperty" key="source_code" value="/usr/share/nginx/html/index.html"/>
+    </components>
+  </application>
+  <infrastructure name="infra">
+    <generators xsi:type="infra:VMImage" name="vm_img" uri="ami-xxxxxxxxxxxxxxxxx" kind="IMAGE" generatedVMs="//@infrastructure/@groups.0/@machineDefinition"/>
+    <credentials xsi:type="commons:KeyPair" name="ssh_key" user="ec2-user" keyfile="/tmp/ssh_key_file" algorithm="RSA" bits="4096"/>
+    <groups xsi:type="infra:AutoScalingGroup" name="ag">
+      <machineDefinition name="vm1" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.0">
+        <ifaces name="i1" endPoint="10.0.0.1" associated="//@infrastructure/@securityGroups.0"/>
+        <location region="eu-central-1"/>
+      </machineDefinition>
+    </groups>
+    <securityGroups name="sg" ifaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0">
+      <rules name="icmp" protocol="icmp" fromPort="-1" toPort="-1">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="https" kind="INGRESS" protocol="tcp" fromPort="443" toPort="443">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="ssh" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+    </securityGroups>
+    <networks name="vpc" protocol="tcp/ip" addressRange="/24">
+      <subnets name="vpc_subnet" protocol="tcp/ip" addressRange="/24"/>
+    </networks>
+  </infrastructure>
+  <concretizations name="con_infra">
+    <providers name="aws">
+      <vms name="ec2_vm" maps="//@infrastructure/@groups.0/@machineDefinition">
+        <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/>
+        <annotations xsi:type="commons:SProperty" key="instance_type" value="t2.micro"/>
+        <annotations xsi:type="commons:SProperty" key="ssh_key_name" value="demo-key"/>
+        <annotations xsi:type="commons:SProperty" key="ec2_role_name" value="demo-ec2-role"/>
+      </vms>
+      <vmImages name="concrete_vm_image" maps="//@infrastructure/@generators.0"/>
+      <networks name="concrete_net" maps="//@infrastructure/@networks.0">
+        <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/>
+      </networks>
+    </providers>
+  </concretizations>
+  <optimization name="opt">
+    <objectives xsi:type="optimization:MeasurableObjective" kind="min" property="cost"/>
+    <objectives xsi:type="optimization:MeasurableObjective" kind="max" property="availability"/>
+    <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req1" description="Cost &lt;= 70.0" property="cost" max="70.0"/>
+    <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req2" description="Availability >= 66.5%" property="availability" min="66.5"/>
+  </optimization>
+  <configurations name="conf">
+    <deployments component="//@application/@components.0" node="//@infrastructure/@groups.0/@machineDefinition"/>
+  </configurations>
+  <functionalRequirements name="req_ext" description="```&#xA;&#xA;# + &quot;VM must have iface and iface is connected to network&quot;&#xA;# &#x9;forall vm (&#xA;# &#x9;&#x9;vm is class abstract.VirtualMachine&#xA;#    &#x9;implies&#xA;#        (&#xA;#        &#x9;vm has abstract.ComputingNode.ifaces iface&#xA;#        &#x9;and&#xA;#        &#x9;iface has abstract.NetworkInterface.belongsTo net&#xA;#        )&#xA;#    )&#xA;# error: &quot;TEST ERROR&quot;&#xA;&#xA;- &quot;VM must have iface and iface is connected to network&quot;&#xA;&#x9;vm is class abstract.VirtualMachine&#xA;&#x9;and&#xA;&#x9;not exists iface, net (&#xA;    &#x9;vm has abstract.ComputingNode.ifaces iface&#xA;    &#x9;and&#xA;    &#x9;iface has abstract.NetworkInterface.belongsTo net&#xA;    &#xA;    )&#xA; error: &quot;TEST ERROR&quot;&#xA; &#xA; ```"/>
+</commons:DOMLModel>
diff --git a/tests/doml/v2.2/nginx_func_req_neg.domlx b/tests/doml/v2.2/nginx_func_req_neg.domlx
new file mode 100644
index 0000000000000000000000000000000000000000..206a82af3d96c2f2a393981599b26adf6cfd5b94
--- /dev/null
+++ b/tests/doml/v2.2/nginx_func_req_neg.domlx
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="ASCII"?>
+<commons:DOMLModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:app="http://www.piacere-project.eu/doml/application" xmlns:commons="http://www.piacere-project.eu/doml/commons" xmlns:infra="http://www.piacere-project.eu/doml/infrastructure" xmlns:optimization="http://www.piacere-project.eu/doml/optimization" name="nginx_func_req" activeConfiguration="//@configurations.0" activeInfrastructure="//@concretizations.0">
+  <application name="app">
+    <components xsi:type="app:SoftwareComponent" name="nginx">
+      <annotations xsi:type="commons:SProperty" key="source_code" value="/usr/share/nginx/html/index.html"/>
+    </components>
+  </application>
+  <infrastructure name="infra">
+    <generators xsi:type="infra:VMImage" name="vm_img" uri="ami-xxxxxxxxxxxxxxxxx" kind="IMAGE" generatedVMs="//@infrastructure/@groups.0/@machineDefinition"/>
+    <credentials xsi:type="commons:KeyPair" name="ssh_key" user="ec2-user" keyfile="/tmp/ssh_key_file" algorithm="RSA" bits="4096"/>
+    <groups xsi:type="infra:AutoScalingGroup" name="ag">
+      <machineDefinition name="vm1" credentials="//@infrastructure/@credentials.0" generatedFrom="//@infrastructure/@generators.0">
+        <ifaces name="i1" endPoint="10.0.0.1" belongsTo="//@infrastructure/@networks.0" associated="//@infrastructure/@securityGroups.0"/>
+        <location region="eu-central-1"/>
+      </machineDefinition>
+    </groups>
+    <securityGroups name="sg" ifaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0">
+      <rules name="icmp" protocol="icmp" fromPort="-1" toPort="-1">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="http" kind="INGRESS" protocol="tcp" fromPort="80" toPort="80">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="https" kind="INGRESS" protocol="tcp" fromPort="443" toPort="443">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+      <rules name="ssh" kind="INGRESS" protocol="tcp" fromPort="22" toPort="22">
+        <cidr>0.0.0.0/0</cidr>
+      </rules>
+    </securityGroups>
+    <networks name="vpc" protocol="tcp/ip" addressRange="/24" connectedIfaces="//@infrastructure/@groups.0/@machineDefinition/@ifaces.0">
+      <subnets name="vpc_subnet" protocol="tcp/ip" addressRange="/24"/>
+    </networks>
+  </infrastructure>
+  <concretizations name="con_infra">
+    <providers name="aws">
+      <vms name="ec2_vm" maps="//@infrastructure/@groups.0/@machineDefinition">
+        <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/>
+        <annotations xsi:type="commons:SProperty" key="instance_type" value="t2.micro"/>
+        <annotations xsi:type="commons:SProperty" key="ssh_key_name" value="demo-key"/>
+        <annotations xsi:type="commons:SProperty" key="ec2_role_name" value="demo-ec2-role"/>
+      </vms>
+      <vmImages name="concrete_vm_image" maps="//@infrastructure/@generators.0"/>
+      <networks name="concrete_net" maps="//@infrastructure/@networks.0">
+        <annotations xsi:type="commons:SProperty" key="vm_name" value="nginx-host"/>
+      </networks>
+    </providers>
+  </concretizations>
+  <optimization name="opt">
+    <objectives xsi:type="optimization:MeasurableObjective" kind="min" property="cost"/>
+    <objectives xsi:type="optimization:MeasurableObjective" kind="max" property="availability"/>
+    <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req1" description="Cost &lt;= 70.0" property="cost" max="70.0"/>
+    <nonfunctionalRequirements xsi:type="commons:RangedRequirement" name="req2" description="Availability >= 66.5%" property="availability" min="66.5"/>
+  </optimization>
+  <configurations name="conf">
+    <deployments component="//@application/@components.0" node="//@infrastructure/@groups.0/@machineDefinition"/>
+  </configurations>
+  <functionalRequirements name="req_ext" description="```&#xA;&#xA;# + &quot;VM must have iface and iface is connected to network&quot;&#xA;# &#x9;forall vm (&#xA;# &#x9;&#x9;vm is class abstract.VirtualMachine&#xA;#    &#x9;implies&#xA;#        (&#xA;#        &#x9;vm has abstract.ComputingNode.ifaces iface&#xA;#        &#x9;and&#xA;#        &#x9;iface has abstract.NetworkInterface.belongsTo net&#xA;#        )&#xA;#    )&#xA;# error: &quot;TEST ERROR&quot;&#xA;&#xA;- &quot;VM must have iface and iface is connected to network&quot;&#xA;&#x9;vm is class abstract.VirtualMachine&#xA;&#x9;and&#xA;&#x9;not exists iface, net (&#xA;    &#x9;vm has abstract.ComputingNode.ifaces iface&#xA;    &#x9;and&#xA;    &#x9;iface has abstract.NetworkInterface.belongsTo net&#xA;    &#xA;    )&#xA; error: &quot;TEST ERROR&quot;&#xA; &#xA; ```"/>
+</commons:DOMLModel>
diff --git a/tests/doml/v2.3/UC3_Simplified.doml b/tests/doml/v2.3/UC3_Simplified.doml
new file mode 100644
index 0000000000000000000000000000000000000000..93e3e5b0fce02f66bed954c8bb73132d8c779544
--- /dev/null
+++ b/tests/doml/v2.3/UC3_Simplified.doml
@@ -0,0 +1,294 @@
+doml uc3_openstack
+
+application app {
+
+	// need to define all sw components of the project this is a placeholder
+	// need to understand what is really needed in this spec
+	// need to specify all provides/consumes
+
+	software_component iwg {
+		provides { net_info }
+	}
+	software_component osint {
+		provides { osint_info }
+		consumes { net_info, get_twitter, ewcf_rest_interface }
+	}
+	software_component ewcf {
+		provides { ewcf_rest_interface }
+		consumes { get_firebase }
+	}
+	saas external_twitter {
+		provides { get_twitter @ "https://twitter_api/get" }
+	}
+	saas external_firebase {
+		provides { get_firebase @ "https://firebase_api/get" }
+	}
+
+}
+
+infrastructure infra {
+	// Giuseppe - tutti devono collegarsi a oam
+	// Giuseppe - igw deve avere reti oam la net1 verso osint e net2 verso network 5G 
+	
+	// VMs region
+	vm igw_vm {
+		os "Ubuntu-Focal-20.04-Daily-2022-04-19"
+		size "small"
+		
+		iface igw_vm_oam {
+			belongs_to subnet_oam_igw
+		}
+		
+		iface igw_vm_net1 {
+			belongs_to subnet_net1_igw
+		}
+		
+		iface igw_vm_net2 {
+			belongs_to subnet_net2_igw
+		}
+		
+		credentials ssh_key
+	}
+
+	// Giuseppe - osint deve avere reti oam la net1 verso igw e net3 verso network internet
+	vm osint_vm {
+		os "Ubuntu-Focal-20.04-Daily-2022-04-19"
+		size "small"
+		
+		iface osint_vm_oam {
+			belongs_to subnet_oam_osint
+		}
+		
+		iface osint_vm_net1 {
+			belongs_to subnet_net1_osint
+		}
+		
+		iface osint_vm_net3 {
+			belongs_to subnet_net3_osint
+		}
+
+		credentials ssh_key
+	}
+
+	// Giuseppe - ewcf deve avere reti oam la net1 verso osint e net3 verso network internet
+	vm ewcf_vm {
+		os "Ubuntu-Focal-20.04-Daily-2022-04-19"
+		size "small"
+		
+		iface ewcf_vm_oam {
+			belongs_to subnet_oam_ewcf
+		}
+		
+		iface ewcf_vm_net1 {
+			belongs_to subnet_net1_ewcf
+		}
+		
+		iface ewcf_vm_net3 {
+			belongs_to subnet_net3_ewcf
+		}
+
+		credentials ssh_key
+	}
+
+	// Network region
+	
+	// Internal Network
+	net oam {
+		protocol "TCP/IP"
+		cidr "16.0.0.0/24"
+		
+		subnet subnet_oam_igw {
+			protocol "TCP/IP"
+			cidr "16.0.1.0/26"
+		}
+		
+		subnet subnet_oam_osint {
+			protocol "TCP/IP"
+			cidr "16.0.1.64/26"
+		}
+		
+		subnet subnet_oam_ewcf {
+			protocol "TCP/IP"
+			cidr "16.0.1.128/26"
+		}
+	}
+	
+	// Internal network
+	net net1 {
+		protocol "TCP/IP"
+		cidr "16.0.1.0/24"
+
+		// Subnets definition
+		subnet subnet_net1_igw {
+			connections {
+				subnet_net1_osint
+			}
+			protocol "TCP/IP"
+			cidr "16.0.1.0/25"
+		}
+
+		subnet subnet_net1_osint {
+			connections {
+				subnet_net1_igw
+				subnet_net1_ewcf
+			}
+			protocol "TCP/IP"
+			cidr "16.0.1.64/26"
+		}
+		
+		subnet subnet_net1_ewcf {
+			connections {
+				subnet_net1_osint
+			}
+			protocol "TCP/IP"
+			cidr "16.0.1.128/26"
+		}
+	}
+	
+	// Network connecting igw to 5G
+	net net2 {
+		protocol "TCP/IP"
+		cidr "16.0.2.0/24"
+		
+		subnet subnet_net2_igw {
+			protocol "TCP/IP"
+			cidr "16.0.2.0/25"
+		}
+		
+		gateway net2_igw {
+			// TODO: Define address
+			address "16.0.2.22"
+		}
+		
+	}
+	
+	// Network connecting osint and ewcf to Internet
+	net net3 {
+		protocol "TCP/IP"
+		cidr "16.0.3.0/24"
+		
+		subnet subnet_net3_osint {
+			protocol "TCP/IP"
+			cidr "16.0.3.0/25"
+		}
+		
+		subnet subnet_net3_ewcf {
+			protocol "TCP/IP"
+			cidr "16.0.3.128/25"
+		}
+		
+		gateway net3_igw {
+			// TODO: Define address
+			address "16.0.3.22"
+		}
+	}
+
+	// credentials region
+	key_pair ssh_key {
+		user "ubuntu"
+		keyfile "AAAAB3NzaC1yc2EAAAADAQABAAABAQC63ZvocMhX1LsdUlhzqLNSsh/Wotk/EMfDfa9pBHC52NXv05uENTjd/LBj8PS5JXEr7rKG9Zpj2Kj/PA7Gu0X1BZMwAiNR2dKjw9K0HO6Ozj3elCA7WjjotiQcO+OLWefE1PUW8/BJjtjFD/qf6wJd8CwInH8cjpkccQQfA55IXXegQMm5qv2a/S2XBvMMzv1dzsCy5UPO7tiOz4RBfi56JK8o2mDR327yY7+goA0HQz5tSN1X98+vxLpTPD5qINEFfVk1yNmf/ls3C7EBZQFJ6tsHgl070ymdBLHccmDMEYktzBnc/IhNWMq7K4IxwgFfQ7YSzAAqMr1n04+3oUeB"
+		algorithm "RSA"
+		bits 4096
+	}
+
+	// Security region
+
+	// security group is left as originally defined needs to be updated
+	security_group sg {
+		egress icmp {
+			protocol "ICMP"
+			from_port -1
+			to_port -1
+			cidr ["0.0.0.0/0"]
+		}
+		ingress http {
+			protocol "TCP"
+			from_port 80
+			to_port 80
+			cidr ["0.0.0.0/0"]
+		}
+		ingress https {
+			protocol "TCP"
+			from_port 443
+			to_port 443
+			cidr ["0.0.0.0/0"]
+		}
+		ingress ssh {
+			protocol "TCP"
+			from_port 22
+			to_port 22
+			cidr ["0.0.0.0/0"]
+		}
+
+		ifaces igw_vm_oam, igw_vm_net1, igw_vm_net2, osint_vm_oam, osint_vm_net1, osint_vm_net3, ewcf_vm_oam, ewcf_vm_net1, ewcf_vm_net3
+	}
+}
+
+deployment config1 {
+	osint -> osint_vm,
+	iwg -> igw_vm,
+	ewcf -> ewcf_vm
+}
+
+active deployment config1
+
+concretizations {
+	concrete_infrastructure con_infra {
+
+		provider openstack {
+
+			// Concrete computing nodes region
+
+			vm concrete_osint_vm {
+				maps osint_vm
+			}
+
+			vm concrete_igw_vm {
+				maps igw_vm
+			}
+
+			vm concrete_ewcf_vm {
+				maps ewcf_vm
+			}
+
+			// Concrete Network region
+			net concrete_oam {
+				maps oam
+			}
+			
+			net concrete_net1 {
+				maps net1
+			}
+			
+			net concrete_net2 {
+				maps net2
+			}
+			
+			net concrete_net3 {
+				maps net3
+			}
+				
+		}
+	}
+	active con_infra
+}
+
+// It's currently not possible to provide "storage" for OPEN provider (IOP)
+// req4 "elements" => "VM, storage";
+// Required performance was too much (70%), modified after talking with Eneko
+
+optimization opt {
+	
+	objectives {
+		"cost" => min
+		"performance" => max
+		"availability" => max
+	}
+	nonfunctional_requirements {
+		req1 "Cost <= 300" max 300.0 => "cost";
+		req2 "Performance >= 7%" min 7.0 => "performance";
+		req3 "Provider" values "OPEN" => "provider";
+		req4 "elements" => "VM, VM, VM";
+	}
+	
+}
\ No newline at end of file
diff --git a/tests/domlr/example_multiple_reqs.domlr b/tests/domlr/example_multiple_reqs.domlr
new file mode 100644
index 0000000000000000000000000000000000000000..451857494997fd31bd458e29b6c09d8c19021338
--- /dev/null
+++ b/tests/domlr/example_multiple_reqs.domlr
@@ -0,0 +1,52 @@
+-   "VM must have iface"
+    vm is class infrastructure.VirtualMachine
+    and
+    not exists iface (
+        vm has infrastructure.ComputingNode.ifaces iface
+    )
+
+    error: "VM {vm} must have iface {iface}"
+
+# +   "VM must have iface"
+#     forall vm (
+#         vm is class infrastructure.VirtualMachine
+#         implies
+#         exists iface (
+#             vm has infrastructure.ComputingNode.ifaces iface
+#         )
+#     )
+
+#     error: "VM {vm} must have iface {iface}"
+
++   "VM must have cpu_count >= 4"
+    forall vm (
+        vm is class infrastructure.VirtualMachine
+        implies
+        vm has infrastructure.ComputingNode.cpu_count >= 4
+    )
+
+    error: "VM {vm} must have cpu_count >= 4 {iface}"
+
++   "VM must have os == 'rhel8'"
+    forall vm (
+        vm is class infrastructure.VirtualMachine
+        implies
+        vm has infrastructure.ComputingNode.os == "rhel8"
+    )
+
+    error: "VM {vm} must have os == 'rhel'"
+
+# OLD SYNTAX:
+# -   "Iface must be unique"
+#     ni1 has infrastructure.NetworkInterface.endPoint Value
+#     and
+#     ni1 is not ni2
+#     and
+#     ni2 has infrastructure.NetworkInterface.endPoint Value
+
+-   "Iface must be unique"
+    ni1 has infrastructure.NetworkInterface.endPoint == ni2 infrastructure.NetworkInterface.endPoint
+    and
+    ni1 is not ni2
+
+    error: "Iface {ni1} and {ni2} must have different values"
diff --git a/tests/domlr/example_single_req.domlr b/tests/domlr/example_single_req.domlr
new file mode 100644
index 0000000000000000000000000000000000000000..a3e87f406f7802d20ad1964591d49b2b7cad0210
--- /dev/null
+++ b/tests/domlr/example_single_req.domlr
@@ -0,0 +1,18 @@
+# vm, iface = get_consts(smtsorts, ["vm", "iface"])
+# return And(
+#     smtenc.element_class_fun(vm) == smtenc.classes["infrastructure_VirtualMachine"],
+#     Not(
+#         Exists(
+#             [iface],
+#             ENCODINGS.association_rel(vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], iface)
+#         )
+#     )
+# )
+
+-   "All VMs have at least one interface 1"
+    vm is class infrastructure.VirtualMachine
+    and
+    not exists iface (
+        vm has abstract.ComputingNode.ifaces iface
+    )
+    error: "VM {vm} has no associated interface."
diff --git a/tests/domlr/example_single_req_bad_syntax.domlr b/tests/domlr/example_single_req_bad_syntax.domlr
new file mode 100644
index 0000000000000000000000000000000000000000..195f5b49205d9368e0245a3d17334cda7a765ef9
--- /dev/null
+++ b/tests/domlr/example_single_req_bad_syntax.domlr
@@ -0,0 +1,21 @@
+# vm, iface = get_consts(smtsorts, ["vm", "iface"])
+# return And(
+#     smtenc.element_class_fun(vm) == smtenc.classes["infrastructure_VirtualMachine"],
+#     Not(
+#         Exists(
+#             [iface],
+#             ENCODINGS.association_rel(vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], iface)
+#         )
+#     )
+# )
+
++   "All VMs have at least one interface 1"
+    vm is class infrastructure.VirtualMachine
+    and
+    not exists iface (
+        vm has infrastructure.ComputingNode.ifaces iface
+        and
+        vm has infrastructure.ComputingNode.ifaces X
+    )
+    ---
+    "VM {vm} has no associated interface."
diff --git a/tests/domlr/example_single_req_qty_comparison.domlr b/tests/domlr/example_single_req_qty_comparison.domlr
new file mode 100644
index 0000000000000000000000000000000000000000..9d7029dcc1b145e2d62a8885e81f3fc1aa564de7
--- /dev/null
+++ b/tests/domlr/example_single_req_qty_comparison.domlr
@@ -0,0 +1,35 @@
+# vm, iface = get_consts(smtsorts, ["vm", "iface"])
+# return And(
+#     smtenc.element_class_fun(vm) == smtenc.classes["infrastructure_VirtualMachine"],
+#     Not(
+#         Exists(
+#             [iface],
+#             ENCODINGS.association_rel(vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], iface)
+#         )
+#     )
+# )
+
+# OLD SYNTAX
+# +   "All VMs have at least 512 MB of memory"
+#     forall vm (
+#         vm is class infrastructure.VirtualMachine
+#         implies
+#         (
+#             vm has abstract.ComputingNode.memory_mb Mem
+#             and
+#             Mem < 512
+#         )
+#     )
+    
+#     ---
+#     "All VMs have at least 256 MB of memory"
+
++   "All VMs have at least 512 MB of memory"
+    forall vm (
+        vm is class infrastructure.VirtualMachine
+        implies    
+        vm has abstract.ComputingNode.memory_mb >= 512
+        
+    )
+    
+    error: "All VMs have at least 256 MB of memory"
\ No newline at end of file
diff --git a/tests/domlr/example_single_req_v3.0.domlr b/tests/domlr/example_single_req_v3.0.domlr
new file mode 100644
index 0000000000000000000000000000000000000000..8adb15392a464475797d6f33a5b05781b3c7f044
--- /dev/null
+++ b/tests/domlr/example_single_req_v3.0.domlr
@@ -0,0 +1,18 @@
+# vm, iface = get_consts(smtsorts, ["vm", "iface"])
+# return And(
+#     smtenc.element_class_fun(vm) == smtenc.classes["infrastructure_VirtualMachine"],
+#     Not(
+#         Exists(
+#             [iface],
+#             ENCODINGS.association_rel(vm, smtenc.associations["infrastructure_ComputingNode::ifaces"], iface)
+#         )
+#     )
+# )
+
+-   "All VMs have at least one interface 1"
+    vm is class infrastructure.VirtualMachine
+    and
+    not exists iface (
+        vm has abstract.Node.ifaces iface
+    )
+    error: "VM {vm} has no associated interface."
diff --git a/tests/domlr/example_vm_has_sizedesc_cpu_count.domlr b/tests/domlr/example_vm_has_sizedesc_cpu_count.domlr
new file mode 100644
index 0000000000000000000000000000000000000000..c48e812e1f15ed1a38e473fb56baf6e970b38fab
--- /dev/null
+++ b/tests/domlr/example_vm_has_sizedesc_cpu_count.domlr
@@ -0,0 +1,9 @@
++   "VM has size description and cpu_count >= 4"
+    forall vm (
+        vm is class infrastructure.VirtualMachine
+        implies
+            vm has infrastructure.VirtualMachine.sizeDescription == "EXAMPLE"
+            and
+            vm has infrastructure.ComputingNode.cpu_count >= 4
+    )
+    error: "Model is wrong..."
\ No newline at end of file
diff --git a/tests/test_mc_openapi.py b/tests/test_mc_openapi.py
index 66c7a77e5f86170fd2c4ac1c6cd3321e0dd6d7fb..7fd2ca595b95d1ffd82243a2f879d891eaa7388d 100644
--- a/tests/test_mc_openapi.py
+++ b/tests/test_mc_openapi.py
@@ -1,39 +1,104 @@
 from mc_openapi import __version__
+from mc_openapi.doml_mc.common_reqs import CommonRequirements
+from mc_openapi.doml_mc import DOMLVersion
 import requests
 
+# V2_0 tests
+def test_post_nginx_sat_V2_0():
+    with open("tests/doml/v2.0/nginx-openstack_v2.0.domlx", "r") as f:
+        doml = f.read()
 
-def test_version():
-    assert __version__ == '0.2.0'
+    r = requests.post("http://0.0.0.0:80/modelcheck", data=doml)
+    payload = r.json()
+    assert r.status_code == requests.codes.ok
+    assert payload["result"] is not None
+    assert payload["result"] == "sat"
 
 
-def test_post_nginx_sat():
-    with open("tests/doml/nginx-openstack_v2.domlx", "r") as f:
+def test_post_faas_unsat_V2_0():
+    with open("tests/doml/v2.0/faas.domlx", "r") as f:
         doml = f.read()
 
-    r = requests.post("http://0.0.0.0:8080/modelcheck", data=doml)
+    r = requests.post("http://0.0.0.0:80/modelcheck", data=doml)
     payload = r.json()
     assert r.status_code == requests.codes.ok
     assert payload["result"] is not None
-    assert payload["result"] == "sat"
+    assert payload["result"] == "unsat"
+
 
+def test_post_common_reqs_V2_0():
+    check_strings = [
+        "is not connected to any network interface.",
+        "but they are deployed to nodes that cannot communicate through a common network.",
+        "share the same IP address.",
+        "is not deployed to any abstract infrastructure node.",
+        "is not mapped to any element in the active concretization.",
+        "is not mapped to any abstract infrastructure element."
+    ]
 
-def test_post_nginx_unsat():
-    with open("tests/doml/nginx-openstack_v2_wrong.domlx", "r") as f:
+    for req, err_desc in zip(CommonRequirements[DOMLVersion.V2_0].get_all_requirements(), check_strings):
+        with open(f"tests/doml/v2.0/nginx-openstack_v2.0_wrong_{req.assert_name}.domlx", "r") as f:
+            doml = f.read()
+
+        r = requests.post("http://0.0.0.0:80/modelcheck", data=doml)
+        payload = r.json()
+        assert r.status_code == requests.codes.ok
+        assert payload["result"] is not None
+        assert payload["result"] == "unsat"
+        assert err_desc in payload["description"]
+
+
+# V2_1 tests
+def test_post_nginx_sat_V2_1():
+    with open("tests/doml/v2.1/nginx-aws-ec2.domlx", "r") as f:
         doml = f.read()
 
-    r = requests.post("http://0.0.0.0:8080/modelcheck", data=doml)
+    r = requests.post("http://0.0.0.0:80/modelcheck", data=doml)
+    payload = r.json()
+    assert r.status_code == requests.codes.ok
+    assert payload["result"] is not None
+    assert payload["result"] == "unsat" # it was sat before req change
+
+
+def test_post_faas_unsat_V2_1():
+    with open("tests/doml/v2.1/faas.domlx", "r") as f:
+        doml = f.read()
+
+    r = requests.post("http://0.0.0.0:80/modelcheck", data=doml)
     payload = r.json()
     assert r.status_code == requests.codes.ok
     assert payload["result"] is not None
     assert payload["result"] == "unsat"
 
+# V2_2 tests
+def test_post_nginx_sat_V2_1():
+    with open("tests/doml/v2.2/nginx-aws-ec2.domlx", "r") as f:
+        doml = f.read()
+
+    r = requests.post("http://0.0.0.0:80/modelcheck", data=doml)
+    payload = r.json()
+    assert r.status_code == requests.codes.ok
+    assert payload["result"] is not None
+    assert payload["result"] == "unsat" # it was sat before req change
+
 
-def test_post_faas_sat():
-    with open("tests/doml/faas.domlx", "r") as f:
+def test_post_faas_unsat_V2_2():
+    with open("tests/doml/v2.2/faas.domlx", "r") as f:
         doml = f.read()
 
-    r = requests.post("http://0.0.0.0:8080/modelcheck", data=doml)
+    r = requests.post("http://0.0.0.0:80/modelcheck", data=doml)
     payload = r.json()
     assert r.status_code == requests.codes.ok
     assert payload["result"] is not None
     assert payload["result"] == "unsat"
+
+
+def test_post_nginx_with_func_reqs_unsat_V2_2():
+    with open("tests/doml/v2.2/nginx_func_req.domlx", "r") as f:
+        doml = f.read()
+
+    r = requests.post("http://0.0.0.0:80/modelcheck", data=doml)
+    payload = r.json()
+    assert r.status_code == requests.codes.ok
+    assert payload["result"] is not None
+    assert payload["result"] == "unsat" # it was sat before req change
\ No newline at end of file
diff --git a/tests/test_modelchecker.py b/tests/test_modelchecker.py
new file mode 100644
index 0000000000000000000000000000000000000000..f62315b1d524f54fae13e10a9ba0f03250c505d9
--- /dev/null
+++ b/tests/test_modelchecker.py
@@ -0,0 +1,70 @@
+from importlib.resources import files
+from mc_openapi.doml_mc import init_model, verify_model
+from pathlib import Path
+
+from mc_openapi.doml_mc.intermediate_model.metamodel import DOMLVersion
+
+doml_test_dir = files(package='tests') / 'doml'
+
+def run(src, ver):
+    dmc = init_model(src, ver)
+    return verify_model(dmc)
+
+def test_domlx_models_by_version(subtests):
+    i = 0
+    for doml_ver_dir in [ver for ver in doml_test_dir.iterdir() if ver.name != 'CaseStudies']:
+        doml_ver = doml_ver_dir.name
+        domlx_files = [f for f in doml_ver_dir.iterdir() if f.is_file() and f.name.endswith('.domlx')]
+        for domlx in domlx_files:
+            with open(domlx, "rb") as f:
+                domlx_file = f.read()
+                assert_ver = DOMLVersion.get(doml_ver)
+                assert_result = None
+                try:
+                    assert_result = OUTPUT[doml_ver][domlx.name]
+                    i += 1
+                except:
+                    pass
+                if assert_result:
+                    with subtests.test(msg=f"{doml_ver}/{domlx.name}", i=i):
+                            res = run(domlx_file, assert_ver)
+                            assert assert_result == res['result']
+                            assert assert_ver.name == res['doml_version']
+
+OUTPUT = {
+    'v2.0': {
+        'faas.domlx': 'unsat',
+        'nginx-openstack_v2.0.domlx': 'sat',
+        'nginx-openstack_v2.0_wrong_all_concrete_map_something.domlx': 'unsat',
+        'nginx-openstack_v2.0_wrong_all_infrastructure_elements_deployed.domlx': 'unsat',
+        'nginx-openstack_v2.0_wrong_iface_uniq.domlx': 'unsat',
+        'nginx-openstack_v2.0_wrong_software_package_iface_net.domlx': 'unsat',
+        'nginx-openstack_v2.0_valid_mem_req.domlx': 'sat',
+        'nginx-openstack_v2.0_wrong_nginx_source_code.domlx': 'sat',
+        'openstack_template.domlx': 'unsat',
+        'saas.domlx': 'sat',
+        'saas_https_no_attrs.domlx': 'sat',
+        'saas_no_https_rule.domlx': 'sat',
+        'saas_wrong_no_iface_sg.domlx': 'sat',
+        'nginx-openstack_v2.0_wrong_vm_has_iface.domlx': 'unsat',
+        'nginx-openstack_v2.0_wrong_all_software_components_deployed.domlx': 'unsat'
+    },
+    'v2.1': {
+        'faas.domlx': 'unsat',
+        'nginx-aws-ec2.domlx': 'sat'
+    },
+    'v2.2': {
+        'faas.domlx': 'unsat',
+        'iot_simple_app.domlx': 'unsat',
+        'nginx-aws-ec2.domlx': 'unsat', # was sat before concrete_asg_no_vm req
+        'nginx_func_req2_unsat.domlx': 'unsat',
+        'nginx_func_req2_unsat_neg.domlx': 'unsat',
+        'nginx_func_req_neg.domlx': 'unsat', # ditto
+        'nginx-csp-compatibility-test.domlx': 'unsat', # ditto
+        'nginx_func_req.domlx': 'unsat', # ditto
+        'nginx_flags.domlx': 'unsat' # ditto
+    },
+    'v2.3': {
+
+    },
+}
\ No newline at end of file
diff --git a/uwsgi_config.yaml b/uwsgi_config.yaml
deleted file mode 100644
index 7870e5aba1235d6c08655f8c4230465faa7d1813..0000000000000000000000000000000000000000
--- a/uwsgi_config.yaml
+++ /dev/null
@@ -1,11 +0,0 @@
-uwsgi:
-  strict: true
-  master: true
-  workers: 4
-  http-timeout: 120
-  module: mc_openapi.app_config
-  enable-threads: true
-  threads: 2
-  single-interpreter: true
-  need-app: true
-  thunder-lock: true