diff --git a/CHANGELOG.md b/CHANGELOG.md
index 03710a3d17afebc1636ed47bd870742db3be9e04..d4d39bda064d6caf53ddfd816cdb398f1eed07de 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,7 +9,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ### Added
 
-- New functions getEnumNameFromValue() and getEnumValueFromName().
+* New functions getEnumNameFromValue() and getEnumValueFromName().
+* Extern C now supports datatypes, roles, and importances as enums,
+  and typed property values
 
 ### Changed
 
diff --git a/include/caosdb/status_code.h b/include/caosdb/status_code.h
index 573b126fa94435c4669ace37ea00cbdbbbde6545..5689b9ebeab94d01272ce049d3cb0e3f16d13665 100644
--- a/include/caosdb/status_code.h
+++ b/include/caosdb/status_code.h
@@ -61,6 +61,7 @@ enum StatusCode {
   FILE_DOES_NOT_EXIST_LOCALLY = 34,
   FILE_UPLOAD_ERROR = 35,
   FILE_DOWNLOAD_ERROR = 36,
+  ENUM_MAPPING_ERROR = 37,
   OTHER_CLIENT_ERROR = 9999,
 };
 
diff --git a/include/ccaosdb.h b/include/ccaosdb.h
index d2f899fd7657fa4c3867f2e008ff9fb270ca8490..e23e3a72ad58167e060081757e97d84cbfeaa2b8 100644
--- a/include/ccaosdb.h
+++ b/include/ccaosdb.h
@@ -321,14 +321,32 @@ typedef struct {
 } caosdb_entity_message;
 
 // GETTERS FOR EVERYTHING
-int caosdb_entity_entity_get_id(caosdb_entity_entity *entity, char *out);
-int caosdb_entity_entity_get_role(caosdb_entity_entity *entity, char *out);
-int caosdb_entity_entity_get_name(caosdb_entity_entity *entity, char *out);
-int caosdb_entity_entity_get_description(caosdb_entity_entity *entity, char *out);
-int caosdb_entity_entity_get_datatype(caosdb_entity_entity *entity, char *out);
-int caosdb_entity_entity_get_unit(caosdb_entity_entity *entity, char *out);
-int caosdb_entity_entity_get_value(caosdb_entity_entity *entity, char *out);
-int caosdb_entity_entity_get_version_id(caosdb_entity_entity *entity, char *out);
+int caosdb_entity_entity_get_id(caosdb_entity_entity *entity, char **out);
+int caosdb_entity_entity_get_role(caosdb_entity_entity *entity, char **out);
+int caosdb_entity_entity_get_name(caosdb_entity_entity *entity, char **out);
+int caosdb_entity_entity_get_description(caosdb_entity_entity *entity, char **out);
+/**
+ * Get the name of the entity's datatype, whether it is a reference, and whether it is a list.
+ */
+int caosdb_entity_entity_get_datatype(caosdb_entity_entity *entity, char **name, bool *is_ref,
+                                      bool *is_list);
+int caosdb_entity_entity_get_unit(caosdb_entity_entity *entity, char **out);
+
+int caosdb_entity_entity_get_int_value(caosdb_entity_entity *entity, long *out);
+int caosdb_entity_entity_get_double_value(caosdb_entity_entity *entity, double *out);
+int caosdb_entity_entity_get_boolean_value(caosdb_entity_entity *entity, bool *out);
+int caosdb_entity_entity_get_string_value(caosdb_entity_entity *entity, char **out);
+int caosdb_entity_entity_get_int_list_value_at(caosdb_entity_entity *entity, long *out,
+                                               const int index);
+int caosdb_entity_entity_get_double_list_value_at(caosdb_entity_entity *entity, double *out,
+                                                  const int index);
+int caosdb_entity_entity_get_boolean_list_value_at(caosdb_entity_entity *entity, bool *out,
+                                                   const int index);
+int caosdb_entity_entity_get_string_list_value_at(caosdb_entity_entity *entity, char **out,
+                                                  const int index);
+int caosdb_entity_entity_get_value_list_length(caosdb_entity_entity *entity, int *out);
+
+int caosdb_entity_entity_get_version_id(caosdb_entity_entity *entity, char **out);
 int caosdb_entity_entity_get_errors_size(caosdb_entity_entity *entity, int *out);
 int caosdb_entity_entity_get_error(caosdb_entity_entity *entity, caosdb_entity_message *out,
                                    int index);
