diff --git a/.gitignore b/.gitignore
index b522b1da9176e59756bffe89cd4eafe0d751a23c..55fb3f0d1bc6c101704557da8f35d6e784b5ea89 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,4 +15,5 @@ build/
 src/caosdb/version.py
 
 # documentation
-_apidoc
\ No newline at end of file
+_apidoc
+*~
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f51b1e3bc534ca2d3f3e0804febc7716e43d80b7..e594d9c23d4a5d5791cd437e25fa08f953179e9a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,31 +5,37 @@ All notable changes to this project will be documented in this file.
 The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
-## [0.8.0] - 2022-07-12
-(Timm Fitschen)
+## [0.9.0] - 2022-10-24
+(Florian Spreckelsen)
 
 ### Added ###
 
-### Changed ###
+* Add TimeZone class and parse the server's time zone in the Info response.
 
-### Deprecated ###
+### Fixed ###
+
+* [#141](https://gitlab.indiscale.com/caosdb/src/caosdb-pylib/-/issues/141)
+  `password_method = unauthenticated` not allowed by schema
+* Set PyYAML dependency back to PyYaml>=5.4.1 (from 6.0) for better
+  compatibility with docker-compose
+
+### Documentation ###
+
+* Added curator role permissions example to code gallery
+
+## [0.8.0] - 2022-07-12
+(Timm Fitschen)
 
 ### Removed ###
 
 * Support for Python 3.6 and Python 3.7
 
 ### Fixed ###
-* [#75](https://gitlab.indiscale.com/caosdb/src/caosdb-pylib/-/issues/75), [#103](https://gitlab.indiscale.com/caosdb/src/caosdb-pylib/-/issues/103) Fixed JSON schema to allow more sections, and correct requirements for
-  password method.
-- `read()` of MockupResponse returns now an appropriate type on modern systems
 
+* `read()` of MockupResponse returns now an appropriate type on modern systems
 * [caosdb-server#142](https://gitlab.com/caosdb/caosdb-server/-/issues/142)
   Can't create users with dots in their user names
 
-### Security ###
-
-### Documentation ###
-
 ## [0.7.4] - 2022-05-31
 (Florian Spreckelsen)
 
@@ -210,7 +216,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ### Removed ###
 
-* Dynamic exception type `EntityMultiError`. 
+* Dynamic exception type `EntityMultiError`.
 * `get_something` functions from all error object in `exceptions.py`
 * `AmbiguityException`
 
diff --git a/README.md b/README.md
index 04b34cbc07c98e73740b13200ed83fe067af99d2..602df33cecfc8ec37fd791e3257221e66f120cb3 100644
--- a/README.md
+++ b/README.md
@@ -47,7 +47,7 @@ However, you can also create an issue for it.
 
 * Copyright (C) 2018 Research Group Biomedical Physics, Max Planck Institute
   for Dynamics and Self-Organization Göttingen.
-* Copyright (C) 2020-2021 Indiscale GmbH <info@indiscale.com>
+* Copyright (C) 2020-2022 Indiscale GmbH <info@indiscale.com>
 
 All files in this repository are licensed under a [GNU Affero General Public
 License](LICENCE.md) (version 3 or later).
diff --git a/RELEASE_GUIDELINES.md b/RELEASE_GUIDELINES.md
index b4e38d643756798f0ba8b07d6eceec529cbb3054..863afb8f3ac7d6770c372620523638b900785227 100644
--- a/RELEASE_GUIDELINES.md
+++ b/RELEASE_GUIDELINES.md
@@ -40,6 +40,9 @@ guidelines of the CaosDB Project
 
 11. Merge the main branch back into the dev branch.
 
-12. After the merge of main to dev, start a new development version by
-    setting `ISRELEASED` to `False` and by increasing at least the `MICRO`
-    version in [setup.py](./setup.py) and preparing CHANGELOG.md.
+12. After the merge of main to dev, start a new development version by setting
+    `ISRELEASED` to `False` and by increasing at least the `MICRO` version in
+    [setup.py](./setup.py). Please note that due to a bug in pip, the `PRE`
+    version has to remain empty in the setup.py.  
+    Also update CHANGELOG.md (new "Unreleased" section). Also update
+    `src/doc/conf.py`.
diff --git a/setup.py b/setup.py
index af9e680981ba7a802e22fcde706cb6b73dc7f6dc..9618cd53077e58c35cafb4611b3520b9355eead9 100755
--- a/setup.py
+++ b/setup.py
@@ -47,7 +47,7 @@ from setuptools import find_packages, setup
 
 ISRELEASED = True
 MAJOR = 0
-MINOR = 8
+MINOR = 9
 MICRO = 0
 # Do not tag as pre-release until this commit
 # https://github.com/pypa/packaging/pull/515
@@ -171,7 +171,7 @@ def setup_package():
         python_requires='>=3.8',
         package_dir={'': 'src'},
         install_requires=['lxml>=4.6.3',
-                          'PyYAML>=6.0', 'future', 'PySocks>=1.6.7'],
+                          'PyYAML>=5.4.1', 'future', 'PySocks>=1.6.7'],
         extras_require={'keyring': ['keyring>=13.0.0'],
                         'jsonschema': ['jsonschema>=4.4.0']},
         setup_requires=["pytest-runner>=2.0,<3dev"],
diff --git a/src/caosdb/apiutils.py b/src/caosdb/apiutils.py
index 4c8393111bcbb4f9f91e309b81bebdcac55ba626..bd5b0eeca217e1f77d1bd5d5c60e18f33dd76212 100644
--- a/src/caosdb/apiutils.py
+++ b/src/caosdb/apiutils.py
@@ -338,11 +338,19 @@ def merge_entities(entity_a: Entity, entity_b: Entity):
                 raise NotImplementedError()
 
             for attribute in ("datatype", "unit", "value"):
-                if diff_r1["properties"][key][attribute] is None:
-                    setattr(entity_a.get_property(key), attribute,
-                            diff_r2["properties"][key][attribute])
-                else:
-                    raise RuntimeError("Merge conflict.")
+                if (attribute in diff_r2["properties"][key] and
+                        diff_r2["properties"][key][attribute] is not None):
+                    if (diff_r1["properties"][key][attribute] is None):
+                        setattr(entity_a.get_property(key), attribute,
+                                diff_r2["properties"][key][attribute])
+                    else:
+                        raise RuntimeError(
+                            f"Merge conflict:\nEntity a ({entity_a.id}, {entity_a.name}) "
+                            f"has a Property '{key}' with {attribute}="
+                            f"{diff_r2['properties'][key][attribute]}\n"
+                            f"Entity b ({entity_b.id}, {entity_b.name}) "
+                            f"has a Property '{key}' with {attribute}="
+                            f"{diff_r1['properties'][key][attribute]}")
         else:
             # TODO: This is a temporary FIX for
             #       https://gitlab.indiscale.com/caosdb/src/caosdb-pylib/-/issues/105
diff --git a/src/caosdb/common/models.py b/src/caosdb/common/models.py
index f974060f4727e575a94a3afcdd2f86520e6123a9..7000ede917995c6c01b78a822c2d39ac626fcc23 100644
--- a/src/caosdb/common/models.py
+++ b/src/caosdb/common/models.py
@@ -51,6 +51,7 @@ from caosdb.common.datatype import (BOOLEAN, DATETIME, DOUBLE, INTEGER, TEXT,
                                     is_list_datatype, is_reference)
 from caosdb.common.state import State
 from caosdb.common.utils import uuid, xml2str
+from caosdb.common.timezone import TimeZone
 from caosdb.common.versioning import Version
 from caosdb.configuration import get_config
 from caosdb.connection.connection import get_connection
@@ -4327,6 +4328,8 @@ class Info():
 
             if isinstance(m, UserInfo):
                 self.user_info = m
+            elif isinstance(m, TimeZone):
+                self.time_zone = m
             else:
                 self.messages.append(m)
 
@@ -4460,6 +4463,9 @@ def _parse_single_xml_element(elem):
         return Permissions(xml=elem)
     elif elem.tag == "UserInfo":
         return UserInfo(xml=elem)
+    elif elem.tag == "TimeZone":
+        return TimeZone(zone_id=elem.get("id"), offset=elem.get("offset"),
+                        display_name=elem.text.strip())
     else:
         return Message(type=elem.tag, code=elem.get(
             "code"), description=elem.get("description"), body=elem.text)
diff --git a/src/caosdb/common/timezone.py b/src/caosdb/common/timezone.py
new file mode 100644
index 0000000000000000000000000000000000000000..2bd3d3d4d739118e160f7b3a35757fbb0afe70cb
--- /dev/null
+++ b/src/caosdb/common/timezone.py
@@ -0,0 +1,18 @@
+class TimeZone():
+    """
+    TimeZone, e.g. CEST, Europe/Berlin, UTC+4.
+
+
+    Attributes
+    ----------
+    zone_id : string
+        ID of the time zone.
+    offset : int
+        Offset to UTC in seconds.
+    display_name : string
+        A human-friendly name of the time zone:
+    """
+    def __init__(self, zone_id, offset, display_name):
+        self.zone_id = zone_id
+        self.offset = offset
+        self.display_name = display_name
diff --git a/src/caosdb/schema-pycaosdb-ini.yml b/src/caosdb/schema-pycaosdb-ini.yml
index 5dabdd89795e19a757209e03cc843776be705777..a81bf006523ab7690ee0bf9d27e0a2d57ce8c3c3 100644
--- a/src/caosdb/schema-pycaosdb-ini.yml
+++ b/src/caosdb/schema-pycaosdb-ini.yml
@@ -26,7 +26,7 @@ schema-pycaosdb-ini:
           description: The password input method defines how the password is supplied that is used for authentication with the server.
           type: string
           default: input
-          enum: [input, plain, pass, keyring]
+          enum: [input, unauthenticated, plain, pass, keyring]
         password_identifier:
           type: string
         password:
diff --git a/src/caosdb/utils/register_tests.py b/src/caosdb/utils/register_tests.py
new file mode 100644
index 0000000000000000000000000000000000000000..9d0afcbb0845e1d8d31622e8ab9926f26f7e78f6
--- /dev/null
+++ b/src/caosdb/utils/register_tests.py
@@ -0,0 +1,136 @@
+#!/usr/bin/env python
+# encoding: utf-8
+#
+# This file is a part of the CaosDB Project.
+#
+# Copyright (C) 2022 Alexander Schlemmer <alexander.schlemmer@ds.mpg.de>
+# Copyright (C) 2022 Timm Fitschen <t.fitschen@indiscale.com>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+import caosdb as db
+from caosdb import administration as admin
+
+"""
+This module implements a registration procedure for integration tests which
+need a running CaosDB instance.
+
+It ensures that tests do not accidentally overwrite data in real CaosDB
+instances, as it checks whether the running CaosDB instance is actually the
+correct one, that
+should be used for these tests.
+
+The test files have to define a global variable TEST_KEY which must be unique
+for each test using
+
+set_test_key("ABCDE")
+
+The test procedure (invoked by pytest) checks whether a registration
+information is stored in one of the server properties or otherwise
+- offers to register this test in the currently running database ONLY if this
+  is empty.
+- fails otherwise with a RuntimeError
+
+NOTE: you probably need to use pytest with the -s option to be able to
+      register the test interactively. Otherwise, the server property has to be
+      set before server start-up in the server.conf of the CaosDB server.
+
+This module is intended to be used with pytest.
+
+There is a pytest fixture "clear_database" that performs the above mentioned
+checks and clears the database in case of success.
+"""
+
+TEST_KEY = None
+
+
+def set_test_key(KEY):
+    global TEST_KEY
+    TEST_KEY = KEY
+
+
+def _register_test():
+    res = db.execute_query("COUNT Entity")
+    if not isinstance(res, int):
+        raise RuntimeError("Response from server for Info could not be interpreted.")
+    if res > 0:
+        raise RuntimeError("This instance of CaosDB contains entities already."
+                           "It must be empty in order to register a new test.")
+
+    print("Current host of CaosDB instance is: {}".format(
+        db.connection.connection.get_connection()._delegate_connection.setup_fields["host"]))
+    answer = input("This method will register your current test with key {} with the currently"
+                   " running instance of CaosDB. Do you want to continue (y/N)?".format(
+                       TEST_KEY))
+    if answer != "y":
+        raise RuntimeError("Test registration aborted by user.")
+
+    admin.set_server_property("_CAOSDB_INTEGRATION_TEST_SUITE_KEY",
+                              TEST_KEY)
+
+
+def _get_registered_test_key():
+    try:
+        return admin.get_server_property("_CAOSDB_INTEGRATION_TEST_SUITE_KEY")
+    except KeyError:
+        return None
+
+
+def _is_registered():
+    registered_test_key = _get_registered_test_key()
+    if not registered_test_key:
+        return False
+    elif registered_test_key == TEST_KEY:
+        return True
+    else:
+        raise RuntimeError("The database has been setup for a different test.")
+
+
+def _assure_test_is_registered():
+    global TEST_KEY
+    if TEST_KEY is None:
+        raise RuntimeError("TEST_KEY is not defined.")
+    if not _is_registered():
+        answer = input("Do you want to register this instance of CaosDB"
+                       " with the current test? Do you want to continue (y/N)?")
+        if answer == "y":
+            _register_test()
+            raise RuntimeError("Test has been registered. Please rerun tests.")
+        else:
+            raise RuntimeError("The database has not been setup for this test.")
+
+
+def _clear_database():
+    c = db.execute_query("FIND ENTITY WITH ID>99")
+    c.delete(raise_exception_on_error=False)
+    return None
+
+
+try:
+    import pytest
+
+    @pytest.fixture
+    def clear_database():
+        """Remove Records, RecordTypes, Properties, and Files ONLY IF the CaosDB
+        server the current connection points to was registered with the appropriate key.
+
+        PyTestInfo Records and the corresponding RecordType and Property are preserved.
+        """
+        _assure_test_is_registered()
+        yield _clear_database()  # called before the test function
+        _clear_database()  # called after the test function
+except ImportError:
+    raise Warning("""The register_tests module depends on pytest and is
+                  intended to be used in integration test suites for the
+                  caosdb-pylib library only.""")
diff --git a/src/doc/administration.rst b/src/doc/administration.rst
index 061acc8364d2ef62f743a20d7b9e6562baac0fc5..eab02e43a833559dc21ea7a9fa5edfaf6431facf 100644
--- a/src/doc/administration.rst
+++ b/src/doc/administration.rst
@@ -5,10 +5,12 @@ The Python script ``caosdb_admin.py`` should be used for administrative tasks.
 Call ``caosdb_admin.py --help`` to see how to use it.
 
 The most common task is to create a new user (in the CaosDB realm) and set a 
-password for the user (note that a user typically needs to be activated)::
+password for the user (note that a user typically needs to be activated):
 
-     caosdb_admin.py create_user anna
-     caosdb_admin.py set_user_password anna
-     caosdb_admin.py add_user_roles anna administration
-     caosdb_admin.py activate_user anna
+.. code:: console
+
+   $ caosdb_admin.py create_user anna
+   $ caosdb_admin.py set_user_password anna
+   $ caosdb_admin.py add_user_roles anna administration
+   $ caosdb_admin.py activate_user anna
 
diff --git a/src/doc/conf.py b/src/doc/conf.py
index 77531343d49a9bfa9b1d30d7681f040509d0c336..7f5f70a82fc2782cba18891bcb23598a93033b59 100644
--- a/src/doc/conf.py
+++ b/src/doc/conf.py
@@ -29,10 +29,10 @@ copyright = '2022, IndiScale GmbH'
 author = 'Daniel Hornung'
 
 # The short X.Y version
-version = '0.8.0'
+version = '0.9.0'
 # The full version, including alpha/beta/rc tags
 # release = '0.5.2-rc2'
-release = '0.8.0'
+release = '0.9.0'
 
 
 # -- General configuration ---------------------------------------------------
diff --git a/src/doc/gallery/curator-permissions.rst b/src/doc/gallery/curator-permissions.rst
new file mode 100644
index 0000000000000000000000000000000000000000..fa6b4022b7fbc1d042ed00f265e63a2675794a21
--- /dev/null
+++ b/src/doc/gallery/curator-permissions.rst
@@ -0,0 +1,123 @@
+
+Setting permissions for a curator role
+======================================
+
+The following example shows how to create and set permissions for a ``curator``
+role that is allowed to insert, update, or delete any entity apart from a set of
+RecordTypes and properties that define a "core data model" which can only be
+altered with administration permissions.
+
+In the following, you'll learn how to
+
+1. create the ``curator`` role.
+2. configure the ``global_entity_permissions.xml`` s.th. the ``curator`` role is
+   allowed to insert, update, or delete any entity by default.
+3. use a Python script to override the above configuration for the entities in
+   the externally defined core data model.
+
+Prerequisites
+-------------
+
+This example needs some preparations regarding your CaosDB setup that have to
+(or, for the sake of simplicity, should) be done outside the actual Python
+example script.
+
+The curator role
+~~~~~~~~~~~~~~~~
+
+First, a ``curator`` role is created with a meaningful description. We'll use
+``caosdb_admin.py`` for this which leads to the following command:
+
+.. code:: console
+
+   $ caosdb_admin.py create_role "curator" "A user who is permitted to create new Records, Properties, and RecordTypes but who is not allowed to change the core data model."
+
+To actually see how this role's permissions change, we also need a user with
+this role. Assume you already have created and activated (see
+:doc:`Administration <../administration>`) a ``test_curator`` user, then
+``caosdb_admin.py`` is used again to assign it the correct role:
+
+.. code:: console
+
+   $ caosdb_admin.py add_user_roles test_curator curator
+
+.. note::
+
+   The ``test_curator`` user shouldn't have administration privileges, otherwise
+   the below changes won't have any effect.
+
+The core data model and caosdb-advanced-user-tools
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In principle, the following script works with any data model defined in a json
+or yaml file (just adapt lines 39-42 accordingly). In this example, we'll use the
+`metadata schema <https://github.com/leibniz-zmt/zmt-metadata-schema>`_ that was
+developed by J. Schmidt at the `Leibniz Centre for Tropical Marine Research
+<https://www.leibniz-zmt.de/en/>`_.
+
+Clone the schemata into the same directory containing the below script via
+
+.. code:: console
+
+   $ git clone https://github.com/leibniz-zmt/zmt-metadata-schema.git
+
+Furthermore, we'll need the `CaosDB Advanced User Tools
+<https://gitlab.com/caosdb/caosdb-advanced-user-tools>`_ for loading the
+metadata schemata from the json files, so install them via
+
+.. code:: console
+
+   $ pip install caosadvancedtools
+
+The global entity permissions file
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Users with the ``curator`` role should be able to have any permission for all
+entities by default. The exceptions for the core data model entities will be set
+with the script below. These default settings are best done via the
+``global_entities_permissions.xml`` config file (see the `server documentation
+<https://docs.indiscale.com/caosdb-server/permissions.html#how-to-set-permissions>`_). Simply
+add the following line to the file
+
+.. code:: xml
+
+   <Grant priority="true" role="curator"><Permission name="*"/></Grant>
+
+This means that, by default, all users with the ``curator`` role are **granted**
+all entity permissions (including insert, update, and delete as specified in the
+beginning) **with priority**. This ensures, that no normal user is allowed to
+overrule these permissions (since it is granted with priority), but it can still
+be denied for the core data model entities by a **deny** rule with priority. See
+the server documentation on `permission
+calculation <https://docs.indiscale.com/caosdb-server/permissions.html#permission-calculation>`_
+for more information on which permission rules can or can't be overruled.
+
+Your complete ``global_entities_permissions.xml`` might then look like
+
+.. code:: xml
+
+   <globalPermissions>
+       <Grant priority="false" role="?OWNER?"><Permission name="*"/></Grant>
+       <Grant priority="false" role="?OTHER?"><Permission name="RETRIEVE:*"/></Grant>
+       <Grant priority="false" role="?OTHER?"><Permission name="USE:*"/></Grant>
+       <Grant priority="false" role="anonymous"><Permission name="RETRIEVE:*"/></Grant>
+       <Grant priority="true" role="curator"><Permission name="*"/></Grant>
+       <Deny priority="false" role="?OTHER?"><Permission name="UPDATE:*"/></Deny>
+       <Deny priority="false" role="?OTHER?"><Permission name="DELETE"/></Deny>
+       <Deny priority="true" role="?OTHER?"><Permission name="EDIT:ACL"/></Deny>
+   </globalPermissions>
+
+.. note::
+
+   Note that you have to restart your CaosDB server after modifying the
+   ``global_entities_permissions.xml``.
+
+The code
+--------
+
+After having applied all of the above prerequisites and restarting your CaosDB
+server, execute the following code.
+
+:download:`Download full code<curator_permissions.py>`
+
+.. literalinclude:: curator_permissions.py
diff --git a/src/doc/gallery/curator_permissions.py b/src/doc/gallery/curator_permissions.py
new file mode 100644
index 0000000000000000000000000000000000000000..16b4b7f6f1bb9abfb7e191c6a1101181984bce9a
--- /dev/null
+++ b/src/doc/gallery/curator_permissions.py
@@ -0,0 +1,100 @@
+#!/usr/bin/env python3
+# encoding: utf-8
+#
+# This file is a part of the CaosDB Project.
+#
+# Copyright (C) 2022 Indiscale GmbH <info@indiscale.com>
+# Copyright (C) 2022 Florian Spreckelsen <f.spreckelsen@indiscale.com>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+#
+
+import os
+import sys
+
+import caosdb as db
+from caosadvancedtools.models.parser import parse_model_from_json_schema
+from caosdb import administration as admin
+
+CURATOR = "curator"
+
+
+def main():
+    """Set curator role permissions: Is allowed to edit all Records; is allowed
+    to create new RTs and Properties and change them, but is not allowed to
+    change anything defined in the core data model, i.e., in the schemas.
+
+    """
+    dataspace_definitions = parse_model_from_json_schema(
+        "zmt-metadata-schema/schemas/dataspace.schema.json")
+    dataset_definitions = parse_model_from_json_schema(
+        "zmt-metadata-schema/schemas/dataset.schema.json")
+
+    # Set general permissions. The curator users should be allowed to perform
+    # any transaction.
+    perms = admin._get_permissions(CURATOR)
+    general_grant_perms = [
+        "TRANSACTION:*"
+    ]
+
+    for p in general_grant_perms:
+
+        g = admin.PermissionRule(action="Grant", permission=p, priority=True)
+        d = admin.PermissionRule(action="Deny", permission=p, priority=True)
+
+        if g in perms:
+            perms.remove(g)
+        if d in perms:
+            perms.remove(d)
+        perms.add(g)
+
+    admin._set_permissions(CURATOR, permission_rules=perms)
+
+    # Deny all permissions that could change the data model ...
+    core_model_deny_permissions = [
+        "DELETE",
+        "UPDATE:*",
+        "EDIT:ACL"
+    ]
+    # ... but allow read-access and of course using the entities as parents,
+    # properties, ...
+    core_model_grant_permissions = [
+        "RETRIEVE:*",
+        "USE:*",
+    ]
+
+    # Iterate over all entities defined in the schemas and update their access control list (ACL) accordingly.
+    updates = db.Container()
+    for model in [dataspace_definitions, dataset_definitions]:
+
+        for ent in model.values():
+            if ent.name in [u.name for u in updates]:
+                # Skip entities that have been updated already
+                continue
+            # The entity needs to be retrieved with the ACL flag to update the
+            # ACL down the road
+            ent.retrieve(flags={"ACL": None})
+            for d in core_model_deny_permissions:
+                ent.deny(role=CURATOR, priority=True, permission=d)
+            ent.update_acl()
+            ent.retrieve(flags={"ACL": None})
+            for g in core_model_grant_permissions:
+                ent.grant(role=CURATOR, priority=True, permission=g)
+            updates.append(ent)
+            ent.update_acl()
+
+
+if __name__ == "__main__":
+
+    sys.exit(main())
diff --git a/src/doc/gallery/index.rst b/src/doc/gallery/index.rst
index a6ef53e4c7d1272c5dbc8c62b4d90a89591cac0f..bfba4317c3556d0692eb402f42ba3699be586d5a 100644
--- a/src/doc/gallery/index.rst
+++ b/src/doc/gallery/index.rst
@@ -14,3 +14,4 @@ This chapter collects code examples which can be immediately run against an empt
    :caption: The code examples:
 
    simulation
+   curator-permissions
diff --git a/src/doc/tutorials/first_steps.rst b/src/doc/tutorials/first_steps.rst
index 34b96bbeca416107fb34feb4707b9ef46fc49fe7..486cd4d437c8b13a253cadc8ed45f49b4a7634e4 100644
--- a/src/doc/tutorials/first_steps.rst
+++ b/src/doc/tutorials/first_steps.rst
@@ -87,7 +87,7 @@ Ids can also come in handy when searching. Suppose you have some complicated con
 
 
 >>> # This condition is not that complicated and long but let's suppose it was.
->>> record = db.execute_query("FIND Analysis with quality_factor=0.08", unique=True)
+>>> record = db.execute_query("FIND MusicalAnalysis with quality_factor=0.08", unique=True)
 >>> # You can use unique=True when you only expect one result Entity. An error will be
 >>> # thrown if the number of results is unequal to 1 and the resulting object will be
 >>> # an Entity and not a Container
diff --git a/unittests/docker/Dockerfile b/unittests/docker/Dockerfile
index 7fa3f75bd198724628dee48ab328829fa071a639..06f9d6c830068a2c1c85caef79c64f899eaefb33 100644
--- a/unittests/docker/Dockerfile
+++ b/unittests/docker/Dockerfile
@@ -1,4 +1,8 @@
 FROM debian:latest
+# Use local package repository
+COPY sources.list.local /etc/apt/
+RUN mv /etc/apt/sources.list /etc/apt/sources.list.orig
+RUN cat /etc/apt/sources.list.local /etc/apt/sources.list.orig > /etc/apt/sources.list
 RUN apt-get update && \
     apt-get install -y \
       pylint3 python3-pip tox git \
diff --git a/unittests/docker/sources.list.local b/unittests/docker/sources.list.local
new file mode 100644
index 0000000000000000000000000000000000000000..c0b4107350ba37e77aa95d5a56c31976979e51e1
--- /dev/null
+++ b/unittests/docker/sources.list.local
@@ -0,0 +1,6 @@
+# Local repositories at Netcup
+deb http://debian.netcup.net/debian/ buster main
+deb http://mirrors.n-ix.net/debian-security buster/updates main
+deb http://debian.netcup.net/debian/ buster-updates main
+
+# The original content follows here:
\ No newline at end of file
diff --git a/unittests/test_apiutils.py b/unittests/test_apiutils.py
index 43ab8107183f16bf8df1d0ea8e447b378bcf8123..2ebdf95a3aa5ce76b983b2c3c47630e1a8884705 100644
--- a/unittests/test_apiutils.py
+++ b/unittests/test_apiutils.py
@@ -296,6 +296,19 @@ def test_merge_entities():
     assert r2.get_property("F").value == "text"
 
 
+def test_merge_bug_conflict():
+    r = db.Record()
+    r.add_property(name="C", value=4)
+    r2 = db.Record()
+    r2.add_property(name="C", value=4, datatype="TEXT")
+    merge_entities(r, r2)
+
+    r3 = db.Record()
+    r3.add_property(name="C", value=4, datatype="INTEGER")
+    with pytest.raises(RuntimeError) as excinfo:
+        merge_entities(r3, r2)
+
+
 def test_merge_bug_109():
     rt = db.RecordType(name="TestBug")
     p = db.Property(name="test_bug_property", datatype=db.LIST(db.INTEGER))
diff --git a/unittests/test_configs/pycaosdb6.ini b/unittests/test_configs/pycaosdb6.ini
new file mode 100644
index 0000000000000000000000000000000000000000..3826564f043c5702385a3d093cb4ebb8d4c24cd2
--- /dev/null
+++ b/unittests/test_configs/pycaosdb6.ini
@@ -0,0 +1,4 @@
+[Connection]
+url=https://localhost:10443/
+# No username, unauthenticated connection
+password_method = unauthenticated