diff --git a/pybis/src/python/pybis/experiment.py b/pybis/src/python/pybis/experiment.py
index eb54dc6fd082045c634a1332f0c275c2aefb297a..b5102dd8bc2f64ed5e88b2f7451319a9908e3f54 100644
--- a/pybis/src/python/pybis/experiment.py
+++ b/pybis/src/python/pybis/experiment.py
@@ -1,4 +1,4 @@
-from .property import PropertyHolder, PropertyAssignments
+from .property import PropertyHolder
 from .attribute import AttrHolder
 from .openbis_object import OpenBisObject 
 from .definitions import openbis_definitions
diff --git a/pybis/src/python/pybis/openbis_object.py b/pybis/src/python/pybis/openbis_object.py
index d6e683a67f87997369dffbf10b3a9efb14645555..1bf0ffedbbb4bc95873565f21f6e1e91d6b0274f 100644
--- a/pybis/src/python/pybis/openbis_object.py
+++ b/pybis/src/python/pybis/openbis_object.py
@@ -1,4 +1,4 @@
-from .property import PropertyHolder, PropertyAssignments
+from .property import PropertyHolder
 from .attribute import AttrHolder
 
 class OpenBisObject():
diff --git a/pybis/src/python/pybis/plugin.py b/pybis/src/python/pybis/plugin.py
index 40cb11891ac9aecd5740ebcdd473de5a5521af14..ea8d7e35d917ad8406002fde054c7ed00cd38237 100644
--- a/pybis/src/python/pybis/plugin.py
+++ b/pybis/src/python/pybis/plugin.py
@@ -1,7 +1,6 @@
 from .openbis_object import OpenBisObject 
 from .definitions import openbis_definitions, fetch_option
 from .utils import VERBOSE
-from .property import PropertyHolder, PropertyAssignments
 from .attribute import AttrHolder
 import json
 
diff --git a/pybis/src/python/pybis/project.py b/pybis/src/python/pybis/project.py
index c3258740f847d3cb216baf5d64367ae934b4fed4..60ee53ba918c33125df6812bc09619aa61c995e9 100644
--- a/pybis/src/python/pybis/project.py
+++ b/pybis/src/python/pybis/project.py
@@ -1,4 +1,3 @@
-from .property import PropertyHolder, PropertyAssignments
 from .attribute import AttrHolder
 from .openbis_object import OpenBisObject 
 from .utils import VERBOSE
