diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 02c895db00b140cf0014c89bb3f33988884e6c8d..a54a23c5ad43ef851afeea2e31351a00ec2cadcc 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -107,6 +107,7 @@ trigger_inttest:
     # ... or use main if possible...
     - if [[ "$CI_COMMIT_REF_NAME" == "main" ]] ; then
         CPPINT_REF=main ;
+        F_BRANCH=main ;
       fi
     - if echo "$CI_COMMIT_REF_NAME" | grep -c "^v" ; then
         CPPINT_REF=main ;
diff --git a/include/caosdb/configuration.h b/include/caosdb/configuration.h
index 4910bee6954097797ccb755142c8a51aff62e641..bb6a1ff598be3df57ae24b21e5844cad6a9c0e71 100644
--- a/include/caosdb/configuration.h
+++ b/include/caosdb/configuration.h
@@ -237,7 +237,9 @@ private:
   ConnectionConfigurationHelper connection_configuration_helper;
   LoggingConfigurationHelper logging_configuration_helper;
 
-  inline ConfigurationManager() { InitializeDefaults(); };
+  inline ConfigurationManager(){
+    // InitializeDefaults();
+  };
 
   /**
    * Initialize this ConfigurationManager with the defaults.
diff --git a/include/caosdb/entity.h b/include/caosdb/entity.h
index dac3e73d363a161ea69b3610d3bd2301aa94da72..f18a0d904d1be282ec35b4842539850e3f31425b 100644
--- a/include/caosdb/entity.h
+++ b/include/caosdb/entity.h
@@ -60,6 +60,7 @@ using caosdb::StatusCode;
 using caosdb::entity::v1alpha1::EntityResponse;
 using caosdb::entity::v1alpha1::FileTransmissionId;
 using google::protobuf::RepeatedPtrField;
+using ProtoMessage = caosdb::entity::v1alpha1::Message;
 
 const std::string logger_name = "caosdb::entity";
 
@@ -102,13 +103,13 @@ private:
  */
 class Messages {
 public:
-  [[nodiscard]] inline auto Size() const -> int {
+  [[nodiscard]] inline auto size() const -> int {
     if (wrapped == nullptr) {
       return 0;
     }
     return wrapped->size();
   }
-  [[nodiscard]] inline auto At(int index) const -> const Message {
+  [[nodiscard]] inline auto at(int index) const -> const Message {
     if (wrapped == nullptr) {
       throw std::out_of_range("Number of messages: 0");
     }
@@ -135,8 +136,7 @@ private:
  */
 class Parent {
 public:
-  explicit inline Parent(caosdb::entity::v1alpha1::Parent *wrapped)
-    : wrapped(wrapped){};
+  explicit inline Parent(ProtoParent *wrapped) : wrapped(wrapped){};
   Parent();
 
   /**
@@ -220,7 +220,7 @@ private:
   /**
    * Message which serves as storage backend.
    */
-  mutable caosdb::entity::v1alpha1::Parent *wrapped;
+  mutable ProtoParent *wrapped;
   // Messages errors;
   // Messages warnings;
   // Messages infos;
@@ -238,11 +238,11 @@ public:
    *
    * That is also the number of parents the owning entity currently has.
    */
-  [[nodiscard]] inline auto Size() const -> int { return wrapped->size(); }
+  [[nodiscard]] inline auto size() const -> int { return wrapped->size(); }
   /**
    * Return the parent at the given index.
    */
-  [[nodiscard]] inline auto At(int index) const -> const Parent {
+  [[nodiscard]] inline auto at(int index) const -> const Parent {
     return Parent(&(wrapped->at(index)));
   }
 
@@ -257,7 +257,7 @@ private:
   /**
    * Append a parent.
    *
-   * This increases the Size() by one.
+   * This increases the size() by one.
    */
   auto Append(const Parent &parent) -> void;
   /**
@@ -275,8 +275,7 @@ private:
  */
 class Property {
 public:
-  explicit inline Property(caosdb::entity::v1alpha1::Property *wrapped)
-    : wrapped(wrapped){};
+  explicit inline Property(ProtoProperty *wrapped) : wrapped(wrapped){};
   Property();
 
   /**
@@ -321,6 +320,10 @@ public:
    * Set the name of this property.
    */
   auto SetName(const std::string &name) -> void;
+  /**
+   * Set the description of this property.
+   */
+  auto SetDescription(const std::string &description) -> void;
   /**
    * Set the importance of this property.
    */
@@ -358,7 +361,7 @@ public:
 private:
   static auto CreateProtoProperty() -> ProtoProperty *;
 
-  mutable caosdb::entity::v1alpha1::Property *wrapped;
+  mutable ProtoProperty *wrapped;
 };
 
 /**
@@ -373,11 +376,11 @@ public:
    *
    * This is also the number of properties the owningn entity currently has.
    */
-  [[nodiscard]] inline auto Size() const -> int { return wrapped->size(); }
+  [[nodiscard]] inline auto size() const -> int { return wrapped->size(); }
   /**
    * Return the property at the given index.
    */
-  [[nodiscard]] auto At(int index) const -> const Property {
+  [[nodiscard]] auto at(int index) const -> const Property {
     return Property(&(wrapped->at(index)));
   }
 
@@ -392,7 +395,7 @@ private:
   /**
    * Append a property
    *
-   * This increases the Size() by one.
+   * This increases the size() by one.
    */
   auto Append(const Property &property) -> void;
 
@@ -479,6 +482,10 @@ public:
 
   auto SetRole(const std::string &role) -> void;
   auto SetName(const std::string &name) -> void;
+  /**
+   * Set the description of this entity.
+   */
+  auto SetDescription(const std::string &description) -> void;
 
   auto SetValue(const std::string &value) -> void;
   auto SetUnit(const std::string &unit) -> void;
diff --git a/include/caosdb/logging.h b/include/caosdb/logging.h
index 2f04ec6087cfec19e1a5fbe87483544bd4e144a6..439eefd41ea0c90f263b095f1033270e3d546e7b 100644
--- a/include/caosdb/logging.h
+++ b/include/caosdb/logging.h
@@ -38,10 +38,10 @@ namespace caosdb::logging {
 
 const std::string logger_name = "caosdb::logging";
 
-typedef boost::log::sources::severity_channel_logger<int, std::string>
+typedef boost::log::sources::severity_channel_logger_mt<int, std::string>
   boost_logger_class;
 
-BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT(logger, boost_logger_class)
+BOOST_LOG_GLOBAL_LOGGER(logger, boost_logger_class)
 
 /**
  * This class stores the integer log level.
diff --git a/include/caosdb/transaction.h b/include/caosdb/transaction.h
index 9073b73752119fc29222589747d2cb65c1c54a74..b25cd41c3412109c887739d095c17a1c6746c1b8 100644
--- a/include/caosdb/transaction.h
+++ b/include/caosdb/transaction.h
@@ -176,8 +176,7 @@ using caosdb::entity::v1alpha1::MultiTransactionResponse;
 using caosdb::entity::v1alpha1::RegisterFileUploadRequest;
 using caosdb::entity::v1alpha1::RegisterFileUploadResponse;
 using caosdb::transaction::TransactionStatus;
-using WrappedResponseCase =
-  caosdb::entity::v1alpha1::TransactionResponse::WrappedResponseCase;
+using TransactionResponseCase = caosdb::entity::v1alpha1::TransactionResponse::TransactionResponseCase;
 
 class Transaction;
 
@@ -186,133 +185,62 @@ static const std::string logger_name = "caosdb::transaction";
 /**
  * Abstract base class for the results of a Transaction.
  */
-template <class T> class ResultSet {
+class ResultSet {
   class iterator;
 
 public:
   virtual ~ResultSet() = default;
-  [[nodiscard]] virtual auto Size() const noexcept -> int = 0;
-  [[nodiscard]] virtual auto At(const int index) const -> const T & = 0;
+  [[nodiscard]] virtual auto size() const noexcept -> int = 0;
+  [[nodiscard]] virtual auto at(const int index) const -> const Entity & = 0;
+  [[nodiscard]] virtual auto mutable_at(int index) const -> Entity * = 0;
   auto begin() const -> iterator;
   auto end() const -> iterator;
 
 private:
-  class iterator : public std::iterator<std::output_iterator_tag, T> {
+  class iterator : public std::iterator<std::output_iterator_tag, Entity> {
   public:
-    explicit iterator(const ResultSet<T> *result_set, int index = 0);
-    auto operator*() const -> const T &;
+    explicit iterator(const ResultSet *result_set, int index = 0);
+    auto operator*() const -> const Entity &;
     auto operator++() -> iterator &;
     auto operator++(int) -> iterator;
     auto operator!=(const iterator &rhs) const -> bool;
 
   private:
     int current_index = 0;
-    const ResultSet<T> *result_set;
+    const ResultSet *result_set;
   };
 };
 
-template <class T>
-ResultSet<T>::iterator::iterator(const ResultSet *result_set_param, int index)
-  : current_index(index), result_set(result_set_param) {}
-
-template <class T> auto ResultSet<T>::iterator::operator*() const -> const T & {
-  return this->result_set->At(current_index);
-}
-
-template <class T>
-auto ResultSet<T>::iterator::operator++() -> ResultSet<T>::iterator & {
-  current_index++;
-  return *this;
-}
-
-template <class T>
-auto ResultSet<T>::iterator::operator++(int) -> ResultSet<T>::iterator {
-  iterator tmp(*this);
-  operator++();
-  return tmp;
-}
-
-template <class T>
-auto ResultSet<T>::iterator::operator!=(const iterator &rhs) const -> bool {
-  return this->current_index != rhs.current_index;
-}
-
-template <class T> auto ResultSet<T>::begin() const -> ResultSet<T>::iterator {
-  return ResultSet<T>::iterator(this, 0);
-}
-
-template <class T> auto ResultSet<T>::end() const -> ResultSet<T>::iterator {
-  return ResultSet<T>::iterator(this, Size());
-}
-
-template <class T> class AbstractMultiResultSet : public ResultSet<T> {
+class AbstractMultiResultSet : public ResultSet {
 public:
   virtual ~AbstractMultiResultSet() = default;
   inline explicit AbstractMultiResultSet(
-    std::vector<std::unique_ptr<T>> result_set)
+    std::vector<std::unique_ptr<Entity>> result_set)
     : items(std::move(result_set)) {}
-  [[nodiscard]] inline auto Size() const noexcept -> int override {
+  [[nodiscard]] inline auto size() const noexcept -> int override {
     return this->items.size();
   }
-  [[nodiscard]] inline auto At(const int index) const -> const T & override {
+  [[nodiscard]] inline auto at(const int index) const
+    -> const Entity & override {
     return *(this->items.at(index));
   }
+  [[nodiscard]] inline auto mutable_at(int index) const -> Entity * override {
+    return this->items.at(index).get();
+  }
 
 protected:
-  std::vector<std::unique_ptr<T>> items;
-};
-
-/**
- * Container of files which have been downloaded during a transaction.
- */
-class FilesResultSet : public AbstractMultiResultSet<FileDescriptor> {
-public:
-  ~FilesResultSet() = default;
-  explicit FilesResultSet(
-    std::vector<std::unique_ptr<FileDescriptor>> result_set);
+  std::vector<std::unique_ptr<Entity>> items;
 };
 
 /**
  * Container with results of a transaction.
- *
- * In contrast to UniqueResult, this one can also hold multiple entities or zero
- * entities.
  */
-class MultiResultSet : public AbstractMultiResultSet<Entity> {
+class MultiResultSet : public AbstractMultiResultSet {
 public:
   ~MultiResultSet() = default;
   explicit MultiResultSet(std::vector<std::unique_ptr<Entity>> result_set);
 };
 
-/**
- * Container with the single result of a transaction.
- *
- * In contrast to MultiResultSet, this one guarantees to hold exactly one
- * entity.
- */
-class UniqueResult : public ResultSet<Entity> {
-public:
-  ~UniqueResult() = default;
-  explicit inline UniqueResult(EntityResponse *entityResponse)
-    : entity(new Entity(entityResponse)){};
-  explicit inline UniqueResult(IdResponse *idResponse)
-    : entity(new Entity(idResponse)){};
-  [[nodiscard]] auto GetEntity() const -> const Entity &;
-  [[nodiscard]] inline auto Size() const noexcept -> int override { return 1; }
-  [[nodiscard]] inline auto At(const int index) const
-    -> const Entity & override {
-    if (index != 0) {
-      throw std::out_of_range("Index out of range. Length is 1.");
-    }
-    return *(this->entity);
-  }
-
-  friend Transaction;
-
-private:
-  std::unique_ptr<Entity> entity;
-};
-
 /**
  * @brief Create a transaction via `CaosDBConnection.createTransaction()`
  */
@@ -350,13 +278,6 @@ public:
                                     const std::string &local_path) noexcept
     -> StatusCode;
 
-  /**
-   * Return a ResultSet<FileDescriptor>.
-   *
-   * The file result set is empty until the transaction terminates.
-   */
-  auto GetDownloadedFiles() const noexcept -> const FilesResultSet &;
-
   /**
    * Add an entity id to this transaction for retrieval.
    *
@@ -440,10 +361,8 @@ public:
     return this->status;
   }
 
-  [[nodiscard]] inline auto GetResultSet() const noexcept
-    -> const ResultSet<Entity> & {
-    const ResultSet<Entity> *result_set = this->result_set.get();
-    return *result_set;
+  [[nodiscard]] inline auto GetResultSet() const noexcept -> const ResultSet & {
+    return *(this->result_set.get());
   }
 
   /**
@@ -503,7 +422,7 @@ private:
                     const FileTransmissionId &file_transmission_id) -> void;
   bool has_query = false;
   TransactionType transaction_type = TransactionType::NONE;
-  mutable std::unique_ptr<ResultSet<Entity>> result_set;
+  mutable std::unique_ptr<ResultSet> result_set;
   mutable TransactionStatus status = TransactionStatus::INITIAL();
   std::shared_ptr<EntityTransactionService::Stub> entity_service;
   std::shared_ptr<FileTransmissionService::Stub> file_service;
diff --git a/proto b/proto
index ab5494165946c032325a2d37dec1d563ffc8a959..af178772ef43ded290168f33852ef3d85583b20a 160000
--- a/proto
+++ b/proto
@@ -1 +1 @@
-Subproject commit ab5494165946c032325a2d37dec1d563ffc8a959
+Subproject commit af178772ef43ded290168f33852ef3d85583b20a
diff --git a/src/caosdb/entity.cpp b/src/caosdb/entity.cpp
index ec84d669ee0a93c0b43d468fa0e4081d155b9bfc..d283305dedd408e8dedd8c3a9320803a3696e932 100644
--- a/src/caosdb/entity.cpp
+++ b/src/caosdb/entity.cpp
@@ -118,6 +118,10 @@ auto Property::SetName(const std::string &name) -> void {
   this->wrapped->set_name(name);
 }
 
+auto Property::SetDescription(const std::string &description) -> void {
+  this->wrapped->set_description(description);
+}
+
 auto Property::SetImportance(const std::string &importance) -> void {
   this->wrapped->set_importance(importance);
 }
@@ -194,6 +198,10 @@ auto Entity::SetName(const std::string &name) -> void {
   this->wrapped->set_name(name);
 }
 
+auto Entity::SetDescription(const std::string &description) -> void {
+  this->wrapped->set_description(description);
+}
+
 auto Entity::SetValue(const std::string &value) -> void {
   this->wrapped->set_value(value);
 }
diff --git a/src/caosdb/logging.cpp b/src/caosdb/logging.cpp
index 3be4d38ac9a882f59a0b803c818c276d326ab504..5e6cd4e3577b57ec7491a26ae71982667a096609 100644
--- a/src/caosdb/logging.cpp
+++ b/src/caosdb/logging.cpp
@@ -44,6 +44,10 @@
 
 namespace caosdb::logging {
 
+BOOST_LOG_GLOBAL_LOGGER_INIT(logger, boost_logger_class) {
+  boost_logger_class lg;
+  return lg;
+}
 LoggingConfiguration::LoggingConfiguration(int level)
   : LevelConfiguration(level) {}
 
diff --git a/src/caosdb/transaction.cpp b/src/caosdb/transaction.cpp
index 8122b130fc94078f76a81876fbbcae4e4fc38f58..06fc46af3019eb406db16d6f7e82e415541c8122 100644
--- a/src/caosdb/transaction.cpp
+++ b/src/caosdb/transaction.cpp
@@ -113,9 +113,9 @@ using caosdb::entity::v1alpha1::FileTransmissionService;
 using caosdb::entity::v1alpha1::MultiTransactionRequest;
 using caosdb::entity::v1alpha1::MultiTransactionResponse;
 using TransactionResponseCase =
-  caosdb::entity::v1alpha1::TransactionResponse::WrappedResponseCase;
-using QueryResponseCase =
-  caosdb::entity::v1alpha1::RetrieveResponse::WrappedResponseCase;
+  caosdb::entity::v1alpha1::TransactionResponse::TransactionResponseCase;
+using RetrieveResponseCase =
+  caosdb::entity::v1alpha1::RetrieveResponse::RetrieveResponseCase;
 using caosdb::utility::get_arena;
 using grpc::ClientAsyncResponseReader;
 using ProtoEntity = caosdb::entity::v1alpha1::Entity;
@@ -123,14 +123,39 @@ using FileExchange::FileExchangeClient;
 using google::protobuf::Arena;
 using grpc::CompletionQueue;
 
-MultiResultSet::MultiResultSet(std::vector<std::unique_ptr<Entity>> result_set)
-  : AbstractMultiResultSet<Entity>(std::move(result_set)) {}
+ResultSet::iterator::iterator(const ResultSet *result_set_param, int index)
+  : current_index(index), result_set(result_set_param) {}
+
+auto ResultSet::iterator::operator*() const -> const Entity & {
+  return this->result_set->at(current_index);
+}
+
+auto ResultSet::iterator::operator++() -> ResultSet::iterator & {
+  current_index++;
+  return *this;
+}
+
+auto ResultSet::iterator::operator++(int) -> ResultSet::iterator {
+  iterator tmp(*this);
+  operator++();
+  return tmp;
+}
+
+auto ResultSet::iterator::operator!=(const iterator &rhs) const -> bool {
+  return this->current_index != rhs.current_index;
+}
+
+auto ResultSet::begin() const -> ResultSet::iterator {
+  return ResultSet::iterator(this, 0);
+}
 
-[[nodiscard]] auto UniqueResult::GetEntity() const -> const Entity & {
-  const Entity *result = this->entity.get();
-  return *result;
+auto ResultSet::end() const -> ResultSet::iterator {
+  return ResultSet::iterator(this, size());
 }
 
+MultiResultSet::MultiResultSet(std::vector<std::unique_ptr<Entity>> result_set)
+  : AbstractMultiResultSet(std::move(result_set)) {}
+
 Transaction::Transaction(
   std::shared_ptr<EntityTransactionService::Stub> entity_service,
   std::shared_ptr<FileTransmissionService::Stub> file_service)
@@ -324,7 +349,7 @@ auto Transaction::ExecuteAsynchronously() noexcept -> StatusCode {
   if (status.GetCode() == StatusCode::SUCCESS && !download_files.empty()) {
     // run over all retrieved entities and get the download_id
     for (auto sub_response : *(response->mutable_responses())) {
-      if (sub_response.wrapped_response_case() ==
+      if (sub_response.transaction_response_case() ==
           TransactionResponseCase::kRetrieveResponse) {
         if (sub_response.retrieve_response()
               .entity_response()
@@ -366,112 +391,201 @@ auto Transaction::ExecuteAsynchronously() noexcept -> StatusCode {
 }
 
 auto Transaction::WaitForIt() const noexcept -> TransactionStatus {
-  if (this->response->responses_size() == 1) {
-    auto *responses = this->response->mutable_responses(0);
-    switch (responses->wrapped_response_case()) {
-    case WrappedResponseCase::kRetrieveResponse: {
-      auto *retrieve_response = responses->mutable_retrieve_response();
-      switch (retrieve_response->wrapped_response_case()) {
-      case QueryResponseCase::kEntityResponse: {
-        auto *entity = retrieve_response->release_entity_response();
-        auto id = entity->entity().id();
-        if (!entity->errors().empty()) {
-          this->status = TransactionStatus::TRANSACTION_ERROR(
-            "The request returned with errors.");
-        }
-
-        this->result_set = std::make_unique<UniqueResult>(entity);
-        if (!id.empty() && download_files.count(id) == 1) {
-          const auto &local_path = download_files.at(id).local_path;
-          const auto &unique_result_set =
-            dynamic_cast<const UniqueResult &>(*result_set);
-          unique_result_set.entity->SetLocalPath(local_path);
-        }
+  // if (this->response->responses_size() == 1) {
+  // auto *responses = this->response->mutable_responses(0);
+  // switch (responses->wrapped_response_case()) {
+  // case WrappedResponseCase::kRetrieveResponse: {
+  // auto *retrieve_response = responses->mutable_retrieve_response();
+  // switch (retrieve_response->query_response_case()) {
+  // case QueryResponseCase::kEntity: {
+  // auto *entity = retrieve_response->release_entity();
+  // if (!entity->errors().empty()) {
+  // this->status = TransactionStatus::TRANSACTION_ERROR(
+  //"The request returned with errors.");
+  //}
+  // this->result_set = std::make_unique<UniqueResult>(entity);
+  //} break;
+  // case QueryResponseCase::kSelectResult: {
+  //// TODO(tf) Select queries
+  //} break;
+  // case QueryResponseCase::kCountResult: {
+  // this->query_count = retrieve_response->count_result();
+  // std::vector<std::unique_ptr<Entity>> entities;
+  // this->result_set =
+  // std::make_unique<MultiResultSet>(std::move(entities));
+  //} break;
+  // default:
+  //// TODO(tf) Error
+  // break;
+  //}
+  //} break;
+  // case WrappedResponseCase::kUpdateResponse: {
+  // auto *updatedIdResponse = responses->mutable_update_response();
+  // if (!updatedIdResponse->entity_errors().empty()) {
+  // this->status = TransactionStatus::TRANSACTION_ERROR(
+  //"The request returned with errors.");
+  //}
+  // this->result_set = std::make_unique<UniqueResult>(updatedIdResponse);
+  //} break;
+  // case WrappedResponseCase::kInsertResponse: {
+  // auto *insertedIdResponse = responses->mutable_insert_response();
+  // if (!insertedIdResponse->entity_errors().empty()) {
+  // this->status = TransactionStatus::TRANSACTION_ERROR(
+  //"The request returned with errors.");
+  //}
+  // this->result_set = std::make_unique<UniqueResult>(insertedIdResponse);
+  //} break;
+  // default:
+  //// TODO(tf) Error and Update
+  // break;
+  //}
+  //} else {
+  bool set_error = false;
+  auto *responses = this->response->mutable_responses();
+  std::vector<std::unique_ptr<Entity>> entities;
+  for (auto &sub_response : *responses) {
+    std::unique_ptr<Entity> result;
+    switch (sub_response.transaction_response_case()) {
+
+    case TransactionResponseCase::kRetrieveResponse: {
+      auto *retrieve_response = sub_response.mutable_retrieve_response();
+
+      switch (retrieve_response->retrieve_response_case()) {
+      case RetrieveResponseCase::kEntityResponse: {
+        auto *retrieve_entity_response = retrieve_response->release_entity_response();
+        result = std::make_unique<Entity>(retrieve_entity_response);
       } break;
-      case QueryResponseCase::kSelectResult: {
+      case RetrieveResponseCase::kSelectResult: {
         CAOSDB_LOG_ERROR(logger_name) << "Results of a SELECT query cannot be "
                                          "processed by this client yet.";
         // TODO(tf) Select queries
       } break;
-      case QueryResponseCase::kCountResult: {
+      case RetrieveResponseCase::kCountResult: {
         this->query_count = retrieve_response->count_result();
-        std::vector<std::unique_ptr<Entity>> entities;
-        this->result_set =
-          std::make_unique<MultiResultSet>(std::move(entities));
       } break;
+      case RetrieveResponseCase::kFindResult: {
+        for (auto &entity_response : *retrieve_response->mutable_find_result()->mutable_result_set()) {
+          result = std::make_unique<Entity>(&entity_response);
+          if (result->HasErrors()) {
+            set_error = true;
+          }
+          entities.push_back(std::move(result));
+        }
+                                              } break;
       default:
         CAOSDB_LOG_FATAL(logger_name) << "Received invalid QueryResponseCase.";
         break;
       }
-    } break;
-    case WrappedResponseCase::kUpdateResponse: {
-      auto *updatedIdResponse = responses->mutable_update_response();
-      if (!updatedIdResponse->id_response().errors().empty()) {
-        this->status = TransactionStatus::TRANSACTION_ERROR(
-          "The request returned with errors.");
-      }
-      this->result_set = std::make_unique<UniqueResult>(
-        updatedIdResponse->release_id_response());
-    } break;
-    case WrappedResponseCase::kInsertResponse: {
-      auto *insertedIdResponse = responses->mutable_insert_response();
-      if (!insertedIdResponse->id_response().errors().empty()) {
-        this->status = TransactionStatus::TRANSACTION_ERROR(
-          "The request returned with errors.");
-      }
-      this->result_set = std::make_unique<UniqueResult>(
-        insertedIdResponse->release_id_response());
-    } break;
-    case WrappedResponseCase::kDeleteResponse: {
-      auto *deletedIdResponse = responses->mutable_delete_response();
-      if (!deletedIdResponse->id_response().errors().empty()) {
-        this->status = TransactionStatus::TRANSACTION_ERROR(
-          "The request returned with errors.");
-      }
-      this->result_set = std::make_unique<UniqueResult>(
-        deletedIdResponse->release_id_response());
-    } break;
+      //<<<<<<< HEAD
+      //} break;
+      // case WrappedResponseCase::kUpdateResponse: {
+      // auto *updatedIdResponse = responses->mutable_update_response();
+      // if (!updatedIdResponse->id_response().errors().empty()) {
+      // this->status = TransactionStatus::TRANSACTION_ERROR(
+      //"The request returned with errors.");
+      //}
+      // this->result_set = std::make_unique<UniqueResult>(
+      // updatedIdResponse->release_id_response());
+      //} break;
+      // case WrappedResponseCase::kInsertResponse: {
+      // auto *insertedIdResponse = responses->mutable_insert_response();
+      // if (!insertedIdResponse->id_response().errors().empty()) {
+      // this->status = TransactionStatus::TRANSACTION_ERROR(
+      //"The request returned with errors.");
+      //}
+      // this->result_set = std::make_unique<UniqueResult>(
+      // insertedIdResponse->release_id_response());
+      //} break;
+      // case WrappedResponseCase::kDeleteResponse: {
+      // auto *deletedIdResponse = responses->mutable_delete_response();
+      // if (!deletedIdResponse->id_response().errors().empty()) {
+      // this->status = TransactionStatus::TRANSACTION_ERROR(
+      //"The request returned with errors.");
+      //}
+      // this->result_set = std::make_unique<UniqueResult>(
+      // deletedIdResponse->release_id_response());
+      //} break;
+      // default:
+      // CAOSDB_LOG_FATAL(logger_name) << "Received invalid
+      // WrappedResponseCase."; break;
+      //}
+      //} else {
+      // auto *responses = this->response->mutable_responses();
+      // std::vector<std::unique_ptr<Entity>> entities;
+      // CAOSDB_LOG_DEBUG(logger_name)
+      //<< "Number of subresponses: " << responses->size();
+      // for (auto sub_response : *responses) {
+      // switch (sub_response.wrapped_response_case()) {
+      // case TransactionResponseCase::kRetrieveResponse:
+      // entities.push_back(std::make_unique<Entity>(
+      // sub_response.mutable_retrieve_response()->release_entity_response()));
+      // break;
+      // case TransactionResponseCase::kInsertResponse:
+      // entities.push_back(std::make_unique<Entity>(
+      // sub_response.mutable_insert_response()->release_id_response()));
+      // break;
+      // case TransactionResponseCase::kDeleteResponse:
+      // entities.push_back(std::make_unique<Entity>(
+      // sub_response.mutable_delete_response()->release_id_response()));
+      // break;
+      // case TransactionResponseCase::kUpdateResponse:
+      // entities.push_back(std::make_unique<Entity>(
+      // sub_response.mutable_update_response()->release_id_response()));
+      // break;
+      // default:
+      // CAOSDB_LOG_FATAL(logger_name)
+      //<< "Received invalid TransactionResponseCase.";
+      // break;
+      //}
+      //}
+      // this->result_set =
+      // std::make_unique<MultiResultSet>(std::move(entities));
+      //=======
+
+      break;
+    }
+
+    case TransactionResponseCase::kInsertResponse: {
+      auto *inserted_id_response = sub_response.mutable_insert_response()->release_id_response();
+      result = std::make_unique<Entity>(inserted_id_response);
+      break;
+    }
+    case TransactionResponseCase::kDeleteResponse: {
+      auto *deleted_id_response = sub_response.mutable_delete_response()->release_id_response();
+      result = std::make_unique<Entity>(deleted_id_response);
+      break;
+    }
+    case TransactionResponseCase::kUpdateResponse: {
+      auto *updated_id_response = sub_response.mutable_update_response()->release_id_response();
+      result = std::make_unique<Entity>(updated_id_response);
+      break;
+    }
     default:
-      CAOSDB_LOG_FATAL(logger_name) << "Received invalid WrappedResponseCase.";
+      CAOSDB_LOG_FATAL(logger_name)
+        << "Received invalid TransactionResponseCase.";
       break;
     }
-  } else {
-    auto *responses = this->response->mutable_responses();
-    std::vector<std::unique_ptr<Entity>> entities;
-    CAOSDB_LOG_DEBUG(logger_name)
-      << "Number of subresponses: " << responses->size();
-    for (auto sub_response : *responses) {
-      switch (sub_response.wrapped_response_case()) {
-      case TransactionResponseCase::kRetrieveResponse:
-        entities.push_back(std::make_unique<Entity>(
-          sub_response.mutable_retrieve_response()->release_entity_response()));
-        break;
-      case TransactionResponseCase::kInsertResponse:
-        entities.push_back(std::make_unique<Entity>(
-          sub_response.mutable_insert_response()->release_id_response()));
-        break;
-      case TransactionResponseCase::kDeleteResponse:
-        entities.push_back(std::make_unique<Entity>(
-          sub_response.mutable_delete_response()->release_id_response()));
-        break;
-      case TransactionResponseCase::kUpdateResponse:
-        entities.push_back(std::make_unique<Entity>(
-          sub_response.mutable_update_response()->release_id_response()));
-        break;
-      default:
-        CAOSDB_LOG_FATAL(logger_name)
-          << "Received invalid TransactionResponseCase.";
-        break;
+    if(result != nullptr) {
+      if (result->HasErrors()) {
+        set_error = true;
       }
+      entities.push_back(std::move(result));
     }
-    for (auto &entity : entities) {
-      auto id = entity->GetId();
-      if (!id.empty() && download_files.count(id) == 1) {
-        const auto &local_path = download_files.at(id).local_path;
-        entity->SetLocalPath(local_path);
-      }
+  }
+
+  // copy local path of downloaded files into the entities file descriptor
+  for (auto &entity : entities) {
+    auto id = entity->GetId();
+    if (!id.empty() && download_files.count(id) == 1) {
+      const auto &local_path = download_files.at(id).local_path;
+      entity->SetLocalPath(local_path);
     }
-    this->result_set = std::make_unique<MultiResultSet>(std::move(entities));
+  }
+  this->result_set = std::make_unique<MultiResultSet>(std::move(entities));
+
+  if (set_error) {
+    this->status = TransactionStatus::TRANSACTION_ERROR(
+      "The request terminated with errors.");
   }
 
   return this->status;
diff --git a/test/test_entity.cpp b/test/test_entity.cpp
index 7930ab52d242a19f1833e77aedaabf34c56608c8..6ff700414d79095cc2f2909f1646f2bbf81eae60 100644
--- a/test/test_entity.cpp
+++ b/test/test_entity.cpp
@@ -38,6 +38,7 @@
 namespace caosdb::entity {
 using caosdb::entity::v1alpha1::IdResponse;
 using ProtoEntity = caosdb::entity::v1alpha1::Entity;
+using ProtoParent = caosdb::entity::v1alpha1::Parent;
 using caosdb::utility::get_arena;
 
 TEST(test_entity, test_parent_setters) {
@@ -54,11 +55,11 @@ TEST(test_entity, test_append_parent) {
   parent.SetId("some-id");
 
   auto entity = Entity();
-  EXPECT_EQ(entity.GetParents().Size(), 0);
+  EXPECT_EQ(entity.GetParents().size(), 0);
   entity.AppendParent(parent);
-  EXPECT_EQ(entity.GetParents().Size(), 1);
+  EXPECT_EQ(entity.GetParents().size(), 1);
 
-  auto same_parent = entity.GetParents().At(0);
+  auto same_parent = entity.GetParents().at(0);
   EXPECT_EQ(same_parent.GetId(), "some-id");
 }
 
@@ -90,11 +91,11 @@ TEST(test_entity, test_append_property) {
   prop.SetUnit("prop_unit");
   prop.SetDatatype("prop_dtype");
 
-  EXPECT_EQ(entity.GetProperties().Size(), 0);
+  EXPECT_EQ(entity.GetProperties().size(), 0);
   entity.AppendProperty(prop);
-  EXPECT_EQ(entity.GetProperties().Size(), 1);
+  EXPECT_EQ(entity.GetProperties().size(), 1);
 
-  auto same_prop = entity.GetProperties().At(0);
+  auto same_prop = entity.GetProperties().at(0);
 
   EXPECT_EQ(prop.GetName(), same_prop.GetName());
   EXPECT_EQ(prop.GetId(), same_prop.GetId());
@@ -128,10 +129,10 @@ TEST(test_entity, test_copy_to) {
 
   EXPECT_EQ(entity.GetRole(), copied.GetRole());
   EXPECT_EQ(entity.GetName(), copied.GetName());
-  EXPECT_EQ(copied.GetParents().At(0).GetId(), parent.GetId());
-  EXPECT_EQ(copied.GetParents().At(0).GetName(), parent.GetName());
-  EXPECT_EQ(copied.GetProperties().At(0).GetId(), prop.GetId());
-  EXPECT_EQ(copied.GetProperties().At(0).GetName(), prop.GetName());
+  EXPECT_EQ(copied.GetParents().at(0).GetId(), parent.GetId());
+  EXPECT_EQ(copied.GetParents().at(0).GetName(), parent.GetName());
+  EXPECT_EQ(copied.GetProperties().at(0).GetId(), prop.GetId());
+  EXPECT_EQ(copied.GetProperties().at(0).GetName(), prop.GetName());
 }
 
 TEST(test_entity, test_insert_entity) {
@@ -192,8 +193,8 @@ TEST(test_entity, test_insert_with_parent) {
   transaction.InsertEntity(&entity);
 
   EXPECT_EQ(entity.GetName(), "entity_name");
-  EXPECT_EQ(entity.GetParents().Size(), 1);
-  auto inserted_parent = entity.GetParents().At(0);
+  EXPECT_EQ(entity.GetParents().size(), 1);
+  auto inserted_parent = entity.GetParents().at(0);
   EXPECT_EQ(inserted_parent.GetId(), parent.GetId());
   EXPECT_EQ(inserted_parent.GetName(), parent.GetName());
 }
@@ -218,9 +219,9 @@ TEST(test_entity, test_insert_with_property) {
 
   transaction.InsertEntity(&entity);
 
-  EXPECT_EQ(entity.GetProperties().Size(), 1);
+  EXPECT_EQ(entity.GetProperties().size(), 1);
 
-  auto inserted_prop = entity.GetProperties().At(0);
+  auto inserted_prop = entity.GetProperties().at(0);
 
   EXPECT_EQ(prop.GetName(), inserted_prop.GetName());
   EXPECT_EQ(prop.GetId(), inserted_prop.GetId());
@@ -241,9 +242,9 @@ TEST(test_entity, test_from_id_response) {
 
   EXPECT_EQ(entity.GetId(), "entity_id");
   EXPECT_TRUE(entity.HasErrors());
-  EXPECT_EQ(entity.GetErrors().Size(), 1);
-  EXPECT_EQ(entity.GetErrors().At(0).GetDescription(), "error_desc");
-  EXPECT_EQ(entity.GetErrors().At(0).GetCode(),
+  EXPECT_EQ(entity.GetErrors().size(), 1);
+  EXPECT_EQ(entity.GetErrors().at(0).GetDescription(), "error_desc");
+  EXPECT_EQ(entity.GetErrors().at(0).GetCode(),
             MessageCode::ENTITY_DOES_NOT_EXIST);
 
   IdResponse idr_warnings_and_infos;
@@ -258,14 +259,14 @@ TEST(test_entity, test_from_id_response) {
   Entity other_ent(&idr_warnings_and_infos);
 
   EXPECT_EQ(other_ent.GetId(), "other_entity_id");
-  EXPECT_EQ(other_ent.GetWarnings().Size(), 1);
+  EXPECT_EQ(other_ent.GetWarnings().size(), 1);
   EXPECT_TRUE(other_ent.HasWarnings());
-  EXPECT_EQ(other_ent.GetWarnings().At(0).GetDescription(), "warning_desc");
-  EXPECT_EQ(other_ent.GetWarnings().At(0).GetCode(),
+  EXPECT_EQ(other_ent.GetWarnings().at(0).GetDescription(), "warning_desc");
+  EXPECT_EQ(other_ent.GetWarnings().at(0).GetCode(),
             MessageCode::ENTITY_HAS_NO_PROPERTIES);
-  EXPECT_EQ(other_ent.GetInfos().Size(), 1);
-  EXPECT_EQ(other_ent.GetInfos().At(0).GetDescription(), "info_desc");
-  EXPECT_EQ(other_ent.GetInfos().At(0).GetCode(), MessageCode::UNSPECIFIED);
+  EXPECT_EQ(other_ent.GetInfos().size(), 1);
+  EXPECT_EQ(other_ent.GetInfos().at(0).GetDescription(), "info_desc");
+  EXPECT_EQ(other_ent.GetInfos().at(0).GetCode(), MessageCode::UNSPECIFIED);
 }
 
 TEST(test_entity, test_add_file_to_non_file_entity) {
@@ -286,6 +287,27 @@ TEST(test_entity, test_add_directory_path) {
   EXPECT_EQ(entity.SetLocalPath("./"), StatusCode::PATH_IS_A_DIRECTORY);
 }
 
+TEST(test_entity, test_description) {
+  Entity entity;
+  Property property;
+  Parent parent;
+
+  EXPECT_EQ(entity.GetDescription(), "");
+  EXPECT_EQ(property.GetDescription(), "");
+  EXPECT_EQ(parent.GetDescription(), "");
+
+  entity.SetDescription("desc entity");
+  property.SetDescription("desc property");
+  // Parent has not setter
+  ProtoParent protoParent;
+  protoParent.set_description("desc parent");
+  parent = Parent(&protoParent);
+
+  EXPECT_EQ(entity.GetDescription(), "desc entity");
+  EXPECT_EQ(property.GetDescription(), "desc property");
+  EXPECT_EQ(parent.GetDescription(), "desc parent");
+}
+
 TEST(test_entity, test_add_file) {
   Entity entity;
   entity.SetRole("File");
diff --git a/test/test_transaction.cpp b/test/test_transaction.cpp
index ff64f3d256014554f685b4fa7dc492662da237a8..abecb1a2a25df106b015d644a4d09833df19a688 100644
--- a/test/test_transaction.cpp
+++ b/test/test_transaction.cpp
@@ -23,7 +23,7 @@
 #include "caosdb/entity/v1alpha1/main.pb.h" // for Entity
 #include "caosdb/exceptions.h"              // for ConnectionError
 #include "caosdb/status_code.h"
-#include "caosdb/transaction.h"        // for Transaction, UniqueResult
+#include "caosdb/transaction.h"        // for Transaction
 #include "caosdb/transaction_status.h" // for ConnectionError
 #include "caosdb_test_utility.h"       // for EXPECT_THROW_MESSAGE
 #include "gtest/gtest-message.h"       // for Message
@@ -37,11 +37,32 @@
 namespace caosdb::transaction {
 using caosdb::configuration::InsecureConnectionConfiguration;
 using caosdb::connection::Connection;
+using caosdb::entity::Entity;
 using caosdb::exceptions::ConnectionError;
-using caosdb::transaction::UniqueResult;
 using ProtoEntity = caosdb::entity::v1alpha1::Entity;
 using caosdb::entity::v1alpha1::RetrieveResponse;
 
+TEST(test_transaction, test_multi_result_set) {
+  std::vector<std::unique_ptr<Entity>> entities;
+  for (int i = 0; i < 5; i++) {
+    entities.push_back(std::make_unique<Entity>());
+    entities[i]->SetName("E" + std::to_string(i));
+  }
+  MultiResultSet result_set(std::move(entities));
+
+  EXPECT_EQ(result_set.size(), 5);
+  EXPECT_EQ(result_set.mutable_at(3)->GetName(), "E3");
+  EXPECT_EQ(result_set.at(4).GetName(), "E4");
+  EXPECT_EQ(result_set.at(4).GetName(), "E4");
+  EXPECT_THROW(auto &e = result_set.at(15), std::out_of_range);
+
+  int counter = 0;
+  for (const auto &entity : result_set) {
+    EXPECT_EQ(entity.GetName(), "E" + std::to_string(counter++));
+  }
+  EXPECT_EQ(counter, 5);
+}
+
 TEST(test_transaction, create_transaction) {
   const auto *host = "localhost";
   auto configuration = InsecureConnectionConfiguration(host, 8000);
@@ -55,18 +76,6 @@ TEST(test_transaction, create_transaction) {
     "connection to the server could not be established.");
 }
 
-TEST(test_transaction, unique_result) {
-  auto *entity_response = new EntityResponse;
-  entity_response->mutable_entity()->set_id("test");
-  UniqueResult result(entity_response);
-
-  EXPECT_EQ("test", result.GetEntity().GetId());
-
-  // DON'T DELETE! The caosdb::entity::Entity takes care of that
-  // Try it yourself:
-  // delete entity;
-}
-
 TEST(test_transaction, test_unavailable) {
   const auto *host = "localhost";
   auto configuration = InsecureConnectionConfiguration(host, 8000);
@@ -96,7 +105,7 @@ TEST(test_transaction, test_retrieve_by_ids) {
 TEST(test_transaction, test_multi_result_set_empty) {
   std::vector<std::unique_ptr<Entity>> empty;
   MultiResultSet rs(std::move(empty));
-  EXPECT_EQ(rs.Size(), 0);
+  EXPECT_EQ(rs.size(), 0);
 }
 
 TEST(test_transaction, test_multi_result_iterator) {
@@ -107,19 +116,8 @@ TEST(test_transaction, test_multi_result_iterator) {
     std::make_unique<Entity>(response.release_entity_response()));
 
   MultiResultSet rs(std::move(one_elem));
-  EXPECT_EQ(rs.Size(), 1);
-
-  for (const Entity &entity : rs) {
-    EXPECT_EQ(entity.GetId(), "100");
-  }
-}
-
-TEST(test_transaction, test_unique_result_iterator) {
-  caosdb::entity::v1alpha1::EntityResponse response;
-  response.mutable_entity()->set_id("100");
+  EXPECT_EQ(rs.size(), 1);
 
-  UniqueResult rs(&response);
-  EXPECT_EQ(rs.Size(), 1);
   for (const Entity &entity : rs) {
     EXPECT_EQ(entity.GetId(), "100");
   }
@@ -133,8 +131,8 @@ TEST(test_transaction, test_multi_result_set_one) {
     std::make_unique<Entity>(response.release_entity_response()));
 
   MultiResultSet rs(std::move(one_elem));
-  EXPECT_EQ(rs.Size(), 1);
-  EXPECT_EQ(rs.At(0).GetId(), "100");
+  EXPECT_EQ(rs.size(), 1);
+  EXPECT_EQ(rs.at(0).GetId(), "100");
 }
 
 TEST(test_transaction, test_multi_result_set_three) {
@@ -165,8 +163,8 @@ TEST(test_transaction, test_multi_result_set_three) {
   }
 
   MultiResultSet rs(std::move(three_elem));
-  EXPECT_EQ(rs.Size(), 3);
-  EXPECT_TRUE(rs.At(1).HasErrors());
+  EXPECT_EQ(rs.size(), 3);
+  EXPECT_TRUE(rs.at(1).HasErrors());
 }
 
 TEST(test_transaction, test_update_entity) {