diff --git a/CHANGELOG.md b/CHANGELOG.md
index a6b2de738c79b3ad38c6bf77a2abb3611a6511eb..c307c15ac9ceb0a039f6406d0cb9148931c2837e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 - CFood that creates a Record for each line in a csv file
 - `generic_analysis.py` allows to easily call scripts to perform analyses in
   server side scripting [EXPERIMENTAL]
+- New keyword "role" in yaml data model that allows creation of Records and Files.
+- It is now possible to set values of properties and default values of properties
+  directly in the yaml model.
 
 ### Changed ###
 
diff --git a/src/caosadvancedtools/models/parser.py b/src/caosadvancedtools/models/parser.py
index e56a492fa3e9199a312d374a622770e7836f42cb..f385a1a3cdfaa91d3d61e6474743cd0549318e0d 100644
--- a/src/caosadvancedtools/models/parser.py
+++ b/src/caosadvancedtools/models/parser.py
@@ -25,7 +25,7 @@ import yaml
 from .data_model import DataModel
 
 # Keywords which are allowed in data model descriptions.
-KEYWORDS = ["parent",
+KEYWORDS = ["parent",  # TODO: can we remove that, see: #36
             "importance",
             "datatype",  # for example TEXT, INTEGER or REFERENCE
             "unit",
@@ -35,8 +35,11 @@ KEYWORDS = ["parent",
             "suggested_properties",
             "inherit_from_recommended",
             "inherit_from_suggested",
-            "inherit_from_obligatory", ]
+            "inherit_from_obligatory",
+            "role",
+            "value", ]
 
+# TODO: check whether it's really ignored
 # These KEYWORDS are not forbidden as properties, but merely ignored.
 KEYWORDS_IGNORED = [
     "unit",
@@ -109,6 +112,10 @@ def parse_model_from_string(string):
 
 class Parser(object):
     def __init__(self):
+        """
+        Initialize an empty parer object and initialize
+        the dictionary of entities and the list of treated elements.
+        """
         self.model = {}
         self.treated = []
 
@@ -177,13 +184,11 @@ class Parser(object):
             ymlmodel["extern"] = []
 
         for name in ymlmodel["extern"]:
-            if db.execute_query("COUNT Property {}".format(name)) > 0:
-                self.model[name] = db.execute_query(
-                    "FIND Property WITH name={}".format(name), unique=True)
-
-            elif db.execute_query("COUNT RecordType {}".format(name)) > 0:
-                self.model[name] = db.execute_query(
-                    "FIND RecordType WITH name={}".format(name), unique=True)
+            for role in ("Property", "RecordType", "Record", "File"):
+                if db.execute_query("COUNT {} {}".format(role, name)) > 0:
+                    self.model[name] = db.execute_query(
+                        "FIND {} WITH name={}".format(role, name), unique=True)
+                    break
             else:
                 raise Exception("Did not find {}".format(name))
 
@@ -235,6 +240,8 @@ class Parser(object):
         """ adds names of Properties and RecordTypes to the model dictionary
 
         Properties are also initialized.
+
+        name is the key of the yaml element and definition the value.
         """
 
         if name == "__line__":
@@ -258,9 +265,25 @@ class Parser(object):
             # and create the new property
             self.model[name] = db.Property(name=name,
                                            datatype=definition["datatype"])
+        elif (self.model[name] is None and isinstance(definition, dict)
+              and "role" in definition):
+            if definition["role"] == "RecordType":
+                self.model[name] = db.RecordType(name=name)
+            elif definition["role"] == "Record":
+                self.model[name] = db.Record(name=name)
+            elif definition["role"] == "File":
+                self.model[name] = db.File(name=name)
+            elif definition["role"] == "Property":
+                self.model[name] = db.Property(name=name)
+            else:
+                raise RuntimeError("Unknown role {} in definition of entity.".format(
+                    definition["role"]))
 
-        # add other definitions recursively
+        # for setting values of properties directly:
+        if not isinstance(definition, dict):
+            return
 
+        # add other definitions recursively
         for prop_type in ["recommended_properties",
                           "suggested_properties", "obligatory_properties"]:
 
@@ -303,8 +326,12 @@ class Parser(object):
                     name=n,
                     importance=importance,
                     datatype=db.LIST(_get_listdatatype(e["datatype"])))
+            elif e is None:
+                self.model[ent_name].add_property(name=n,
+                                                  importance=importance)
             else:
                 self.model[ent_name].add_property(name=n,
+                                                  value=e,
                                                   importance=importance)
 
     def _inherit(self, name, prop, inheritance):
@@ -328,6 +355,10 @@ class Parser(object):
             if definition is None:
                 return
 
+            # for setting values of properties directly:
+            if not isinstance(definition, dict):
+                return
+
             if ("datatype" in definition
                     and definition["datatype"].startswith("LIST")):
 
@@ -344,6 +375,9 @@ class Parser(object):
                 if prop_name == "unit":
                     self.model[name].unit = prop
 
+                elif prop_name == "value":
+                    self.model[name].value = prop
+
                 elif prop_name == "description":
                     self.model[name].description = prop
 
@@ -372,6 +406,10 @@ class Parser(object):
                 elif prop_name == "datatype":
                     continue
 
+                # role has already been used
+                elif prop_name == "role":
+                    continue
+
                 elif prop_name == "inherit_from_obligatory":
                     self._inherit(name, prop, db.OBLIGATORY)
                 elif prop_name == "inherit_from_recommended":
diff --git a/unittests/test_parser.py b/unittests/test_parser.py
index 161e2873a9c01f9ce415818116b9e4cf9aeadb5c..a14cb1ab516e87eb64bc78deadc0481c8501a058 100644
--- a/unittests/test_parser.py
+++ b/unittests/test_parser.py
@@ -15,6 +15,8 @@ def to_file(string):
 
     return f.name
 
+# TODO: check purpose of this function... add documentation
+
 
 def parse_str(string):
     parse_model_from_yaml(to_file(string))
@@ -68,7 +70,8 @@ RT2:
         a:
 """
 
-        self.assertRaises(TwiceDefinedException, lambda: parse_model_from_yaml(to_file(string)))
+        self.assertRaises(TwiceDefinedException,
+                          lambda: parse_model_from_yaml(to_file(string)))
 
     def test_typical_case(self):
         string = """
@@ -103,7 +106,8 @@ RT5:
 - RT1:
 - RT2:
 """
-        self.assertRaises(ValueError, lambda: parse_model_from_yaml(to_file(string)))
+        self.assertRaises(
+            ValueError, lambda: parse_model_from_yaml(to_file(string)))
 
     def test_unknown_kwarg(self):
         string = """
@@ -111,7 +115,8 @@ RT1:
   datetime:
     p1:
 """
-        self.assertRaises(ValueError, lambda: parse_model_from_yaml(to_file(string)))
+        self.assertRaises(
+            ValueError, lambda: parse_model_from_yaml(to_file(string)))
 
     def test_definition_in_inheritance(self):
         string = """
@@ -121,7 +126,8 @@ RT2:
   - RT1:
     description: "tach"
 """
-        self.assertRaises(ValueError, lambda: parse_model_from_yaml(to_file(string)))
+        self.assertRaises(
+            ValueError, lambda: parse_model_from_yaml(to_file(string)))
 
     def test_inheritance(self):
         string = """
@@ -301,6 +307,8 @@ class ExternTest(unittest.TestCase):
 class ErrorMessageTest(unittest.TestCase):
     """Tests for understandable error messages."""
 
+    # Note: This was changed with implementation of role keyword
+    @unittest.expectedFailure
     def test_non_dict(self):
         """When a value is given, where a list or mapping is expected."""
         recordtype_value = """
@@ -328,3 +336,66 @@ A:
             with self.assertRaises(YamlDefinitionError) as yde:
                 parse_str(string)
             assert("line {}".format(line) in yde.exception.args[0])
+
+
+def test_define_role():
+    model = """
+A:
+  role: Record
+"""
+    entities = parse_model_from_string(model)
+    assert "A" in entities
+    assert isinstance(entities["A"], db.Record)
+    assert entities["A"].role == "Record"
+
+    model = """
+A:
+  role: Record
+  inherit_from_obligatory:
+  - C
+  obligatory_properties:
+    b:
+b:
+  datatype: INTEGER
+C:
+  obligatory_properties:
+    b:
+D:
+  role: RecordType
+"""
+    entities = parse_model_from_string(model)
+    for l, ent in (("A", "Record"), ("b", "Property"),
+                   ("C", "RecordType"), ("D", "RecordType")):
+        assert l in entities
+        assert isinstance(entities[l], getattr(db, ent))
+        assert entities[l].role == ent
+
+    assert entities["A"].parents[0].name == "C"
+    assert entities["A"].name == "A"
+
+    assert entities["A"].properties[0].name == "b"
+    assert entities["A"].properties[0].value is None
+
+    assert entities["C"].properties[0].name == "b"
+    assert entities["C"].properties[0].value is None
+
+    model = """
+A:
+  role: Record
+  obligatory_properties:
+    b: 42
+b:
+  datatype: INTEGER
+"""
+
+    entities = parse_model_from_string(model)
+    assert entities["A"].get_property("b").value == 42
+    assert entities["b"].value is None
+
+    model = """
+b:
+  datatype: INTEGER
+  value: 18
+"""
+    entities = parse_model_from_string(model)
+    assert entities["b"].value == 18