@@ -345,20 +363,37 @@ int caosdb_entity_entity_get_parents_size(caosdb_entity_entity *entity, int *out
 int caosdb_entity_entity_get_parent(caosdb_entity_entity *entity, caosdb_entity_parent *out,
                                     int index);
 
-int caosdb_entity_property_get_id(caosdb_entity_property *property, char *out);
-int caosdb_entity_property_get_name(caosdb_entity_property *property, char *out);
-int caosdb_entity_property_get_description(caosdb_entity_property *property, char *out);
-int caosdb_entity_property_get_importance(caosdb_entity_property *property, char *out);
-int caosdb_entity_property_get_datatype(caosdb_entity_property *property, char *out);
-int caosdb_entity_property_get_unit(caosdb_entity_property *property, char *out);
-int caosdb_entity_property_get_value(caosdb_entity_property *property, char *out);
-
-int caosdb_entity_parent_get_id(caosdb_entity_parent *parent, char *out);
-int caosdb_entity_parent_get_name(caosdb_entity_parent *parent, char *out);
-int caosdb_entity_parent_get_description(caosdb_entity_parent *parent, char *out);
+int caosdb_entity_property_get_id(caosdb_entity_property *property, char **out);
+int caosdb_entity_property_get_name(caosdb_entity_property *property, char **out);
+int caosdb_entity_property_get_description(caosdb_entity_property *property, char **out);
+int caosdb_entity_property_get_importance(caosdb_entity_property *property, char **out);
+/**
+ * Get the name of the property's datatype, whether it is a reference, and whether it is a list.
+ */
+int caosdb_entity_property_get_datatype(caosdb_entity_property *property, char **name, bool *is_ref,
+                                        bool *is_list);
+int caosdb_entity_property_get_unit(caosdb_entity_property *property, char **out);
+
+int caosdb_entity_property_get_int_value(caosdb_entity_property *property, long *out);
+int caosdb_entity_property_get_double_value(caosdb_entity_property *property, double *out);
+int caosdb_entity_property_get_boolean_value(caosdb_entity_property *property, bool *out);
+int caosdb_entity_property_get_string_value(caosdb_entity_property *property, char **out);
+int caosdb_entity_property_get_int_list_value_at(caosdb_entity_property *property, long *out,
+                                                 const int index);
+int caosdb_entity_property_get_double_list_value_at(caosdb_entity_property *property, double *out,
+                                                    const int index);
+int caosdb_entity_property_get_boolean_list_value_at(caosdb_entity_property *property, bool *out,
+                                                     const int index);
+int caosdb_entity_property_get_string_list_value_at(caosdb_entity_property *property, char **out,
+                                                    const int index);
+int caosdb_entity_property_get_value_list_length(caosdb_entity_property *property, int *out);
+
+int caosdb_entity_parent_get_id(caosdb_entity_parent *parent, char **out);
+int caosdb_entity_parent_get_name(caosdb_entity_parent *parent, char **out);
+int caosdb_entity_parent_get_description(caosdb_entity_parent *parent, char **out);
 
 int caosdb_entity_message_get_code(caosdb_entity_message *message, int *out);
-int caosdb_entity_message_get_description(caosdb_entity_message *message, char *out);
+int caosdb_entity_message_get_description(caosdb_entity_message *message, char **out);
 
 // CONSTRUCTORS AND DESTRUCTORS
 int caosdb_entity_create_entity(caosdb_entity_entity *out);
@@ -372,9 +407,26 @@ int caosdb_entity_delete_parent(caosdb_entity_parent *out);
 int caosdb_entity_entity_set_role(caosdb_entity_entity *entity, const char *role);
 int caosdb_entity_entity_set_name(caosdb_entity_entity *entity, const char *name);
 int caosdb_entity_entity_set_description(caosdb_entity_entity *entity, const char *description);
-int caosdb_entity_entity_set_datatype(caosdb_entity_entity *entity, const char *datatype);
+/**
+ * Set the entity's datatype by name, and whether it is a reference or a list.
+ */
+int caosdb_entity_entity_set_datatype(caosdb_entity_entity *entity, const char *datatype,
+                                      const bool is_ref, const bool is_list);
 int caosdb_entity_entity_set_unit(caosdb_entity_entity *entity, const char *unit);
-int caosdb_entity_entity_set_value(caosdb_entity_entity *entity, const char *value);
+// TODO(fspreck) replace by more specific setters
+int caosdb_entity_entity_set_int_value(caosdb_entity_entity *entity, const long value);
+int caosdb_entity_entity_set_double_value(caosdb_entity_entity *entity, const double value);
+int caosdb_entity_entity_set_boolean_value(caosdb_entity_entity *entity, const bool value);
+int caosdb_entity_entity_set_string_value(caosdb_entity_entity *entity, const char *value);
+int caosdb_entity_entity_set_int_list_value(caosdb_entity_entity *entity, const long *value,
+                                            const int length);
+int caosdb_entity_entity_set_double_list_value(caosdb_entity_entity *entity, const double *value,
+                                               const int length);
+int caosdb_entity_entity_set_boolean_list_value(caosdb_entity_entity *entity, const bool *value,
+                                                const int length);
+int caosdb_entity_entity_set_string_list_value(caosdb_entity_entity *entity, const char **value,
+                                               const int length);
+
 int caosdb_entity_entity_append_parent(caosdb_entity_entity *entity, caosdb_entity_parent *parent);
 int caosdb_entity_entity_remove_parent(caosdb_entity_entity *entity, int index);
 int caosdb_entity_entity_append_property(caosdb_entity_entity *entity,
@@ -383,10 +435,26 @@ int caosdb_entity_entity_remove_property(caosdb_entity_entity *entity, int index
 
 int caosdb_entity_property_set_id(caosdb_entity_property *property, const char *id);
 int caosdb_entity_property_set_name(caosdb_entity_property *property, const char *name);
-int caosdb_entity_property_set_datatype(caosdb_entity_property *property, const char *datatype);
+/**
+ * Set the property's datatype by name, and whether it is a reference or a list.
+ */
+int caosdb_entity_property_set_datatype(caosdb_entity_property *property, const char *datatype,
+                                        const bool is_ref, const bool is_list);
 int caosdb_entity_property_set_importance(caosdb_entity_property *property, const char *importance);
 int caosdb_entity_property_set_unit(caosdb_entity_property *property, const char *unit);
-int caosdb_entity_property_set_value(caosdb_entity_property *property, const char *value);
+
+int caosdb_entity_property_set_int_value(caosdb_entity_property *property, const long value);
+int caosdb_entity_property_set_double_value(caosdb_entity_property *property, const double value);
+int caosdb_entity_property_set_boolean_value(caosdb_entity_property *property, const bool value);
+int caosdb_entity_property_set_string_value(caosdb_entity_property *property, const char *value);
+int caosdb_entity_property_set_int_list_value(caosdb_entity_property *property, const long *value,
+                                              const int length);
+int caosdb_entity_property_set_double_list_value(caosdb_entity_property *property,
+                                                 const double *value, const int length);
+int caosdb_entity_property_set_boolean_list_value(caosdb_entity_property *property,
+                                                  const bool *value, const int length);
+int caosdb_entity_property_set_string_list_value(caosdb_entity_property *property,
+                                                 const char **value, const int length);
 
 int caosdb_entity_parent_set_id(caosdb_entity_parent *parent, const char *id);
 int caosdb_entity_parent_set_name(caosdb_entity_parent *parent, const char *name);
diff --git a/src/caosdb/transaction.cpp b/src/caosdb/transaction.cpp
index 75350b2680b55976d9a7a96b58962540216d4eae..5a7cb74683071f42e54f8ad056f37643092bb4ef 100644
--- a/src/caosdb/transaction.cpp
+++ b/src/caosdb/transaction.cpp
@@ -96,6 +96,8 @@ auto get_status_description(int code) -> const std::string & {
     {StatusCode::EXTERN_C_ASSIGNMENT_ERROR,
      "You tried to assign a new object to the wrapped void pointer. You have "
      "to delete the old pointee first."},
+    {StatusCode::ENUM_MAPPING_ERROR,
+     "The role, importance, or datatype you specified does not exist."},
     {StatusCode::OTHER_CLIENT_ERROR,
      "This is code is reserved to errors raised by other clients wrapping the "
      "C++ client (or its Extern C interface).  This should never occur when "
diff --git a/src/ccaosdb.cpp b/src/ccaosdb.cpp
index dce0970bf21343eb12ffac6098450d507de70e59..40a47227c5d146a97583e5068b033896e17b1cfe 100644
--- a/src/ccaosdb.cpp
+++ b/src/ccaosdb.cpp
@@ -22,6 +22,7 @@
 #include "ccaosdb.h"
 #include "caosdb/connection.h"
 #include "caosdb/constants.h"
+#include "caosdb/data_type.h" // for DataType, AtomicDat...
 #include "caosdb/utility.h"
 #include "caosdb/status_code.h"
 #include "caosdb/logging.h"
@@ -37,6 +38,20 @@ extern "C" {
 
 #define CCAOSDB_LOGGER_NAME "ccaosdb"
 
+#define WRAPPED_ENTITY_CAST(name) static_cast<caosdb::entity::Entity *>(name->wrapped_entity)
+
+#define WRAPPED_PROPERTY_CAST(name) static_cast<caosdb::entity::Property *>(name->wrapped_property)
+
+#define WRAPPED_PARENT_CAST(name) static_cast<caosdb::entity::Parent *>(name->wrapped_parent)
+
+#define WRAPPED_MESSAGE_CAST(name) static_cast<caosdb::entity::Message *>(name->wrapped_message)
+
+#define ENUM_NAME_FROM_VALUE(arg, etype)                                                           \
+  caosdb::utility::getEnumNameFromValue<caosdb::entity::etype>(arg)
+
+#define ENUM_VALUE_FROM_NAME(arg, etype)                                                           \
+  caosdb::utility::getEnumValueFromName<caosdb::entity::etype>(arg)
+
 /*
  * Macro for wrapping every function into a try-catch clause. If an exception
  * occurs, the given StatusCode is being returned.
@@ -55,12 +70,16 @@ extern "C" {
 /**
  * Macro for entity getters
  */
-#define CAOSDB_ENTITY_GET(element, body_part)                                                      \
+#define CAOSDB_ENTITY_GET(element, GetFunction)                                                    \
   ERROR_RETURN_CODE(                                                                               \
     GENERIC_ERROR,                                                                                 \
-    int caosdb_entity_entity_get_##element(caosdb_entity_entity *entity, char *out), {             \
-      auto *wrapped_entity = static_cast<caosdb::entity::Entity *>(entity->wrapped_entity);        \
-      body_part return 0;                                                                          \
+    int caosdb_entity_entity_get_##element(caosdb_entity_entity *entity, char **out), {            \
+      auto *wrapped_entity = WRAPPED_ENTITY_CAST(entity);                                          \
+      char *tmp = (char *)malloc(sizeof(char) * wrapped_entity->GetFunction.length() + 1);         \
+      strcpy(tmp, wrapped_entity->GetFunction.c_str());                                            \
+      delete[] * out;                                                                              \
+      *out = tmp;                                                                                  \
+      return 0;                                                                                    \
     })
 
 /**
@@ -70,20 +89,23 @@ extern "C" {
   ERROR_RETURN_CODE(                                                                               \
     GENERIC_ERROR,                                                                                 \
     int caosdb_entity_entity_set_##element(caosdb_entity_entity *entity, const char *value), {     \
-      auto *wrapped_entity = static_cast<caosdb::entity::Entity *>(entity->wrapped_entity);        \
+      auto *wrapped_entity = WRAPPED_ENTITY_CAST(entity);                                          \
       body_part return 0;                                                                          \
     })
 
 /**
  * Macro for property getters
  */
-#define CAOSDB_PROPERTY_GET(element, body_part)                                                    \
+#define CAOSDB_PROPERTY_GET(element, GetFunction)                                                  \
   ERROR_RETURN_CODE(                                                                               \
     GENERIC_ERROR,                                                                                 \
-    int caosdb_entity_property_get_##element(caosdb_entity_property *property, char *out), {       \
-      auto *wrapped_property =                                                                     \
-        static_cast<caosdb::entity::Property *>(property->wrapped_property);                       \
-      body_part return 0;                                                                          \
+    int caosdb_entity_property_get_##element(caosdb_entity_property *property, char **out), {      \
+      auto *wrapped_property = WRAPPED_PROPERTY_CAST(property);                                    \
+      char *tmp = (char *)malloc(sizeof(char) * wrapped_property->GetFunction.length() + 1);       \
+      strcpy(tmp, wrapped_property->GetFunction.c_str());                                          \
+      delete[] * out;                                                                              \
+      *out = tmp;                                                                                  \
+      return 0;                                                                                    \
     })
 
 /**
@@ -94,20 +116,23 @@ extern "C" {
     GENERIC_ERROR,                                                                                 \
     int caosdb_entity_property_set_##element(caosdb_entity_property *property, const char *value), \
     {                                                                                              \
-      auto *wrapped_property =                                                                     \
-        static_cast<caosdb::entity::Property *>(property->wrapped_property);                       \
+      auto *wrapped_property = WRAPPED_PROPERTY_CAST(property);                                    \
       body_part return 0;                                                                          \
     })
 
 /**
  * Macro for parent getters
  */
-#define CAOSDB_PARENT_GET(element, body_part)                                                      \
+#define CAOSDB_PARENT_GET(element, GetFunction)                                                    \
   ERROR_RETURN_CODE(                                                                               \
     GENERIC_ERROR,                                                                                 \
-    int caosdb_entity_parent_get_##element(caosdb_entity_parent *parent, char *out), {             \
-      auto *wrapped_parent = static_cast<caosdb::entity::Parent *>(parent->wrapped_parent);        \
-      body_part return 0;                                                                          \
+    int caosdb_entity_parent_get_##element(caosdb_entity_parent *parent, char **out), {            \
+      auto *wrapped_parent = WRAPPED_PARENT_CAST(parent);                                          \
+      char *tmp = (char *)malloc(sizeof(char) * wrapped_parent->GetFunction.length() + 1);         \
+      strcpy(tmp, wrapped_parent->GetFunction.c_str());                                            \
+      delete[] * out;                                                                              \
+      *out = tmp;                                                                                  \
+      return 0;                                                                                    \
     })
 
 /**
@@ -117,7 +142,7 @@ extern "C" {
   ERROR_RETURN_CODE(                                                                               \
     GENERIC_ERROR,                                                                                 \
     int caosdb_entity_parent_set_##element(caosdb_entity_parent *parent, const char *value), {     \
-      auto *wrapped_parent = static_cast<caosdb::entity::Parent *>(parent->wrapped_parent);        \
+      auto *wrapped_parent = WRAPPED_PARENT_CAST(parent);                                          \
       body_part return 0;                                                                          \
     })
 
@@ -514,18 +539,130 @@ ERROR_RETURN_CODE(GENERIC_ERROR, int caosdb_entity_delete_parent(caosdb_entity_p
   return 0;
 })
 
-CAOSDB_ENTITY_GET(id, strcpy(out, wrapped_entity->GetId().c_str());)
-// TODO(fspreck)
-// CAOSDB_ENTITY_GET(role, strcpy(out, wrapped_entity->GetRole().c_str());)
-CAOSDB_ENTITY_GET(name, strcpy(out, wrapped_entity->GetName().c_str());)
-CAOSDB_ENTITY_GET(description, strcpy(out, wrapped_entity->GetDescription().c_str());)
-// TODO(fspreck)
-// CAOSDB_ENTITY_GET(datatype, strcpy(out,
-// wrapped_entity->GetDatatype().c_str());)
-// TODO(fspreck)
-// CAOSDB_ENTITY_GET(value, strcpy(out, wrapped_entity->GetValue().c_str());)
-CAOSDB_ENTITY_GET(unit, strcpy(out, wrapped_entity->GetUnit().c_str());)
-CAOSDB_ENTITY_GET(version_id, strcpy(out, wrapped_entity->GetVersionId().c_str());)
+CAOSDB_ENTITY_GET(id, GetId())
+ERROR_RETURN_CODE(GENERIC_ERROR,
+                  int caosdb_entity_entity_get_role(caosdb_entity_entity *entity, char **out), {
+                    auto *wrapped_entity = WRAPPED_ENTITY_CAST(entity);
+                    std::string role_str = ENUM_NAME_FROM_VALUE(wrapped_entity->GetRole(), Role);
+                    char *tmp = (char *)malloc(sizeof(char) * role_str.length() + 1);
+                    strcpy(tmp, role_str.c_str());
+                    delete[] * out;
+                    *out = tmp;
+                    return 0;
+                  })
+CAOSDB_ENTITY_GET(name, GetName())
+CAOSDB_ENTITY_GET(description, GetDescription())
+ERROR_RETURN_CODE(GENERIC_ERROR,
+                  int caosdb_entity_entity_get_datatype(caosdb_entity_entity *entity, char **name,
+                                                        bool *is_ref, bool *is_list),
+                  {
+                    auto *wrapped_entity = WRAPPED_ENTITY_CAST(entity);
+                    const auto &datatype = wrapped_entity->GetDataType();
+                    *is_list = datatype.IsList();
+                    std::string datatype_name;
+                    if (*is_list) {
+                      const auto &list_datatype = datatype.AsList();
+                      *is_ref = list_datatype.IsListOfReference();
+                      if (*is_ref) {
+                        datatype_name = list_datatype.GetReferenceDataType().GetName();
+                      } else {
+                        datatype_name =
+                          ENUM_NAME_FROM_VALUE(list_datatype.GetAtomicDataType(), AtomicDataType);
+                      }
+                    } else {
+                      *is_ref = datatype.IsReference();
+                      if (*is_ref) {
+                        datatype_name = datatype.AsReference().GetName();
+                      } else {
+                        datatype_name = ENUM_NAME_FROM_VALUE(datatype.AsAtomic(), AtomicDataType);
+                      }
+                    }
+                    char *tmp = (char *)malloc(sizeof(char) * datatype_name.length() + 1);
+                    strcpy(tmp, datatype_name.c_str());
+                    delete[] * name;
+                    *name = tmp;
+                    return 0;
+                  })
+ERROR_RETURN_CODE(GENERIC_ERROR,
+                  int caosdb_entity_entity_get_int_value(caosdb_entity_entity *entity, long *out), {
+                    auto *wrapped_entity = WRAPPED_ENTITY_CAST(entity);
+                    *out = wrapped_entity->GetValue().AsInteger();
+                    return 0;
+                  })
+ERROR_RETURN_CODE(GENERIC_ERROR,
+                  int caosdb_entity_entity_get_double_value(caosdb_entity_entity *entity,
+                                                            double *out),
+                  {
+                    auto *wrapped_entity = WRAPPED_ENTITY_CAST(entity);
+                    *out = wrapped_entity->GetValue().AsDouble();
+                    return 0;
+                  })
+ERROR_RETURN_CODE(GENERIC_ERROR,
+                  int caosdb_entity_entity_get_boolean_value(caosdb_entity_entity *entity,
+                                                             bool *out),
+                  {
+                    auto *wrapped_entity = WRAPPED_ENTITY_CAST(entity);
+                    *out = wrapped_entity->GetValue().AsBool();
+                    return 0;
+                  })
+CAOSDB_ENTITY_GET(string_value, GetValue().AsString())
+
+ERROR_RETURN_CODE(GENERIC_ERROR,
+                  int caosdb_entity_entity_get_int_list_value_at(caosdb_entity_entity *entity,
+                                                                 long *out, const int index),
+                  {
+                    auto *wrapped_entity = WRAPPED_ENTITY_CAST(entity);
+                    auto value_list = wrapped_entity->GetValue().AsList();
+                    *out = value_list[index].AsInteger();
+                    return 0;
+                  })
+ERROR_RETURN_CODE(GENERIC_ERROR,
+                  int caosdb_entity_entity_get_double_list_value_at(caosdb_entity_entity *entity,
+                                                                    double *out, const int index),
+                  {
+                    auto *wrapped_entity = WRAPPED_ENTITY_CAST(entity);
+                    auto value_list = wrapped_entity->GetValue().AsList();
+                    *out = value_list[index].AsDouble();
+                    return 0;
+                  })
+ERROR_RETURN_CODE(GENERIC_ERROR,
+                  int caosdb_entity_entity_get_boolean_value_list_value_at(
+                    caosdb_entity_entity *entity, bool *out, const int index),
+                  {
+                    auto *wrapped_entity = WRAPPED_ENTITY_CAST(entity);
+                    auto value_list = wrapped_entity->GetValue().AsList();
+                    *out = value_list[index].AsBool();
+                    return 0;
+                  })
+ERROR_RETURN_CODE(GENERIC_ERROR,
+                  int caosdb_entity_entity_get_string_list_value_at(caosdb_entity_entity *entity,
+                                                                    char **out, const int index),
+                  {
+                    auto *wrapped_entity = WRAPPED_ENTITY_CAST(entity);
+                    auto value_list = wrapped_entity->GetValue().AsList();
+                    char *tmp =
+                      (char *)malloc(sizeof(char) * value_list[index].AsString().length() + 1);
+                    strcpy(tmp, value_list[index].AsString().c_str());
+                    delete[] * out;
+                    *out = tmp;
+                    return 0;
+                  })
+
+ERROR_RETURN_CODE(GENERIC_ERROR,
+                  int caosdb_entity_entity_get_value_list_length(caosdb_entity_entity *entity,
+                                                                 int *out),
+                  {
+                    auto *wrapped_entity = WRAPPED_ENTITY_CAST(entity);
+                    if (wrapped_entity->GetValue().IsList()) {
+                      *out = wrapped_entity->GetValue().AsList().size();
+                    } else {
+                      *out = 0;
+                    }
+                    return 0;
+                  })
+
+CAOSDB_ENTITY_GET(unit, GetUnit())
+CAOSDB_ENTITY_GET(version_id, GetVersionId())
 
 ERROR_RETURN_CODE(GENERIC_ERROR,
                   int caosdb_entity_entity_get_errors_size(caosdb_entity_entity *entity, int *out),
@@ -643,54 +780,300 @@ ERROR_RETURN_CODE(GENERIC_ERROR,
                     return 0;
                   })
 
-CAOSDB_PARENT_GET(id, strcpy(out, wrapped_parent->GetId().c_str());)
-CAOSDB_PARENT_GET(name, strcpy(out, wrapped_parent->GetName().c_str());)
-CAOSDB_PARENT_GET(description, strcpy(out, wrapped_parent->GetDescription().c_str());)
+CAOSDB_PARENT_GET(id, GetId())
+CAOSDB_PARENT_GET(name, GetName())
+CAOSDB_PARENT_GET(description, GetDescription())
 
-CAOSDB_PROPERTY_GET(id, strcpy(out, wrapped_property->GetId().c_str());)
-CAOSDB_PROPERTY_GET(name, strcpy(out, wrapped_property->GetName().c_str());)
-CAOSDB_PROPERTY_GET(description, strcpy(out, wrapped_property->GetDescription().c_str());)
-// TODO(fspreck)
-// CAOSDB_PROPERTY_GET(importance,
-//                    strcpy(out, wrapped_property->GetImportance().c_str());)
-// TODO(fspreck)
-// CAOSDB_PROPERTY_GET(datatype,
-//                    strcpy(out, wrapped_property->GetDatatype().c_str());)
-CAOSDB_PROPERTY_GET(unit, strcpy(out, wrapped_property->GetUnit().c_str());)
-// TODO(fspreck)
-// CAOSDB_PROPERTY_GET(value, strcpy(out,
-// wrapped_property->GetValue().c_str());)
+CAOSDB_PROPERTY_GET(id, GetId())
+CAOSDB_PROPERTY_GET(name, GetName())
+CAOSDB_PROPERTY_GET(description, GetDescription())
 
 ERROR_RETURN_CODE(GENERIC_ERROR,
-                  int caosdb_entity_message_get_code(caosdb_entity_message *message, int *out), {
-                    auto *wrapped_message =
-                      static_cast<caosdb::entity::Message *>(message->wrapped_message);
-                    *out = wrapped_message->GetCode();
+                  int caosdb_entity_property_get_importance(caosdb_entity_property *property,
+                                                            char **out),
+                  {
+                    auto *wrapped_property = WRAPPED_PROPERTY_CAST(property);
+                    std::string importance_str =
+                      ENUM_NAME_FROM_VALUE(wrapped_property->GetImportance(), Importance);
+                    char *tmp = (char *)malloc(sizeof(char) * importance_str.length() + 1);
+                    strcpy(tmp, importance_str.c_str());
+                    delete[] * out;
+                    *out = tmp;
                     return 0;
                   })
 
 ERROR_RETURN_CODE(GENERIC_ERROR,
-                  int caosdb_entity_message_get_description(caosdb_entity_message *message,
-                                                            char *out),
+                  int caosdb_entity_property_get_datatype(caosdb_entity_property *property,
+                                                          char **name, bool *is_ref, bool *is_list),
                   {
+                    auto *wrapped_property = WRAPPED_PROPERTY_CAST(property);
+                    const auto &datatype = wrapped_property->GetDataType();
+                    *is_list = datatype.IsList();
+                    std::string datatype_name;
+                    if (*is_list) {
+                      const auto &list_datatype = datatype.AsList();
+                      *is_ref = list_datatype.IsListOfReference();
+                      if (*is_ref) {
+                        datatype_name = list_datatype.GetReferenceDataType().GetName();
+                      } else {
+                        datatype_name =
+                          ENUM_NAME_FROM_VALUE(list_datatype.GetAtomicDataType(), AtomicDataType);
+                      }
+                    } else {
+                      *is_ref = datatype.IsReference();
+                      if (*is_ref) {
+                        datatype_name = datatype.AsReference().GetName();
+                      } else {
+                        datatype_name = ENUM_NAME_FROM_VALUE(datatype.AsAtomic(), AtomicDataType);
+                      }
+                    }
+                    char *tmp = (char *)malloc(sizeof(char) * datatype_name.length() + 1);
+                    strcpy(tmp, datatype_name.c_str());
+                    delete[] * name;
+                    *name = tmp;
+                    return 0;
+                  })
+
+CAOSDB_PROPERTY_GET(unit, GetUnit())
+
+ERROR_RETURN_CODE(GENERIC_ERROR,
+                  int caosdb_entity_property_get_int_value(caosdb_entity_property *property,
+                                                           long *out),
+                  {
+                    auto *wrapped_property = WRAPPED_PROPERTY_CAST(property);
+                    *out = wrapped_property->GetValue().AsInteger();
+                    return 0;
+                  })
+ERROR_RETURN_CODE(GENERIC_ERROR,
+                  int caosdb_entity_property_get_double_value(caosdb_entity_property *property,
+                                                              double *out),
+                  {
+                    auto *wrapped_property = WRAPPED_PROPERTY_CAST(property);
+                    *out = wrapped_property->GetValue().AsDouble();
+                    return 0;
+                  })
+ERROR_RETURN_CODE(GENERIC_ERROR,
+                  int caosdb_entity_property_get_boolean_value(caosdb_entity_property *property,
+                                                               bool *out),
+                  {
+                    auto *wrapped_property = WRAPPED_PROPERTY_CAST(property);
+                    *out = wrapped_property->GetValue().AsBool();
+                    return 0;
+                  })
+CAOSDB_PROPERTY_GET(string_value, GetValue().AsString())
+
+ERROR_RETURN_CODE(GENERIC_ERROR,
+                  int caosdb_entity_property_get_int_list_value_at(caosdb_entity_property *property,
+                                                                   long *out, const int index),
+                  {
+                    auto *wrapped_property = WRAPPED_PROPERTY_CAST(property);
+                    auto value_list = wrapped_property->GetValue().AsList();
+                    *out = value_list[index].AsInteger();
+                    return 0;
+                  })
+ERROR_RETURN_CODE(GENERIC_ERROR,
+                  int caosdb_entity_property_get_double_list_value_at(
+                    caosdb_entity_property *property, double *out, const int index),
+                  {
+                    auto *wrapped_property = WRAPPED_PROPERTY_CAST(property);
+                    auto value_list = wrapped_property->GetValue().AsList();
+                    *out = value_list[index].AsDouble();
+                    return 0;
+                  })
+ERROR_RETURN_CODE(GENERIC_ERROR,
+                  int caosdb_entity_property_get_boolean_value_list_value_at(
+                    caosdb_entity_property *property, bool *out, const int index),
+                  {
+                    auto *wrapped_property = WRAPPED_PROPERTY_CAST(property);
+                    auto value_list = wrapped_property->GetValue().AsList();
+                    *out = value_list[index].AsBool();
+                    return 0;
+                  })
+ERROR_RETURN_CODE(GENERIC_ERROR,
+                  int caosdb_entity_property_get_string_list_value_at(
+                    caosdb_entity_property *property, char **out, const int index),
+                  {
+                    auto *wrapped_property = WRAPPED_PROPERTY_CAST(property);
+                    auto value_list = wrapped_property->GetValue().AsList();
+                    char *tmp =
+                      (char *)malloc(sizeof(char) * value_list[index].AsString().length() + 1);
+                    strcpy(tmp, value_list[index].AsString().c_str());
+                    delete[] * out;
+                    *out = tmp;
+                    return 0;
+                  })
+
+ERROR_RETURN_CODE(GENERIC_ERROR,
+                  int caosdb_entity_property_get_value_list_length(caosdb_entity_property *property,
+                                                                   int *out),
+                  {
+                    auto *wrapped_property = WRAPPED_PROPERTY_CAST(property);
+                    if (wrapped_property->GetValue().IsList()) {
+                      *out = wrapped_property->GetValue().AsList().size();
+                    } else {
+                      *out = 0;
+                    }
+                    return 0;
+                  })
+
+ERROR_RETURN_CODE(GENERIC_ERROR,
+                  int caosdb_entity_message_get_code(caosdb_entity_message *message, int *out), {
                     auto *wrapped_message =
                       static_cast<caosdb::entity::Message *>(message->wrapped_message);
-                    strcpy(out, wrapped_message->GetDescription().c_str());
+                    *out = wrapped_message->GetCode();
                     return 0;
                   })
 
-// TODO(fspreck)
-// CAOSDB_ENTITY_SET(role, role, wrapped_entity->SetRole(std::string(role));)
+ERROR_RETURN_CODE(
+  GENERIC_ERROR,
+  int caosdb_entity_message_get_description(caosdb_entity_message *message, char **out), {
+    auto *wrapped_message = static_cast<caosdb::entity::Message *>(message->wrapped_message);
+    char *tmp = (char *)malloc(sizeof(char) * wrapped_message->GetDescription().length() + 1);
+    strcpy(tmp, wrapped_message->GetDescription().c_str());
+    delete[] * out;
+    *out = tmp;
+    return 0;
+  })
+
+ERROR_RETURN_CODE(GENERIC_ERROR,
+                  int caosdb_entity_entity_set_role(caosdb_entity_entity *entity, const char *role),
+                  {
+                    auto *wrapped_entity = WRAPPED_ENTITY_CAST(entity);
+                    try {
+                      auto enum_value = ENUM_VALUE_FROM_NAME(std::string(role), Role);
+                      wrapped_entity->SetRole(enum_value);
+                      return 0;
+                    } catch (const std::out_of_range &exc) {
+                      caosdb::logging::caosdb_log_fatal(CCAOSDB_LOGGER_NAME, exc.what());
+                      return caosdb::StatusCode::ENUM_MAPPING_ERROR;
+                    }
+                  })
 CAOSDB_ENTITY_SET(name, name, wrapped_entity->SetName(std::string(name));)
 CAOSDB_ENTITY_SET(description, description,
                   wrapped_entity->SetDescription(std::string(description));)
-// TODO(fspreck)
-// CAOSDB_ENTITY_SET(datatype, datatype,
-//                  wrapped_entity->SetDataType(std::string(datatype));)
+ERROR_RETURN_CODE(GENERIC_ERROR,
+                  int caosdb_entity_entity_set_datatype(caosdb_entity_entity *entity,
+                                                        const char *datatype, const bool is_ref,
+                                                        const bool is_list),
+                  {
+                    auto *wrapped_entity = WRAPPED_ENTITY_CAST(entity);
+                    if (is_ref) {
+                      // Refernce datatype with name of reference
+                      wrapped_entity->SetDataType(std::string(datatype), is_list);
+                      return 0;
+                    } else {
+                      // Atomic datatype so get from enum
+                      try {
+                        auto enum_value =
+                          ENUM_VALUE_FROM_NAME(std::string(datatype), AtomicDataType);
+                        wrapped_entity->SetDataType(enum_value, is_list);
+                        return 0;
+                      } catch (const std::out_of_range &exc) {
+                        caosdb::logging::caosdb_log_fatal(CCAOSDB_LOGGER_NAME, exc.what());
+                        return caosdb::StatusCode::ENUM_MAPPING_ERROR;
+                      }
+                    }
+                  })
 CAOSDB_ENTITY_SET(unit, unit, wrapped_entity->SetUnit(std::string(unit));)
-// TODO(fspreck)
-// CAOSDB_ENTITY_SET(value, value,
-// wrapped_entity->SetValue(std::string(value));)
+
+ERROR_RETURN_CODE(GENERIC_ERROR,
+                  int caosdb_entity_entity_set_int_value(caosdb_entity_entity *entity,
+                                                         const long value),
+                  {
+                    auto *wrapped_entity =
+                      static_cast<caosdb::entity::Entity *>(entity->wrapped_entity);
+                    wrapped_entity->SetValue(value);
+                    return 0;
+                  })
+
+ERROR_RETURN_CODE(GENERIC_ERROR,
+                  int caosdb_entity_entity_set_double_value(caosdb_entity_entity *entity,
+                                                            const double value),
+                  {
+                    auto *wrapped_entity =
+                      static_cast<caosdb::entity::Entity *>(entity->wrapped_entity);
+                    wrapped_entity->SetValue(value);
+                    return 0;
+                  })
+
+ERROR_RETURN_CODE(GENERIC_ERROR,
+                  int caosdb_entity_entity_set_boolean_value(caosdb_entity_entity *entity,
+                                                             const bool value),
+                  {
+                    auto *wrapped_entity =
+                      static_cast<caosdb::entity::Entity *>(entity->wrapped_entity);
+                    wrapped_entity->SetValue(value);
+                    return 0;
+                  })
+
+ERROR_RETURN_CODE(GENERIC_ERROR,
+                  int caosdb_entity_entity_set_string_value(caosdb_entity_entity *entity,
+                                                            const char *value),
+                  {
+                    auto *wrapped_entity =
+                      static_cast<caosdb::entity::Entity *>(entity->wrapped_entity);
+                    wrapped_entity->SetValue(std::string(value));
+                    return 0;
+                  })
+
+ERROR_RETURN_CODE(GENERIC_ERROR,
+                  int caosdb_entity_entity_set_int_list_value(caosdb_entity_entity *entity,
+                                                              const long *value, const int length),
+                  {
+                    auto *wrapped_entity =
+                      static_cast<caosdb::entity::Entity *>(entity->wrapped_entity);
+                    std::vector<long> value_list;
+                    for (int i = 0; i < length; i++) {
+                      value_list.push_back(value[i]);
+                    }
+                    wrapped_entity->SetValue(value_list);
+                    return 0;
+                  })
+
+ERROR_RETURN_CODE(GENERIC_ERROR,
+                  int caosdb_entity_entity_set_double_list_value(caosdb_entity_entity *entity,
+                                                                 const double *value,
+                                                                 const int length),
+                  {
+                    auto *wrapped_entity =
+                      static_cast<caosdb::entity::Entity *>(entity->wrapped_entity);
+                    std::vector<double> value_list;
+                    for (int i = 0; i < length; i++) {
+                      value_list.push_back(value[i]);
+                    }
+                    wrapped_entity->SetValue(value_list);
+                    return 0;
+                  })
+
+ERROR_RETURN_CODE(GENERIC_ERROR,
+                  int caosdb_entity_entity_set_boolean_list_value(caosdb_entity_entity *entity,
+                                                                  const bool *value,
+                                                                  const int length),
+                  {
+                    auto *wrapped_entity =
+                      static_cast<caosdb::entity::Entity *>(entity->wrapped_entity);
+                    std::vector<bool> value_list;
+                    for (int i = 0; i < length; i++) {
+                      value_list.push_back(value[i]);
+                    }
+                    wrapped_entity->SetValue(value_list);
+                    return 0;
+                  })
+
+ERROR_RETURN_CODE(GENERIC_ERROR,
+                  int caosdb_entity_entity_set_string_list_value(caosdb_entity_entity *entity,
+                                                                 const char **value,
+                                                                 const int length),
+                  {
+                    auto *wrapped_entity =
+                      static_cast<caosdb::entity::Entity *>(entity->wrapped_entity);
+                    std::vector<std::string> value_list;
+                    for (int i = 0; i < length; i++) {
+                      value_list.push_back(std::string(value[i]));
+                    }
+                    wrapped_entity->SetValue(value_list);
+                    return 0;
+                  })
 
 ERROR_RETURN_CODE(GENERIC_ERROR,
                   int caosdb_entity_entity_append_parent(caosdb_entity_entity *entity,
@@ -737,14 +1120,144 @@ CAOSDB_PARENT_SET(name, name, wrapped_parent->SetName(std::string(name));)
 
 CAOSDB_PROPERTY_SET(name, name, wrapped_property->SetName(std::string(name));)
 CAOSDB_PROPERTY_SET(id, id, wrapped_property->SetId(std::string(id));)
-// TODO(fspreck)
-// CAOSDB_PROPERTY_SET(datatype, datatype,
-//                    wrapped_property->SetDataType(std::string(datatype));)
-// TODO(fspreck)
-// CAOSDB_PROPERTY_SET(importance, importance,
-//                    wrapped_property->SetImportance(std::string(importance));)
+
+ERROR_RETURN_CODE(GENERIC_ERROR,
+                  int caosdb_entity_property_set_datatype(caosdb_entity_property *property,
+                                                          const char *datatype, const bool is_ref,
+                                                          const bool is_list),
+                  {
+                    auto *wrapped_property = WRAPPED_PROPERTY_CAST(property);
+                    if (is_ref) {
+                      // Refernce datatype with name of reference
+                      wrapped_property->SetDataType(std::string(datatype), is_list);
+                      return 0;
+                    } else {
+                      // Atomic datatype so get from enum
+                      try {
+                        auto enum_value =
+                          ENUM_VALUE_FROM_NAME(std::string(datatype), AtomicDataType);
+                        wrapped_property->SetDataType(enum_value, is_list);
+                        return 0;
+                      } catch (const std::out_of_range &exc) {
+                        caosdb::logging::caosdb_log_fatal(CCAOSDB_LOGGER_NAME, exc.what());
+                        return caosdb::StatusCode::ENUM_MAPPING_ERROR;
+                      }
+                    }
+                  })
+
+ERROR_RETURN_CODE(GENERIC_ERROR,
+                  int caosdb_entity_property_set_importance(caosdb_entity_property *property,
+                                                            const char *importance),
+                  {
+                    auto *wrapped_property = WRAPPED_PROPERTY_CAST(property);
+                    try {
+                      auto enum_value = ENUM_VALUE_FROM_NAME(std::string(importance), Importance);
+                      wrapped_property->SetImportance(enum_value);
+                      return 0;
+                    } catch (const std::out_of_range &exc) {
+                      caosdb::logging::caosdb_log_fatal(CCAOSDB_LOGGER_NAME, exc.what());
+                      return caosdb::StatusCode::ENUM_MAPPING_ERROR;
+                    }
+                  })
+
 CAOSDB_PROPERTY_SET(unit, unit, wrapped_property->SetUnit(std::string(unit));)
-// TODO(fspreck)
-// CAOSDB_PROPERTY_SET(value, value,
-//                    wrapped_property->SetValue(std::string(value));)
+
+ERROR_RETURN_CODE(GENERIC_ERROR,
+                  int caosdb_entity_property_set_int_value(caosdb_entity_property *property,
+                                                           const long value),
+                  {
+                    auto *wrapped_property =
+                      static_cast<caosdb::entity::Property *>(property->wrapped_property);
+                    wrapped_property->SetValue(value);
+                    return 0;
+                  })
+
+ERROR_RETURN_CODE(GENERIC_ERROR,
+                  int caosdb_entity_property_set_double_value(caosdb_entity_property *property,
+                                                              const double value),
+                  {
+                    auto *wrapped_property =
+                      static_cast<caosdb::entity::Property *>(property->wrapped_property);
+                    wrapped_property->SetValue(value);
+                    return 0;
+                  })
+
+ERROR_RETURN_CODE(GENERIC_ERROR,
+                  int caosdb_entity_property_set_boolean_value(caosdb_entity_property *property,
+                                                               const bool value),
+                  {
+                    auto *wrapped_property =
+                      static_cast<caosdb::entity::Property *>(property->wrapped_property);
+                    wrapped_property->SetValue(value);
+                    return 0;
+                  })
+
+ERROR_RETURN_CODE(GENERIC_ERROR,
+                  int caosdb_entity_property_set_string_value(caosdb_entity_property *property,
+                                                              const char *value),
+                  {
+                    auto *wrapped_property =
+                      static_cast<caosdb::entity::Property *>(property->wrapped_property);
+                    wrapped_property->SetValue(std::string(value));
+                    return 0;
+                  })
+
+ERROR_RETURN_CODE(GENERIC_ERROR,
+                  int caosdb_entity_property_set_int_list_value(caosdb_entity_property *property,
+                                                                const long *value,
+                                                                const int length),
+                  {
+                    auto *wrapped_property =
+                      static_cast<caosdb::entity::Property *>(property->wrapped_property);
+                    std::vector<long> value_list;
+                    for (int i = 0; i < length; i++) {
+                      value_list.push_back(value[i]);
+                    }
+                    wrapped_property->SetValue(value_list);
+                    return 0;
+                  })
+
+ERROR_RETURN_CODE(GENERIC_ERROR,
+                  int caosdb_entity_property_set_double_list_value(caosdb_entity_property *property,
+                                                                   const double *value,
+                                                                   const int length),
+                  {
+                    auto *wrapped_property =
+                      static_cast<caosdb::entity::Property *>(property->wrapped_property);
+                    std::vector<double> value_list;
+                    for (int i = 0; i < length; i++) {
+                      value_list.push_back(value[i]);
+                    }
+                    wrapped_property->SetValue(value_list);
+                    return 0;
+                  })
+
+ERROR_RETURN_CODE(GENERIC_ERROR,
+                  int caosdb_entity_property_set_boolean_list_value(
+                    caosdb_entity_property *property, const bool *value, const int length),
+                  {
+                    auto *wrapped_property =
+                      static_cast<caosdb::entity::Property *>(property->wrapped_property);
+                    std::vector<bool> value_list;
+                    for (int i = 0; i < length; i++) {
+                      value_list.push_back(value[i]);
+                    }
+                    wrapped_property->SetValue(value_list);
+                    return 0;
+                  })
+
+ERROR_RETURN_CODE(GENERIC_ERROR,
+                  int caosdb_entity_property_set_string_list_value(caosdb_entity_property *property,
+                                                                   const char **value,
+                                                                   const int length),
+                  {
+                    auto *wrapped_property =
+                      static_cast<caosdb::entity::Property *>(property->wrapped_property);
+                    std::vector<std::string> value_list;
+                    for (int i = 0; i < length; i++) {
+                      value_list.push_back(std::string(value[i]));
+                    }
+                    wrapped_property->SetValue(value_list);
+                    return 0;
+                  })
 }
diff --git a/test/test_ccaosdb.cpp b/test/test_ccaosdb.cpp
index 2c45ef7bf3986c8461a9ffe0943e8d1ba1112621..22c59949d0b2e6356b45cf5c96e83d32e43116aa 100644
--- a/test/test_ccaosdb.cpp
+++ b/test/test_ccaosdb.cpp
@@ -97,22 +97,18 @@ TEST_F(test_ccaosdb, test_execute_transaction) {
 }
 
 TEST_F(test_ccaosdb, test_multi_retrieve) {
-  std::cout << "Entering test_multi_retrieve ..." << std::endl;
   caosdb_connection_connection connection;
   caosdb_connection_connection_manager_get_connection(&connection, "local-caosdb-admin");
 
-  std::cout << "Creating transaction" << std::endl;
   caosdb_transaction_transaction multi_transaction;
   caosdb_connection_connection_create_transaction(&connection, &multi_transaction);
 
   // We explicitely want to define a C-style array here, so we disable
   // linting
   const char *ids[] = {"id1", "id2", "id3"}; // NOLINT
-  std::cout << "Adding mutli retrieval ..." << std::endl;
   int return_code(caosdb_transaction_transaction_retrieve_by_ids(&multi_transaction, ids, 3));
   EXPECT_EQ(return_code, caosdb::StatusCode::GO_ON);
 
-  std::cout << "Deleting transaction ..." << std::endl;
   return_code = caosdb_transaction_delete_transaction(&multi_transaction);
   EXPECT_EQ(return_code, 0);
 }
@@ -151,33 +147,41 @@ TEST_F(test_ccaosdb, test_entity) {
   // the strings for the rest
   return_code = caosdb_entity_entity_set_name(&entity, "length");
   EXPECT_EQ(return_code, 0);
-  char out[255] = {"a"}; // NOLINT
-  return_code = caosdb_entity_entity_get_name(&entity, out);
+  char *out = nullptr; // NOLINT
+  return_code = caosdb_entity_entity_get_name(&entity, &out);
   EXPECT_EQ(return_code, 0);
   EXPECT_EQ(strcmp(out, "length"), 0);
 
-  // TODO(fspreck)
-  // caosdb_entity_entity_set_role(&entity, "Property");
-  // caosdb_entity_entity_get_role(&entity, out);
-  // EXPECT_EQ(strcmp(out, "Property"), 0);
+  // invalid role
+  return_code = caosdb_entity_entity_set_role(&entity, "Role does not exist");
+  EXPECT_EQ(return_code, caosdb::StatusCode::ENUM_MAPPING_ERROR);
+
+  caosdb_entity_entity_set_role(&entity, "PROPERTY");
+  caosdb_entity_entity_get_role(&entity, &out);
+  EXPECT_EQ(strcmp(out, "PROPERTY"), 0);
 
   caosdb_entity_entity_set_description(&entity, "The length of an object");
-  caosdb_entity_entity_get_description(&entity, out);
+  caosdb_entity_entity_get_description(&entity, &out);
   EXPECT_EQ(strcmp(out, "The length of an object"), 0);
 
-  // TODO(fspreck)
-  // caosdb_entity_entity_set_datatype(&entity, "DOUBLE");
-  // caosdb_entity_entity_get_datatype(&entity, out);
-  // EXPECT_EQ(strcmp(out, "DOUBLE"), 0);
+  caosdb_entity_entity_set_datatype(&entity, "DOUBLE", false, false);
+  bool is_list[] = {false}; // NOLINT
+  bool is_ref[] = {false};  // NOLINT
+  caosdb_entity_entity_get_datatype(&entity, &out, is_ref, is_list);
+  EXPECT_EQ(strcmp(out, "DOUBLE"), 0);
+  EXPECT_FALSE(*is_list);
+  EXPECT_FALSE(*is_ref);
 
   caosdb_entity_entity_set_unit(&entity, "m");
-  caosdb_entity_entity_get_unit(&entity, out);
+  caosdb_entity_entity_get_unit(&entity, &out);
   EXPECT_EQ(strcmp(out, "m"), 0);
 
-  // TODO(fspreck)
-  // caosdb_entity_entity_set_value(&entity, "5.0");
-  // caosdb_entity_entity_get_value(&entity, out);
-  // EXPECT_EQ(strcmp(out, "5.0"), 0);
+  return_code = caosdb_entity_entity_set_double_value(&entity, 5.0);
+  EXPECT_EQ(return_code, 0);
+  double value[] = {0.0}; // NOLINT
+  return_code = caosdb_entity_entity_get_double_value(&entity, value);
+  EXPECT_EQ(return_code, 0);
+  EXPECT_EQ(*value, 5.0);
 
   return_code = caosdb_entity_delete_entity(&entity);
   EXPECT_EQ(return_code, 0);
@@ -192,11 +196,11 @@ TEST_F(test_ccaosdb, test_parent) {
   caosdb_entity_parent_set_id(&parent, "some_id");
   caosdb_entity_parent_set_name(&parent, "some_name");
 
-  char out[255] = {"a"}; // NOLINT
-  caosdb_entity_parent_get_id(&parent, out);
+  char *out = nullptr; // NOLINT
+  caosdb_entity_parent_get_id(&parent, &out);
   EXPECT_EQ(strcmp(out, "some_id"), 0);
 
-  caosdb_entity_parent_get_name(&parent, out);
+  caosdb_entity_parent_get_name(&parent, &out);
   EXPECT_EQ(strcmp(out, "some_name"), 0);
 
   return_code = caosdb_entity_delete_parent(&parent);
@@ -211,42 +215,77 @@ TEST_F(test_ccaosdb, test_property) {
 
   caosdb_entity_property_set_id(&property, "some_id");
   caosdb_entity_property_set_name(&property, "some_name");
-  // TODO(fspreck)
-  // caosdb_entity_property_set_datatype(&property, "some_datatype");
-  // TODO(fspreck)
-  // caosdb_entity_property_set_importance(&property, "some_importance");
+
+  caosdb_entity_property_set_datatype(&property, "TEXT", false, false);
+  caosdb_entity_property_set_importance(&property, "FIX");
   caosdb_entity_property_set_unit(&property, "some_unit");
-  // TODO(fspreck)
-  // caosdb_entity_property_set_value(&property, "some_value");
+  caosdb_entity_property_set_string_value(&property, "some_value");
 
-  char out[255] = {"a"}; // NOLINT
-  caosdb_entity_property_get_id(&property, out);
+  char *out = nullptr; // NOLINT
+  caosdb_entity_property_get_id(&property, &out);
   EXPECT_EQ(strcmp(out, "some_id"), 0);
 
-  caosdb_entity_property_get_name(&property, out);
+  caosdb_entity_property_get_name(&property, &out);
   EXPECT_EQ(strcmp(out, "some_name"), 0);
 
-  // TODO(fspreck)
-  // caosdb_entity_property_get_datatype(&property, out);
-  // EXPECT_EQ(strcmp(out, "some_datatype"), 0);
+  bool is_ref[] = {false};  // NOLINT
+  bool is_list[] = {false}; // NOLINT
+  caosdb_entity_property_get_datatype(&property, &out, is_ref, is_list);
+  EXPECT_EQ(strcmp(out, "TEXT"), 0);
+  EXPECT_FALSE(*is_ref);
+  EXPECT_FALSE(*is_list);
 
-  // TODO(fspreck)
-  // caosdb_entity_property_get_importance(&property, out);
-  // EXPECT_EQ(strcmp(out, "some_importance"), 0);
+  caosdb_entity_property_get_importance(&property, &out);
+  EXPECT_EQ(strcmp(out, "FIX"), 0);
 
-  caosdb_entity_property_get_unit(&property, out);
+  caosdb_entity_property_get_unit(&property, &out);
   EXPECT_EQ(strcmp(out, "some_unit"), 0);
 
-  // TODO(fspreck)
-  // caosdb_entity_property_get_value(&property, out);
-  // EXPECT_EQ(strcmp(out, "some_value"), 0);
+  caosdb_entity_property_get_string_value(&property, &out);
+  EXPECT_EQ(strcmp(out, "some_value"), 0);
+
+  return_code = caosdb_entity_delete_property(&property);
+  EXPECT_EQ(return_code, 0);
+}
+
+TEST_F(test_ccaosdb, test_list_property) {
+
+  caosdb_entity_property property;
+  int return_code(caosdb_entity_create_property(&property));
+  EXPECT_EQ(return_code, 0);
+
+  return_code = caosdb_entity_property_set_datatype(&property, "TEXT", false, true);
+  EXPECT_EQ(return_code, 0);
+
+  const char *value_list[] = {"val0", "val1", "val2"}; // NOLINT
+  return_code = caosdb_entity_property_set_string_list_value(&property, value_list, 3);
+  EXPECT_EQ(return_code, 0);
+
+  char *out = nullptr;      // NOLINT
+  bool is_ref[] = {false};  // NOLINT
+  bool is_list[] = {false}; // NOLINT
+  return_code = caosdb_entity_property_get_datatype(&property, &out, is_ref, is_list);
+  EXPECT_EQ(return_code, 0);
+  EXPECT_EQ(strcmp(out, "TEXT"), 0);
+  EXPECT_FALSE(*is_ref);
+  EXPECT_TRUE(*is_list);
+
+  int length[] = {0}; // NOLINT
+  return_code = caosdb_entity_property_get_value_list_length(&property, length);
+  EXPECT_EQ(return_code, 0);
+  EXPECT_EQ(*length, 3);
+
+  for (int i = 0; i < *length; i++) {
+    return_code = caosdb_entity_property_get_string_list_value_at(&property, &out, i);
+    EXPECT_EQ(return_code, 0);
+    EXPECT_EQ(strcmp(value_list[i], out), 0); // NOLINT
+  }
 
   return_code = caosdb_entity_delete_property(&property);
   EXPECT_EQ(return_code, 0);
 }
 
 TEST_F(test_ccaosdb, test_entity_with_parent_and_property) {
-  std::cout << "Creating objects ... " << std::endl;
   caosdb_entity_parent input_parent;
   int return_code(caosdb_entity_create_parent(&input_parent));
   EXPECT_EQ(return_code, 0);
@@ -260,23 +299,20 @@ TEST_F(test_ccaosdb, test_entity_with_parent_and_property) {
 
   caosdb_entity_property_set_id(&input_property, "property_id");
   caosdb_entity_property_set_name(&input_property, "property_name");
-  // TODO(fspreck)
-  // caosdb_entity_property_set_datatype(&input_property, "property_datatype");
-  // TODO(fspreck)
-  // caosdb_entity_property_set_value(&input_property, "property_value");
+
+  caosdb_entity_property_set_datatype(&input_property, "TEXT", false, false);
+  caosdb_entity_property_set_string_value(&input_property, "property_value");
 
   caosdb_entity_entity entity;
   return_code = caosdb_entity_create_entity(&entity);
   EXPECT_EQ(return_code, 0);
 
-  std::cout << "Appending parent and property ..." << std::endl;
   return_code = caosdb_entity_entity_append_parent(&entity, &input_parent);
   EXPECT_EQ(return_code, 0);
 
   return_code = caosdb_entity_entity_append_property(&entity, &input_property);
   EXPECT_EQ(return_code, 0);
 
-  std::cout << "Counting parents and properties ..." << std::endl;
   int count[] = {0}; // NOLINT
   return_code = caosdb_entity_entity_get_parents_size(&entity, count);
   EXPECT_EQ(return_code, 0);
@@ -286,54 +322,51 @@ TEST_F(test_ccaosdb, test_entity_with_parent_and_property) {
   EXPECT_EQ(return_code, 0);
   EXPECT_EQ(*count, 1);
 
-  char in[255] = {"a"};  // NOLINT
-  char out[255] = {"b"}; // NOLINT
+  char *in = nullptr;  // NOLINT
+  char *out = nullptr; // NOLINT
 
-  std::cout << "Comparing ..." << std::endl;
   // cannot assign an already assigned property
   return_code = caosdb_entity_entity_get_property(&entity, &input_property, 0);
   EXPECT_EQ(return_code, caosdb::StatusCode::EXTERN_C_ASSIGNMENT_ERROR);
   caosdb_entity_property output_property;
   return_code = caosdb_entity_entity_get_property(&entity, &output_property, 0);
-  std::cout << "Got output property." << std::endl;
   EXPECT_EQ(return_code, 0);
 
-  caosdb_entity_property_get_id(&input_property, in);
-  std::cout << "Got input id." << std::endl;
-  caosdb_entity_property_get_id(&output_property, out);
-  std::cout << "Got output id." << std::endl;
+  caosdb_entity_property_get_id(&input_property, &in);
+  caosdb_entity_property_get_id(&output_property, &out);
   EXPECT_EQ(strcmp(in, out), 0);
 
-  caosdb_entity_property_get_name(&input_property, in);
-  caosdb_entity_property_get_name(&output_property, out);
+  caosdb_entity_property_get_name(&input_property, &in);
+  caosdb_entity_property_get_name(&output_property, &out);
   EXPECT_EQ(strcmp(in, out), 0);
 
-  // TODO(fspreck)
-  // caosdb_entity_property_get_datatype(&input_property, in);
-  // caosdb_entity_property_get_datatype(&output_property, out);
-  // EXPECT_EQ(strcmp(in, out), 0);
+  bool is_list[] = {false}; // NOLINT
+  bool is_ref[] = {false};  // NOLINT
+  caosdb_entity_property_get_datatype(&input_property, &in, is_ref, is_list);
+  EXPECT_FALSE(*is_list);
+  EXPECT_FALSE(*is_ref);
+  caosdb_entity_property_get_datatype(&output_property, &out, is_ref, is_list);
+  EXPECT_FALSE(*is_list);
+  EXPECT_FALSE(*is_ref);
+  EXPECT_EQ(strcmp(in, out), 0);
 
-  // TODO(fspreck)
-  // caosdb_entity_property_get_value(&input_property, in);
-  // caosdb_entity_property_get_value(&output_property, out);
-  // EXPECT_EQ(strcmp(in, out), 0);
+  caosdb_entity_property_get_string_value(&input_property, &in);
+  caosdb_entity_property_get_string_value(&output_property, &out);
+  EXPECT_EQ(strcmp(in, out), 0);
 
-  std::cout << "Comparing parent..." << std::endl;
   caosdb_entity_parent output_parent;
   return_code = caosdb_entity_entity_get_parent(&entity, &output_parent, 0);
-  std::cout << "Got output parent." << std::endl;
   EXPECT_EQ(return_code, 0);
 
-  caosdb_entity_parent_get_id(&input_parent, in);
-  caosdb_entity_parent_get_id(&output_parent, out);
+  caosdb_entity_parent_get_id(&input_parent, &in);
+  caosdb_entity_parent_get_id(&output_parent, &out);
   EXPECT_EQ(strcmp(in, out), 0);
 
-  caosdb_entity_parent_get_name(&input_parent, in);
-  caosdb_entity_parent_get_name(&output_parent, out);
+  caosdb_entity_parent_get_name(&input_parent, &in);
+  caosdb_entity_parent_get_name(&output_parent, &out);
   EXPECT_EQ(strcmp(in, out), 0);
 
   // Delete everything
-  std::cout << "Deleting ..." << std::endl;
   return_code = caosdb_entity_delete_parent(&input_parent);
   EXPECT_EQ(return_code, 0);
   return_code = caosdb_entity_delete_property(&input_property);
@@ -393,13 +426,13 @@ TEST_F(test_ccaosdb, test_remove_property) {
   return_code = caosdb_entity_entity_get_property(&entity, &out_prop, 0);
   EXPECT_EQ(return_code, 0);
 
-  char in[255] = {"a"};  // NOLINT
-  char out[255] = {"b"}; // NOLINT
+  char *in = nullptr;  // NOLINT
+  char *out = nullptr; // NOLINT
 
   // Deleted the first property, so the second one should remain.
-  return_code = caosdb_entity_property_get_name(&in_prop_2, in);
+  return_code = caosdb_entity_property_get_name(&in_prop_2, &in);
   EXPECT_EQ(return_code, 0);
-  return_code = caosdb_entity_property_get_name(&out_prop, out);
+  return_code = caosdb_entity_property_get_name(&out_prop, &out);
   EXPECT_EQ(return_code, 0);
 
   EXPECT_EQ(strcmp(in, out), 0);