diff --git a/pybis/src/python/pybis/property.py b/pybis/src/python/pybis/property.py
index 1eeeebb572b09a70344b9a70a4bfd81cf531cb33..d8b084e14129c571da5824de126a441dda356d72 100644
--- a/pybis/src/python/pybis/property.py
+++ b/pybis/src/python/pybis/property.py
@@ -42,15 +42,17 @@ class PropertyHolder():
         """ 
         if name.endswith('_'):
             name = name.rstrip('_')
-            property_type = self._type.prop[name]['propertyType']
-            if property_type['dataType'] == 'CONTROLLEDVOCABULARY':
-                return self._get_terms(property_type['vocabulary']['code'])
-            else:
-                syntax = { property_type["label"] : property_type["dataType"]}
-                if property_type["dataType"] == "TIMESTAMP":
-                    syntax['syntax'] = 'YYYY-MM-DD HH:MIN:SS'
-                return syntax
-        else: return None
+            if name in self._type.prop:
+                property_type = self._type.prop[name]['propertyType']
+                if property_type['dataType'] == 'CONTROLLEDVOCABULARY':
+                    return self._get_terms(property_type['vocabulary']['code'])
+                else:
+                    syntax = { property_type["label"] : property_type["dataType"]}
+                    if property_type["dataType"] == "TIMESTAMP":
+                        syntax['syntax'] = 'YYYY-MM-DD HH:MIN:SS'
+                    return syntax
+            return None
+
 
     def __setattr__(self, name, value):
         if name not in self._property_names:
@@ -123,172 +125,3 @@ class PropertyHolder():
             ])
         return tabulate(lines, headers=headers)
 
-
-class PropertyAssignments():
-    """ holds are properties, that are assigned to an entity, eg. sample or experiment
-    """
-
-    def __init__(self, openbis_obj, data):
-        self.openbis = openbis_obj
-        self.data = data
-        self.prop = {}
-        if self.data['propertyAssignments'] is None:
-            self.data['propertyAssignments'] = []
-        for pa in self.data['propertyAssignments']:
-            self.prop[pa['propertyType']['code'].lower()] = pa
-
-    def __str__(self):
-        """String representation of this entity type
-        """
-        return self.data['code']
-
-    def _attrs(self):
-        return ['code', 'description', 'autoGeneratedCode', 'subcodeUnique',
-            'generatedCodePrefix', 'listable', 'showContainer', 'showParents',
-            'showParentMetadata', 'validationPlugin']
-
-    def __dir__(self):
-        return self._attrs()
-
-    def __getattr__(self, name):
-        if name in self._attrs():
-            if name in self.data:
-                return self.data[name]
-            else:
-                return ''
-        else:
-            return ''
-
-    def __eq__(self, other):
-        return str(self) == str(other)
-
-    def __ne__(self, other):
-        return str(self) != str(other)
-
-
-    def codes(self):
-        codes = []
-        for pa in self.data['propertyAssignments']:
-            codes.append(pa['propertyType']['code'].lower())
-        return codes
-
-    def _repr_html_(self):
-
-        def nvl(val, string=''):
-            if val is None:
-                return string
-            return val
-
-        html = "<p>{}: <b>{}</b>".format(
-            self.data['@type'].split('.')[-1],
-            self.data['code'], 
-        )
-
-        html += """
-            <table border="1" class="dataframe">
-            <thead>
-                <tr style="text-align: right;">
-                <th>attribute</th>
-                <th>value</th>
-                </tr>
-            </thead>
-            <tbody>
-        """
-
-        for attr in self._attrs():
-            if attr == 'validationPlugin':
-                continue
-            html += "<tr> <td>{}</td> <td>{}</td> </tr>".format(
-                attr, nvl(getattr(self, attr, ''), '')
-            )
-
-        html += """
-            </tbody>
-            </table>
-        """
-
-        if self.validationPlugin:
-            html += "<p/><b>Validation Plugin</b>"
-            html += """
-                <table border="1" class="dataframe">
-                <thead>
-                    <tr style="text-align: right;">
-                    <th>attribute</th>
-                    <th>value</th>
-                    </tr>
-                </thead>
-                <tbody>
-            """
-            for attr in ['name', 'description', 'pluginType', 'pluginKind',
-                'available', 'entityKinds']:
-                html += "<tr> <td>{}</td> <td>{}</td> </tr>".format(
-                    attr, self.validationPlugin.get(attr)
-                )
-            html += """
-                </tbody>
-                </table>
-            """
-
-
-        #if 'autoGeneratedCode' in self.data:
-        #    html += "<p>Code autogenerated: {}</p>".format(
-        #        self.data['autoGeneratedCode'])
-
-        html += """
-        <p><b>Property Assignments</b>
-<table border="1" class="dataframe">
-  <thead>
-    <tr style="text-align: right;">
-      <th>property</th>
-      <th>label</th>
-      <th>description</th>
-      <th>dataType</th>
-      <th>mandatory</th>
-    </tr>
-  </thead>
-  <tbody>
-        """
-
-        for pa in self.data['propertyAssignments']:
-            html += "<tr> <th>{}</th> <td>{}</td> <td>{}</td> <td>{}</td> <td>{}</td> </tr>".format(
-                pa['propertyType']['code'].lower(),    
-                pa['propertyType']['label'],    
-                pa['propertyType']['description'],    
-                pa['propertyType']['dataType'],    
-                pa['mandatory']
-            )
-
-        html += """
-            </tbody>
-            </table>
-        """
-        return html
-
-    def __repr__(self):
-        title = """
-{}: {}
-description: {}""".format (
-            self.data['@type'].split('.')[-1],
-            self.data['code'], 
-            self.data['description']
-        )
-
-        table = Texttable()
-        table.set_deco(Texttable.HEADER)
-
-        headers = ['code', 'label', 'description', 'dataType', 'mandatory']
-
-        lines = []
-        lines.append(headers)
-        for pa in self.data['propertyAssignments']:
-            lines.append([
-                pa['propertyType']['code'].lower(),    
-                pa['propertyType']['label'],    
-                pa['propertyType']['description'],    
-                pa['propertyType']['dataType'],    
-                pa['mandatory']
-            ])
-        table.add_rows(lines)
-        table.set_cols_width([28,28,28,28,9])
-        table.set_cols_align(['l','l','l','l','l'])
-        return title + "\n\n" + table.draw()
diff --git a/pybis/src/python/pybis/sample_type.py b/pybis/src/python/pybis/sample_type.py
index 83491132777046cd9c0f8e67c30ab6def876c1cf..59ca5beb9c728172b41070c05e36a92f1d602a9d 100644
--- a/pybis/src/python/pybis/sample_type.py
+++ b/pybis/src/python/pybis/sample_type.py
@@ -1,4 +1,4 @@
-from .property import PropertyAssignments
+from .property_assignment import PropertyAssignments
 from .semantic_annotation import SemanticAnnotation
 
 class SampleType(PropertyAssignments):
diff --git a/pybis/src/python/pybis/tag.py b/pybis/src/python/pybis/tag.py
index 34e465771174ee27553e915f1afda1e8dd17c0f2..5f7cd9b1bf7c204fe1aa79aa76f407d3e6499d00 100644
--- a/pybis/src/python/pybis/tag.py
+++ b/pybis/src/python/pybis/tag.py
@@ -1,6 +1,5 @@
 from .openbis_object import OpenBisObject 
 from .utils import VERBOSE
-from .property import PropertyHolder, PropertyAssignments
 from .attribute import AttrHolder
 import json