diff --git a/src/linkahead/apiutils.py b/src/linkahead/apiutils.py
index e4608622f44178e3f13645ca5150cb6e15d04fab..d61daeecb3d1ac2305090e7b7210d9c2c40bd33f 100644
--- a/src/linkahead/apiutils.py
+++ b/src/linkahead/apiutils.py
@@ -264,12 +264,12 @@ def compare_entities(entity0: Optional[Entity] = None,
     if old_entity is not None:
         warnings.warn("Please use 'entity0' instead of 'old_entity'.", DeprecationWarning)
         if entity0 is not None:
-            raise ValueError("You cannot use both, entity0 and old_entity")
+            raise ValueError("You cannot use both entity0 and old_entity")
         entity0 = old_entity
     if new_entity is not None:
         warnings.warn("Please use 'entity1' instead of 'new_entity'.", DeprecationWarning)
         if entity1 is not None:
-            raise ValueError("You cannot use both, entity1 and new_entity")
+            raise ValueError("You cannot use both entity1 and new_entity")
         entity1 = new_entity
 
     diff: tuple = ({"properties": {}, "parents": []},
@@ -371,7 +371,7 @@ def compare_entities(entity0: Optional[Entity] = None,
 
     # compare properties
     for prop in entity0.properties:
-        matching = entity1.properties.filter(name=prop.name, pid=prop.id, check_wrapped=False)
+        matching = entity1.properties.filter(name=prop.name, pid=prop.id)
         if len(matching) == 0:
             # entity1 has prop, entity0 does not
             diff[0]["properties"][prop.name] = {}
diff --git a/src/linkahead/common/models.py b/src/linkahead/common/models.py
index 347d413808d680fc17a0fd2ccdb5c22ae39b1701..1dbeb802311c7afaea2340af15e49537520ef57f 100644
--- a/src/linkahead/common/models.py
+++ b/src/linkahead/common/models.py
@@ -2503,38 +2503,31 @@ class PropertyList(list):
 
         return xml2str(xml)
 
-    def filter(self, prop: Optional[Property] = None, pid: Union[None, str, int] = None,
-               name: Optional[str] = None, check_wrapped: bool = True) -> list:
+    def filter(self, prop: Optional[Property] = None,
+               pid: Union[None, str, int] = None,
+               name: Optional[str] = None,
+               conjunction: bool = False) -> list:
         """
         Return all Properties from the given PropertyList that match the
         selection criteria.
 
-        You can provide name or ID and all matching elements will be returned.
-        If both name and ID are given, elements matching either criterion will
-        be returned.
-
-        If a Property is given, neither name nor ID may be set. In this case,
-        only elements matching both name and ID of the Property are returned.
-
-        Also checks the original Properties wrapped within the elements of
-        PropertyList and will return the original Property if both wrapper and
-        original match.
+        Please refer to the documentation of _filter_entity_list for a detailed
+        description of behaviour.
 
         Params
         ------
         listobject        : Iterable(Property)
                             List to be filtered
         prop              : Property
-                            Property to match name and ID with. Cannot be
-                            set simultaneously with ID or name.
+                            Property to match name and ID with. Cannot be set
+                            simultaneously with ID or name.
         pid               : str, int
                             Property ID to match
         name              : str
                             Property name to match
-        check_wrapped     : bool, default: True
-                            If set to False, only the wrapper elements
-                            contained in the given PropertyList will be
-                            checked, not the original Properties they wrap.
+        conjunction       : bool, defaults to False
+                            Set to return only entities that match both id and name
+                            if both are given.
 
         Returns
         -------
@@ -2542,7 +2535,7 @@ class PropertyList(list):
                            List containing all matching Properties
         """
         return _filter_entity_list(self, pid=pid, name=name, entity=prop,
-                                   check_wrapped=check_wrapped)
+                                   conjunction=conjunction)
 
     def _get_entity_by_cuid(self, cuid: str):
         '''
@@ -2674,22 +2667,16 @@ class ParentList(list):
 
         return xml2str(xml)
 
-    def filter(self, parent: Optional[Parent] = None, pid: Union[None, str, int] = None,
-               name: Optional[str] = None, check_wrapped: bool = True) -> list:
+    def filter(self, parent: Optional[Parent] = None,
+               pid: Union[None, str, int] = None,
+               name: Optional[str] = None,
+               conjunction: bool = False) -> list:
         """
         Return all Parents from the given ParentList that match the selection
         criteria.
 
-        You can provide name or ID and all matching elements will be returned.
-        If both name and ID are given, elements matching either criterion will
-        be returned.
-
-        If a Parent is given, neither name nor ID may be set. In this case,
-        only elements matching both name and ID of the Parent are returned.
-
-        Also checks the original Parents wrapped within the elements of
-        ParentList, will return the original Parent if both wrapper and
-        original match.
+        Please refer to the documentation of _filter_entity_list for a detailed
+        description of behaviour.
 
         Params
         ------
@@ -2702,10 +2689,9 @@ class ParentList(list):
         name              : str
                             Parent name to match
                             simultaneously with ID or name.
-        check_wrapped     : bool, default: True
-                            If set to False, only the wrapper elements
-                            contained in the given ParentList will be
-                            checked, not the original Parents they wrap.
+        conjunction       : bool, defaults to False
+                            Set to return only entities that match both id and name
+                            if both are given.
 
         Returns
         -------
@@ -2713,7 +2699,7 @@ class ParentList(list):
                            List containing all matching Parents
         """
         return _filter_entity_list(self, pid=pid, name=name, entity=parent,
-                                   check_wrapped=check_wrapped)
+                                   conjunction=conjunction)
 
     def remove(self, parent: Union[Entity, int, str]):
         """
@@ -5479,25 +5465,33 @@ def delete(ids: Union[list[int], range], raise_exception_on_error: bool = True):
     return c.delete(raise_exception_on_error=raise_exception_on_error)
 
 
-def _filter_entity_list(listobject: list[Entity], entity: Optional[Entity] = None, pid: Union[None, str, int] = None,
-                        name: Optional[str] = None, conjunction: bool = False) -> list:
+def _filter_entity_list(listobject: list[Entity],
+                        entity: Optional[Entity] = None,
+                        pid: Union[None, str, int] = None,
+                        name: Optional[str] = None,
+                        conjunction: bool = False) -> list:
     """
-    Returns a subset of the entities in the list based on whether their ID and name matches the
-    selection criterion.
+    Returns a subset of entities from the list based on whether their id and
+    name matches the selection criterion.
 
-    If an entity in the list has
-    - ID and name are None: will never be returned
-    - ID is not None and name is None: will be returned if the ID matches a given not-None value
-    - ID is None and name is not None: will be returned if the name matches a given not-None value
-    - ID and name are not None: will be returned if the ID matches a given not-None value, if no ID
-      was given, the entity will be returned if the name matches.
+    If both pid and name are given, entities from the list are first matched
+    based on id. If they do not have an id, they are matched based on name.
+    If only one parameter is given, only this parameter is considered.
 
-    As IDs can be strings, integer IDs will be casted to string for the comparison.
+    If an Entity is given, neither name nor ID may be set. In this case, pid
+    and name are determined by the attributes of given entity.
 
-    If an Entity is given, neither name nor ID may be set. In this case, ID and name are taken from
-    the given entity, but the behavior is the same.
+    This results in the following selection criteria:
+    If an entity in the list
+    - has both name and id, it is returned if the id matches the given not-None
+      value for pid. If no pid was given, it is returned if the name matches.
+    - has an id, but no name, it will be returned only if it matches the given
+      not-None value
+    - has no id, but a name, it will be returned if the name matches the given
+      not-None value
+    - has neither id nor name, it will never be returned
 
-    TODO explain conjunction -> Not implementd
+    As IDs can be strings, integer IDs are cast to string for the comparison.
 
     Params
     ------
@@ -5510,20 +5504,28 @@ def _filter_entity_list(listobject: list[Entity], entity: Optional[Entity] = Non
                         Entity ID to match
     name              : str
                         Entity name to match
+    conjunction       : bool, defaults to False
+                        Set to true to return only entities that match both id
+                        and name if both are given.
 
     Returns
     -------
     matches          : list
                        A List containing all matching Entities
     """
-    if conjunction:
-        raise NotImplementedError("conjunction is not yet implemented")
     # Check correct input params and setup
     if entity is not None:
         if pid is not None or name is not None:
-            raise ValueError("Please provide either Entity, pid or name.")
+            raise ValueError("If an entity is given, pid and name must not be set.")
         pid = entity.id
         name = entity.name
+    if pid is None and name is None:
+        if entity is None:
+            raise ValueError("One of entity, pid or name must be set.")
+        else:
+            raise ValueError("A given entity must have at least one of name and id.")
+    if pid is None or name is None:
+        conjunction = False
 
     # Iterate through list and match based on given criteria
     matches = []
@@ -5531,23 +5533,21 @@ def _filter_entity_list(listobject: list[Entity], entity: Optional[Entity] = Non
         name_match, pid_match = False, False
 
         # Check whether name/pid match
-        # pid and candidate.id might be int and str, so cast to str (None safe)
-        if pid is not None and str(candidate.id) == str(pid):
-            pid_match = True
-        elif match_entity and pid is None:
-            # Without a pid we cannot match
+        # Comparison is only possible if both are not None
+        pid_none = pid is None or candidate.id is None
+        # Cast to string in case one is f.e. "12" and the other is 12
+        if not pid_none and str(candidate.id) == str(pid):
             pid_match = True
-        if (name is not None and candidate.name is not None
-                and candidate.name.lower() == name.lower()):
-            name_match = True
-        elif match_entity and name is None:
-            # Without a name we cannot match
+        name_none = name is None or candidate.name is None
+        if not name_none and str(candidate.name).lower() == str(name).lower():
             name_match = True
 
-        # If the criteria are satisfied, append the match. Otherwise, check
-        # the wrapper if applicable
-        if name_match and pid_match:
-            matches.append(candidate)
-        elif not match_entity and (name_match or pid_match):
+        # If the criteria are satisfied, append the match.
+        if pid_match and name_match:
             matches.append(candidate)
+        elif not conjunction:
+            if pid_match:
+                matches.append(candidate)
+            if pid_none and name_match:
+                matches.append(candidate)
     return matches
diff --git a/unittests/test_apiutils.py b/unittests/test_apiutils.py
index 4d59950733ca7070d2a9c5cb4973ef8a167d49ea..35f80e5e3dbe355b9bc32330587f6aa7bc2b0d63 100644
--- a/unittests/test_apiutils.py
+++ b/unittests/test_apiutils.py
@@ -261,16 +261,16 @@ def test_compare_entities_units():
 
 
 def test_compare_entities_battery():
-    par1, par2, par3 = db.Record(), db.Record(), db.RecordType()
+    par1, par3 = db.Record(name=""), db.RecordType(name="")
     r1, r2, r3 = db.Record(), db.Record(), db.Record()
     prop2 = db.Property(name="Property 2")
-    prop3 = db.Property()
+    prop3 = db.Property(name="")
 
     # Basic tests for Properties
     prop_settings = {"datatype": db.REFERENCE, "description": "desc of prop",
                      "value": db.Record().add_parent(par3), "unit": '°'}
-    t1 = db.Record().add_parent(db.RecordType())
-    t2 = db.Record().add_parent(db.RecordType())
+    t1 = db.Record().add_parent(db.RecordType(id=1))
+    t2 = db.Record().add_parent(db.RecordType(id=1))
     # Change datatype
     t1.add_property(db.Property(name="datatype", **prop_settings))
     prop_settings["datatype"] = par3
@@ -335,10 +335,10 @@ def test_compare_entities_battery():
 
     # Basic tests for special attributes
     prop_settings = {"id": 42, "name": "Property",
-                     "datatype": db.LIST(db.REFERENCE), "value": [db.Record()],
+                     "datatype": db.LIST(db.REFERENCE), "value": [db.Record(name="")],
                      "unit": '€', "description": "desc of prop"}
     alt_settings = {"id": 64, "name": "Property 2",
-                    "datatype": db.LIST(db.TEXT), "value": [db.RecordType()],
+                    "datatype": db.LIST(db.TEXT), "value": [db.RecordType(name="")],
                     "unit": '€€', "description": " ę Ě ப ཾ ཿ ∛ ∜ ㅿ ㆀ 값 "}
     t5 = db.Property(**prop_settings)
     t6 = db.Property(**prop_settings)
diff --git a/unittests/test_entity.py b/unittests/test_entity.py
index 5c6752c3e5ca52cf616606ea3f235e009542600b..3fb014f864b5e79844be7165e3b0093bca731451 100644
--- a/unittests/test_entity.py
+++ b/unittests/test_entity.py
@@ -164,14 +164,13 @@ def test_property_list():
 def test_filter():
     rt1 = RecordType(id=100)
     rt2 = RecordType(id=101, name="RT")
-    rt3 = RecordType()
-    # TODO add name only
+    rt3 = RecordType(name="")
     p1 = Property(id=100)
-    p2 = Property(id=100)  # TODO remove
+    p2 = Property(id=100)
     p3 = Property(id=101, name="RT")
     p4 = Property(id=102, name="P")
     p5 = Property(id=103, name="P")
-    p6 = Property()
+    p6 = Property(name="")
     r1 = Record(id=100)
     r2 = Record(id=100)
     r3 = Record(id=101, name="RT")
@@ -181,7 +180,7 @@ def test_filter():
     test_ents = [rt1, rt2, rt3, p1, p2, p3, p4, p5, p6, r1, r2, r3, r4, r5, r6]
 
     # Setup
-    for entity in [Property(), Record(), RecordType()]:
+    for entity in [Property(name=""), Record(name=""), RecordType(name="")]:
         for coll in [entity.properties, entity.parents]:
             for ent in test_ents:
                 assert ent not in coll
@@ -224,8 +223,8 @@ def test_filter():
         assert tr3 not in t_pars.filter(name="R")
         assert tr5 in t_pars.filter(name="R")
         assert tr3 in t_pars.filter(pid=101, name="R")
-        assert tr5 in t_pars.filter(pid=101, name="R")
-        assert tr3 in t_pars.filter(pid=104, name="RT")
+        assert tr5 not in t_pars.filter(pid=101, name="R")
+        assert tr3 not in t_pars.filter(pid=104, name="RT")
         assert tr5 in t_pars.filter(pid=104, name="RT")
         assert tr3 not in t_pars.filter(pid=105, name="T")
         assert tr5 not in t_pars.filter(pid=105, name="T")