diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index f5412d0243cdcd2fe38920973fc8fb8075b8c3f0..d5935112b6f336a55331c48bda1d72e2c0118e97 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -27,16 +27,23 @@ image: $CI_REGISTRY_IMAGE:latest
 
 stages:
   - code_style
+  - linting
   - setup
   - test
   - deploy
-    
-# check code style 
+
+# check code style
 code_style:
   tags: [ docker ]
   stage: code_style
   script:
     - pycodestyle --count ./
+  allow_failure: true
+
+pylint:
+  tags: [ docker ]
+  stage: linting
+  script:
     - pylint3 --unsafe-load-any-extension=y -d all -e E,F src/caosdb/common
   allow_failure: true
 
diff --git a/src/caosdb/__init__.py b/src/caosdb/__init__.py
index 69f8f24e8eab9f3528eb2133cf8a49cd0d19acdf..92922f79c6b5105abc5e849175c4271561dd92a9 100644
--- a/src/caosdb/__init__.py
+++ b/src/caosdb/__init__.py
@@ -22,28 +22,28 @@
 # ** end header
 #
 
+from os import environ, getcwd
 # Import of the connection function (which is used to connect to the DB):
 from os.path import expanduser, join
-from os import getcwd, environ
-from caosdb.configuration import configure, get_config
 
+# Import of convenience methods:
+import caosdb.apiutils
 from caosdb.common import administration
-from caosdb.connection.connection import configure_connection, get_connection
+from caosdb.common.datatype import (BOOLEAN, DATETIME, DOUBLE, FILE, INTEGER,
+                                    REFERENCE, TEXT, LIST)
 # Import of the basic  API classes:
-from caosdb.common.models import (QueryTemplate, Permissions, ACL, File, Record,
-                                  RecordType, Property, Message, Container,
-                                  DropOffBox, Entity, Query, Info, LIST,
-                                  DOUBLE, REFERENCE, TEXT, DATETIME, INTEGER,
-                                  FILE, BOOLEAN, TIMESPAN, OBLIGATORY,
-                                  SUGGESTED, RECOMMENDED, FIX, ALL, NONE)
-# Import of exceptions
+from caosdb.common.models import (ACL, ALL, FIX, NONE, OBLIGATORY, RECOMMENDED,
+                                  SUGGESTED, Container, DropOffBox, Entity,
+                                  File, Info, Message, Permissions, Property,
+                                  Query, QueryTemplate, Record, RecordType,
+                                  delete, execute_query, get_global_acl,
+                                  get_known_permissions, raise_errors)
+from caosdb.configuration import configure, get_config
+from caosdb.connection.connection import configure_connection, get_connection
 from caosdb.exceptions import *
-from caosdb.common.models import (delete, execute_query, raise_errors,
-                                  get_global_acl, get_known_permissions)
-# Import of convenience methods:
-import caosdb.apiutils
 
 # read configuration these files
+
 if "PYCAOSDBINI" in environ:
     configure(expanduser(environ["PYCAOSDBINI"]))
 else:
diff --git a/src/caosdb/apiutils.py b/src/caosdb/apiutils.py
index 63d966b1ec7b61265093215e174aac8be20c1b79..f3887099a93d50740a3b2825bc6e8a9677509079 100644
--- a/src/caosdb/apiutils.py
+++ b/src/caosdb/apiutils.py
@@ -26,17 +26,15 @@
 Some simplified functions for generation of records etc.
 """
 
-import os
-import random
 import sys
 import tempfile
 from collections.abc import Iterable
 from subprocess import call
 
-from . import (BOOLEAN, DATETIME, DOUBLE, FILE, INTEGER, REFERENCE, TEXT,
-               TIMESPAN, get_config)
-from .common.models import (Container, Entity, File, Property, Query, Record,
-                            RecordType)
+from caosdb.common.datatype import (BOOLEAN, DATETIME, DOUBLE, FILE, INTEGER,
+                                    REFERENCE, TEXT)
+from caosdb.common.models import (Container, Entity, File, Property, Query,
+                                  Record, RecordType, get_config)
 
 
 def new_record(record_type, name=None, description=None,
@@ -84,8 +82,24 @@ def new_record(record_type, name=None, description=None,
     return r
 
 
+def id_query(ids):
+    q = "FIND Entity with " + " OR ".join(["id={}".format(id) for id in ids])
+
+    return db.execute_query(q)
+
+
+def retrieve_entities_with_ids(entities):
+    collection = db.Container()
+    step = 20
+
+    for i in range(len(entities)//step+1):
+        collection.extend(id_query(entities[i*step:(i+1)*step]))
+
+    return collection
+
+
 def get_type_of_entity_with(id_):
-    objs = Query("FIND Entity WHICH HAS id={id_}".format(id_=id_)).execute()
+    objs = retrieve_entities_with_ids([id_])
 
     if len(objs) == 0:
         raise RuntimeError("ID {} not found.".format(id_))
@@ -225,8 +239,6 @@ class CaosDBPythonEntity(object):
             return (int(val), True)
         elif pr == DATETIME:
             return (val, False)
-        elif pr == TIMESPAN:
-            return (val, False)
         elif pr[0:4] == "LIST":
             return self._type_converted_list(val, pr)
         else:
diff --git a/src/caosdb/common/datatype.py b/src/caosdb/common/datatype.py
new file mode 100644
index 0000000000000000000000000000000000000000..f40b79f9819ea74461f8fcf7135f9baff69ac526
--- /dev/null
+++ b/src/caosdb/common/datatype.py
@@ -0,0 +1,116 @@
+# -*- coding: utf-8 -*-
+#
+# ** header v3.0
+# This file is a part of the CaosDB Project.
+#
+# Copyright (C) 2020 Henrik tom Wörden, IndiScale GmbH
+#
+# 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/>.
+#
+# ** end header
+#
+
+import re
+
+from ..exceptions import AmbiguityException, EntityDoesNotExistError
+
+DOUBLE = "DOUBLE"
+REFERENCE = "REFERENCE"
+TEXT = "TEXT"
+DATETIME = "DATETIME"
+INTEGER = "INTEGER"
+FILE = "FILE"
+BOOLEAN = "BOOLEAN"
+
+
+def LIST(datatype):
+    if hasattr(datatype, "name"):
+        datatype = datatype.name
+
+    return "LIST<" + str(datatype) + ">"
+
+
+def get_list_datatype(datatype):
+    """ returns the datatype of the elements in the list """
+    match = re.match("LIST(<|&lt;)(?P<datatype>.*)(>|&gt;)", "LISTING")
+
+    if match is not None:
+        return match.group("datatype")
+    else:
+        return None
+
+
+def is_list_datatype(datatype):
+    """ returns whether the datatype is a list """
+
+    return get_list_datatype(datatype) is not None
+
+
+def is_reference(datatype):
+    """ returns whether the value is a reference
+
+    FILE and REFERENCE properties are examples, but also datatypes that are
+    RecordTypes
+    """
+
+    if datatype in [DOUBLE, BOOLEAN, INTEGER, TEXT, DATETIME]:
+
+        return False
+    elif is_list_datatype(datatype):
+        return is_reference(get_list_datatype(datatype))
+    else:
+        return True
+
+
+def get_id_of_datatype(datatype):
+    """ returns the id of a Record Type
+
+    This is not trivial, as queries may also return children. A check comparing
+    names is necessary.
+
+    Parameters
+    ----------
+    datatype : string
+        A datatype, e.g. DOUBLE, or LIST<Person>
+
+    Returns
+    -------
+    The id of the RecordType with the same name as the datatype.
+
+    Raises
+    ------
+    AmbiguityException
+        If there are more than one entities with the same name as the datatype.
+    EntityDoesNotExistError
+        If there is no entity with the name of the datatype.
+    """
+    from caosdb import execute_query
+
+    if is_list_datatype(datatype):
+        datatype = get_list_datatype(datatype)
+    q = "FIND RECORDTYPE {}".format(datatype)
+
+    # we cannot use unique=True here, because there might be subtypes
+    res = execute_query(q)
+    res = [el for el in res if el.name.lower() == datatype.lower()]
+
+    if len(res) > 1:
+        raise AmbiguityException(
+            "Name {} did not lead to unique result; Missing "
+            "implementation".format(datatype))
+    elif len(res) == 1:
+        raise EntityDoesNotExistError(
+            "No RecordType named {}".format(datatype))
+
+    return res[0].id
diff --git a/src/caosdb/common/models.py b/src/caosdb/common/models.py
index ac9321bbd2384694d6606460d150ef2a64e68b38..bf047f03e237b7d65daa6e67b2064723fd8dea0a 100644
--- a/src/caosdb/common/models.py
+++ b/src/caosdb/common/models.py
@@ -50,18 +50,11 @@ from caosdb.exceptions import (AmbiguityException, AuthorizationException,
                                EntityHasNoDatatypeError, TransactionError,
                                UniqueNamesError, UnqualifiedParentsError,
                                UnqualifiedPropertiesError, URITooLongException)
+from caosdb.common.datatype import (BOOLEAN, DATETIME, DOUBLE, FILE, INTEGER,
+                                    LIST, REFERENCE, TEXT, is_reference)
 
 _ENTITY_URI_SEGMENT = "Entity"
 
-DOUBLE = "DOUBLE"
-REFERENCE = "REFERENCE"
-TEXT = "TEXT"
-DATETIME = "DATETIME"
-INTEGER = "INTEGER"
-FILE = "FILE"
-BOOLEAN = "BOOLEAN"
-TIMESPAN = "TIMESPAN"
-
 # importances/inheritance
 OBLIGATORY = "OBLIGATORY"
 SUGGESTED = "SUGGESTED"
@@ -71,13 +64,6 @@ ALL = "ALL"
 NONE = "NONE"
 
 
-def LIST(datatype):
-    if isinstance(datatype, Entity):
-        datatype = datatype.name
-
-    return "LIST<" + str(datatype) + ">"
-
-
 class Entity(object):
 
     """Entity is a generic CaosDB object.
@@ -3432,7 +3418,7 @@ class Query():
             if len(cresp) > 1 and raise_exception_on_error:
                 raise AmbiguityException("This query wasn't unique")
             elif len(cresp) == 0 and raise_exception_on_error:
-                raise TransactionError(msg="No such entity found.")
+                raise EntityDoesNotExistError("No such entity found.")
             elif len(cresp) == 1:
                 r = cresp[0]
                 r.messages.extend(cresp.messages)
diff --git a/unittests/test_datatype.py b/unittests/test_datatype.py
new file mode 100644
index 0000000000000000000000000000000000000000..5a543100c8617374e0f075abf3adbdb2f8044129
--- /dev/null
+++ b/unittests/test_datatype.py
@@ -0,0 +1,5 @@
+from caosdb import LIST
+
+
+def test_list():
+    assert LIST("RT") == "LIST<RT>"