diff --git a/CMakeLists.txt b/CMakeLists.txt
index d4df94cd21b14c07cd84e554d12c99b0177d8fb0..7ee6d193f6814d1d24eb8cb35e3658a87d00e601 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -323,7 +323,7 @@ if(_LINTING)
     else()
         message(STATUS "clang-tidy: ${clang_tidy}")
         set(_CMAKE_CXX_CLANG_TIDY_CHECKS
-            "--checks=*,-fuchsia-*,-llvmlibc-*,-readability-convert-member-functions-to-static,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-hicpp-no-array-decay,-llvm-else-after-return,-readability-else-after-return,-modernize-use-trailing-return-type,-bugprone-branch-clone")
+            "--checks=*,-fuchsia-*,-llvmlibc-*,-readability-convert-member-functions-to-static,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-hicpp-no-array-decay,-llvm-else-after-return,-readability-else-after-return,-modernize-use-trailing-return-type,-bugprone-branch-clone,-altera-*")
         set(_CMAKE_C_CLANG_TIDY_CHECKS "${_CMAKE_CXX_CLANG_TIDY_CHECKS}")
         set(_CMAKE_CXX_CLANG_TIDY "${clang_tidy}"
             "--header-filter=caosdb/.*[^\(\.pb\.h\)]$"
diff --git a/conanfile.py b/conanfile.py
index f399a6445ef3a8f396ae08fc85fe3688fd80f5cc..a773f501212cb23d3649aae31c644bd66a259516 100644
--- a/conanfile.py
+++ b/conanfile.py
@@ -14,10 +14,10 @@ class CaosdbConan(ConanFile):
     default_options = {"shared": False, "fPIC": True}
     generators = "cmake"
     requires = [
-        ("boost/1.77.0"),
         ("grpc/1.39.1"),
     ]
     build_requires = [
+        ("boost/1.77.0"),
         ("gtest/1.11.0"),
     ]
     exports = ("*.cmake", "*CMakeLists.txt", "*.in",
diff --git a/doc/CHANGELOG.md b/doc/CHANGELOG.md
index 7e3d84f6ec43faa429e8a1e9fea8de1182c900c8..fd3083fe290b51f78c12838c94bb3cf5b7a5a066 100644
--- a/doc/CHANGELOG.md
+++ b/doc/CHANGELOG.md
@@ -11,12 +11,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 ### Changed
 
+* Removed boost from the headers. Boost is only a build dependency from now on.
+
 ### Deprecated
 
 ### Removed
 
 ### Fixed
 
+* Calling "GetFileDescriptor().wrapped->path()" after retrieval leads to SegFault.
 - #41 Updated Conan version in CI pipeline.
 
 ### Security
diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt
index 18d9334acdac17d3b583efabb4e2eeb116cbb5a9..784e2e04ae3baa8aacffbacbba2ecc55c1c0af6a 100644
--- a/include/CMakeLists.txt
+++ b/include/CMakeLists.txt
@@ -28,6 +28,7 @@ set(libcaosdb_INCL
     ${CMAKE_CURRENT_SOURCE_DIR}/caosdb/data_type.h
     ${CMAKE_CURRENT_SOURCE_DIR}/caosdb/entity.h
     ${CMAKE_CURRENT_SOURCE_DIR}/caosdb/exceptions.h
+    ${CMAKE_CURRENT_SOURCE_DIR}/caosdb/file_descriptor.h
     ${CMAKE_CURRENT_SOURCE_DIR}/caosdb/handler_interface.h
     ${CMAKE_CURRENT_SOURCE_DIR}/caosdb/info.h
     ${CMAKE_CURRENT_SOURCE_DIR}/caosdb/log_level.h
@@ -42,8 +43,6 @@ set(libcaosdb_INCL
     ${CMAKE_CURRENT_SOURCE_DIR}/caosdb/utility.h
     ${CMAKE_CURRENT_SOURCE_DIR}/caosdb/value.h
     ${CMAKE_CURRENT_SOURCE_DIR}/caosdb/file_transmission/register_file_upload_handler.h
-	# TODO this  file is still missing
-	# ${CMAKE_CURRENT_SOURCE_DIR}/caosdb/file_transmission/register_file_download_handler.h
     ${CMAKE_CURRENT_SOURCE_DIR}/caosdb/file_transmission/upload_request_handler.h
     ${CMAKE_CURRENT_SOURCE_DIR}/caosdb/file_transmission/download_request_handler.h
     ${CMAKE_CURRENT_SOURCE_DIR}/caosdb/file_transmission/file_writer.h
diff --git a/include/caosdb/certificate_provider.h b/include/caosdb/certificate_provider.h
index 1fd4a80b630e53b8b704b29f7803837a3cff6ced..a2cb5b5a1e407d93f3aa0ac774c26aac5ff31f83 100644
--- a/include/caosdb/certificate_provider.h
+++ b/include/caosdb/certificate_provider.h
@@ -46,7 +46,7 @@ private:
   std::string certificate_provider;
 
 public:
-  explicit PemCertificateProvider(const std::string &certificate_provider);
+  explicit PemCertificateProvider(std::string certificate_provider);
   [[nodiscard]] auto GetCertificatePem() const -> std::string override;
 };
 } // namespace caosdb::configuration
diff --git a/include/caosdb/configuration.h b/include/caosdb/configuration.h
index 649495f9a3722c9009edcb6b383f5c02941ade28..053888672ab3e1649a060553264fe8d26fda9907 100644
--- a/include/caosdb/configuration.h
+++ b/include/caosdb/configuration.h
@@ -25,27 +25,20 @@
 #include "caosdb/authentication.h"         // for Authenticator, PlainPassw...
 #include "caosdb/certificate_provider.h"   // for CertificateProvider, path
 #include "caosdb/exceptions.h"             // for ConfigurationError
-#include "caosdb/logging.h"                // for SinkConfiguration, Loggin...
 #include "caosdb/utility.h"                // for load_json_file
 #include <google/protobuf/arena.h>         // for Arena
 #include <google/protobuf/extension_set.h> // for Arena
 #include <grpcpp/security/credentials.h>   // for ChannelCredentials
-#include <boost/json/object.hpp>           // for object
-#include <boost/json/value.hpp>            // for value
-#include <boost/json/value_ref.hpp>        // for array, object
-// IWYU pragma: no_include "boost/json/fwd.hpp"
-#include <filesystem> // for path, exists
-#include <iosfwd>     // for ostream
-#include <memory>     // for shared_ptr, unique_ptr
-#include <string>     // for string
+#include <filesystem>                      // for path, exists
+#include <iosfwd>                          // for ostream
+#include <memory>                          // for shared_ptr, unique_ptr
+#include <string>                          // for string
 
 namespace caosdb::configuration {
-using boost::json::array;
-using boost::json::object;
-using boost::json::value;
 using caosdb::authentication::Authenticator;
 using caosdb::authentication::PlainPasswordAuthenticator;
 using caosdb::exceptions::ConfigurationError;
+using caosdb::utility::JsonValue;
 using caosdb::utility::load_json_file;
 using google::protobuf::Arena;
 using grpc::ChannelCredentials;
@@ -63,7 +56,7 @@ private:
   int port;
 
 public:
-  ConnectionConfiguration(const std::string &host, int port);
+  ConnectionConfiguration(std::string host, int port);
   virtual ~ConnectionConfiguration() = default;
   friend auto operator<<(std::ostream &out, const ConnectionConfiguration &configuration)
     -> std::ostream &;
@@ -102,69 +95,6 @@ public:
   [[nodiscard]] auto ToString() const -> std::string override;
 };
 
-/**
- * Helper class (no state, just member functions) which should only be used by
- * the ConfigurationManager to initialize the logging framework from the stored
- * configuration.
- */
-class LoggingConfigurationHelper {
-public:
-  friend class ConfigurationManager;
-
-private:
-  auto ConvertLogLevel(const std::string &string_level) const -> int;
-  auto CreateConsoleSinkConfiguration(const object &from, const std::string &name, int level) const
-    -> std::shared_ptr<caosdb::logging::SinkConfiguration>;
-  auto CreateSyslogSinkConfiguration(const object &from, const std::string &name, int level) const
-    -> std::shared_ptr<caosdb::logging::SinkConfiguration>;
-  auto CreateFileSinkConfiguration(const object &from, const std::string &name, int level) const
-    -> std::shared_ptr<caosdb::logging::SinkConfiguration>;
-  auto CreateSinkConfiguration(const object &from, const std::string &name, int default_level) const
-    -> std::shared_ptr<caosdb::logging::SinkConfiguration>;
-  auto CreateLoggingConfiguration(const object &from) const
-    -> caosdb::logging::LoggingConfiguration;
-};
-
-/**
- * Helper class (no state, just member functions) which should only be used by
- * the ConfigurationManager to construct Connection instances from the stored
- * configuration.
- */
-class ConnectionConfigurationHelper {
-public:
-  friend class ConfigurationManager;
-
-private:
-  /**
-   * @param from - a single connection configuration.
-   */
-  auto CreateCertificateProvider(const object &from) const -> std::unique_ptr<CertificateProvider>;
-
-  /**
-   * @param from - a single connection configuration.
-   */
-  auto CreateAuthenticator(const object &from) const -> std::unique_ptr<Authenticator>;
-
-  /**
-   * @param from - a single connection configuration.
-   */
-  auto CreateConnectionConfiguration(const bool tls, const std::string &host, const int port,
-                                     const CertificateProvider *certificate_provider,
-                                     const Authenticator *authenticator) const
-    -> std::unique_ptr<ConnectionConfiguration>;
-
-  /**
-   * @param from - a single connection configuration.
-   */
-  auto IsTls(const object &from) const -> bool;
-
-  /**
-   * @param from - a single connection configuration.
-   */
-  auto CreateConnectionConfiguration(const object &from) const
-    -> std::unique_ptr<ConnectionConfiguration>;
-};
-
 /**
  * Reads the configuration file and keeps the configuration. Singleton.
  *
@@ -225,13 +155,12 @@ public:
 
 private:
   Arena arena;
-  value json_configuration;
-  ConnectionConfigurationHelper connection_configuration_helper;
-  LoggingConfigurationHelper logging_configuration_helper;
+  JsonValue json_configuration;
 
-  inline ConfigurationManager(){
-    // InitializeDefaults();
-  };
+  inline ConfigurationManager()
+    : json_configuration(nullptr){
+        // InitializeDefaults();
+      };
 
   /**
    * Initialize this ConfigurationManager with the defaults.
@@ -242,22 +171,6 @@ private:
    */
   auto InitializeDefaults() -> int;
 
-  /**
-   * Return a json object representing the current configuration.
-   */
-  auto GetConfiguration() const -> const object &;
-
-  /**
-   * Return the connection configurations.
-   */
-  auto GetConnections() const -> const object &;
-
-  /**
-   * Return the configuration for the connection with the given name (as a json
-   * object).
-   */
-  auto GetConnection(const std::string &name) const -> const object &;
-
   /**
    * Reset this ConfigurationManager.
    *
diff --git a/include/caosdb/entity.h b/include/caosdb/entity.h
index 2ff36d7242c5bcb8739bbca839e749825e4f6825..23b6e2f612a52e85df9eb2682b6cac11fd594063 100644
--- a/include/caosdb/entity.h
+++ b/include/caosdb/entity.h
@@ -29,29 +29,25 @@
 #ifndef CAOSDB_ENTITY_H
 #define CAOSDB_ENTITY_H
 
-#include "caosdb/data_type.h"                          // for DataType
-#include "caosdb/entity/v1/main.pb.h"                  // for RepeatedPtrField
-#include "caosdb/logging.h"                            // for CAOSDB_LOG_WARN
-#include "caosdb/message_code.h"                       // for get_message_code
-#include "caosdb/protobuf_helper.h"                    // for get_arena
-#include "caosdb/status_code.h"                        // for StatusCode
-#include "caosdb/value.h"                              // for Value
-#include <boost/log/core/record.hpp>                   // for record
-#include <boost/log/detail/attachable_sstream_buf.hpp> // for basic_ostring...
-#include <boost/log/sources/record_ostream.hpp>        // for basic_record_...
-#include <boost/preprocessor/seq/limits/enum_256.hpp>  // for BOOST_PP_SEQ_...
-#include <boost/preprocessor/seq/limits/size_256.hpp>  // for BOOST_PP_SEQ_...
-#include <cstdint>                                     // for int64_t
-#include <filesystem>                                  // for path
-#include <google/protobuf/arena.h>                     // for Arena
-#include <google/protobuf/message.h>                   // for RepeatedPtrField
-#include <iosfwd>                                      // for streamsize
-#include <iterator>                                    // for iterator, output_iterato...
-#include <map>                                         // for map
-#include <stdexcept>                                   // for out_of_range
-#include <string>                                      // for string, basic...
-#include <utility>                                     // for move
-#include <vector>                                      // for vector
+#include "caosdb/data_type.h"         // for DataType
+#include "caosdb/entity/v1/main.pb.h" // for RepeatedPtrField
+#include "caosdb/file_descriptor.h"   // for FileDescriptor
+#include "caosdb/logging.h"           // for CAOSDB_LOG_WARN
+#include "caosdb/message_code.h"      // for get_message_code
+#include "caosdb/protobuf_helper.h"   // for get_arena
+#include "caosdb/status_code.h"       // for StatusCode
+#include "caosdb/value.h"             // for Value
+#include <cstdint>                    // for int64_t
+#include <filesystem>                 // for path
+#include <google/protobuf/arena.h>    // for Arena
+#include <google/protobuf/message.h>  // for RepeatedPtrField
+#include <iterator>                   // for iterator, output_iterato...
+#include <map>                        // for map
+#include <stdexcept>                  // for out_of_range
+#include <string>                     // for string, basic...
+#include <utility>                    // for move
+#include <vector>                     // for vector
+// IWYU pragma: no_include "net/proto2/public/repeated_field.h"
 
 namespace caosdb::entity {
 using caosdb::entity::v1::IdResponse;
@@ -60,7 +56,6 @@ using std::filesystem::is_directory;
 using ProtoParent = caosdb::entity::v1::Parent;
 using ProtoProperty = caosdb::entity::v1::Property;
 using ProtoEntity = caosdb::entity::v1::Entity;
-using ProtoFileDescriptor = caosdb::entity::v1::FileDescriptor;
 using ProtoMessage = caosdb::entity::v1::Message;
 using ProtoValue = caosdb::entity::v1::Value;
 using ProtoDataType = caosdb::entity::v1::DataType;
@@ -109,12 +104,6 @@ const std::map<Role, std::string> role_names = {{Role::UNSPECIFIED, "UNSPECIFIED
                                                 {Role::PROPERTY, "PROPERTY"},
                                                 {Role::FILE, "FILE"}};
 
-struct FileDescriptor {
-  FileTransmissionId *file_transmission_id;
-  ProtoFileDescriptor *wrapped;
-  std::filesystem::path local_path;
-};
-
 /**
  * Abstract base class for Messages, Properties and Parents container classes.
  *
@@ -719,6 +708,9 @@ public:
                                                : static_cast<ProtoDataType *>(nullptr)) {
     properties.wrapped = this->wrapped->mutable_properties();
     parents.wrapped = this->wrapped->mutable_parents();
+    if (this->wrapped->has_file_descriptor()) {
+      file_descriptor.wrapped = this->wrapped->mutable_file_descriptor();
+    }
   };
   explicit inline Entity(EntityResponse *response) : Entity(response->mutable_entity()) {
     this->errors.wrapped->Swap(response->mutable_errors());
diff --git a/include/caosdb/file_descriptor.h b/include/caosdb/file_descriptor.h
new file mode 100644
index 0000000000000000000000000000000000000000..c6d6784c6cc73632dfdd871720c241a59ab03079
--- /dev/null
+++ b/include/caosdb/file_descriptor.h
@@ -0,0 +1,46 @@
+/*
+ * This file is a part of the CaosDB Project.
+ *
+ * Copyright (C) 2022 Timm Fitschen <t.fitschen@indiscale.com>
+ * Copyright (C) 2022 IndiScale GmbH <info@indiscale.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+/**
+ * @brief File descriptors are used to represent directories, links and files
+ * of the caosdb file system and their meta data.
+ * @file caosdb/entity.h
+ * @author Timm Fitchen
+ * @date 2022-01-21
+ */
+#ifndef CAOSDB_FILE_DESCRIPTOR_H
+#define CAOSDB_FILE_DESCRIPTOR_H
+
+#include "caosdb/entity/v1/main.pb.h" // for RepeatedPtrField
+#include <filesystem>                 // for path
+
+namespace caosdb::entity {
+using ProtoFileDescriptor = caosdb::entity::v1::FileDescriptor;
+using caosdb::entity::v1::FileTransmissionId;
+
+struct FileDescriptor {
+  FileTransmissionId *file_transmission_id;
+  ProtoFileDescriptor *wrapped;
+  std::filesystem::path local_path;
+};
+
+} // namespace caosdb::entity
+#endif
diff --git a/include/caosdb/file_transmission/download_request_handler.h b/include/caosdb/file_transmission/download_request_handler.h
index 0a8e13aac4237b2a9c5e1262dd8fdd0b742a0f29..cd8542bef873169c363a43e8c727a7323f3c64bc 100644
--- a/include/caosdb/file_transmission/download_request_handler.h
+++ b/include/caosdb/file_transmission/download_request_handler.h
@@ -49,11 +49,12 @@
 #ifndef CAOSDB_FILE_TRANSMISSION_DOWNLOAD_REQUEST_HANDLER_H
 #define CAOSDB_FILE_TRANSMISSION_DOWNLOAD_REQUEST_HANDLER_H
 
-#include "caosdb/entity.h"                        // for FileDescriptor
+#include "caosdb/file_descriptor.h"               // for FileDescriptor
 #include "caosdb/entity/v1/main.grpc.pb.h"        // for FileTransmissionS...
 #include "caosdb/entity/v1/main.pb.h"             // for FileDownloadResponse
 #include "caosdb/file_transmission/file_writer.h" // for FileWriter
 #include "caosdb/handler_interface.h"             // for HandlerTag, Handl...
+#include <cstdint>                                // for uint64_t
 #include <grpcpp/impl/codegen/async_stream.h>     // for ClientAsyncReader
 #include <grpcpp/impl/codegen/client_context.h>   // for ClientContext
 #include <grpcpp/impl/codegen/completion_queue.h> // for CompletionQueue
@@ -115,7 +116,7 @@ protected:
 
   FileDescriptor file_descriptor_;
 
-  unsigned long long bytesReceived_;
+  uint64_t bytesReceived_;
 };
 
 } // namespace caosdb::transaction
diff --git a/include/caosdb/file_transmission/file_reader.h b/include/caosdb/file_transmission/file_reader.h
index 14f8614896de79b15e9bb793a04ac17f40f27fec..380b6a838b77e9f80f91f93c84eb0b0f888de2e0 100644
--- a/include/caosdb/file_transmission/file_reader.h
+++ b/include/caosdb/file_transmission/file_reader.h
@@ -50,8 +50,9 @@
 #define CAOSDB_FILE_TRANSMISSION_FILE_READER_H
 
 #include <cstddef>    // for size_t
-#include <filesystem> // for ifstream
-#include <fstream>    // for ifstream, size_t
+#include <cstdint>    // for uint64_t
+#include <filesystem> // for path, exists
+#include <fstream>    // for ifstream
 #include <string>     // for string
 
 namespace caosdb::transaction {
@@ -71,7 +72,7 @@ public:
   FileReader(FileReader &&) = default;
   FileReader &operator=(FileReader &&) = default;
 
-  unsigned long long fileSize() const { return size_; }
+  uint64_t fileSize() const { return size_; }
 
   std::size_t read(std::string &buffer);
 
@@ -80,7 +81,7 @@ private:
 
   std::ifstream stream_;
   std::filesystem::path filename_;
-  unsigned long long size_;
+  uint64_t size_;
 };
 
 } // namespace caosdb::transaction
diff --git a/include/caosdb/file_transmission/upload_request_handler.h b/include/caosdb/file_transmission/upload_request_handler.h
index cb9748f868290d362bb21bb66eaacb0267c14eed..193489e21c2c69d4c4df564cc6ad2c71d200cc8f 100644
--- a/include/caosdb/file_transmission/upload_request_handler.h
+++ b/include/caosdb/file_transmission/upload_request_handler.h
@@ -49,9 +49,9 @@
 #ifndef CAOSDB_FILE_TRANSMISSION_UPLOAD_REQUEST_HANDLER_H
 #define CAOSDB_FILE_TRANSMISSION_UPLOAD_REQUEST_HANDLER_H
 
-#include "caosdb/entity.h"                        // for FileDescriptor
 #include "caosdb/entity/v1/main.grpc.pb.h"        // for FileTransmissionS...
 #include "caosdb/entity/v1/main.pb.h"             // for FileUploadRequest
+#include "caosdb/file_descriptor.h"               // for FileDescriptor
 #include "caosdb/file_transmission/file_reader.h" // for FileReader
 #include "caosdb/handler_interface.h"             // for HandlerTag, Handl...
 #include <cstdint>                                // for uint64_t
diff --git a/include/caosdb/logging.h b/include/caosdb/logging.h
index eb99f9a51b3630ce48849acf935b316044aa82b2..263151fd21674d1d801439c7c4b4d13a0837043a 100644
--- a/include/caosdb/logging.h
+++ b/include/caosdb/logging.h
@@ -23,32 +23,34 @@
 #ifndef CAOSDB_LOGGING_H
 #define CAOSDB_LOGGING_H
 
-#include "caosdb/log_level.h"                            // for CAOSDB_LOG_...
-#include <boost/log/sources/record_ostream.hpp>          // IWYU pragma: keep
-#include <boost/log/sources/severity_channel_logger.hpp> // for BOOST_LOG_C...
-#include <boost/log/utility/setup/settings.hpp>          // for settings
-#include <boost/smart_ptr/intrusive_ptr.hpp>             // for intrusive_ptr
-#include <boost/smart_ptr/intrusive_ref_counter.hpp>     // for intrusive_p...
-#include <memory>                                        // for shared_ptr
-#include <string>                                        // for string
-#include <vector>                                        // for vector
+#include "caosdb/log_level.h" // for CAOSDB_LOG_...
+#include <cstdint>            // for uint64_t
+#include <memory>             // for shared_ptr
+#include <ostream>            // for ostream
+#include <string>             // for string
+#include <vector>             // for vector
 
 namespace caosdb::logging {
 
 const std::string logger_name = "caosdb::logging";
 
-typedef boost::log::sources::severity_channel_logger_mt<int, std::string> boost_logger_class;
-
-class logger {
+class LoggerOutputStream {
 public:
-  static auto get() -> boost_logger_class & { return logger::GetInstance()._logger_instance; }
+  LoggerOutputStream(std::string channel, int level);
+  auto operator<<(int msg) -> LoggerOutputStream &;
+  auto operator<<(uint64_t msg) -> LoggerOutputStream &;
+  auto operator<<(int64_t msg) -> LoggerOutputStream &;
+  auto operator<<(std::streambuf *msg) -> LoggerOutputStream &;
+  auto operator<<(const char *msg) -> LoggerOutputStream &;
+  auto operator<<(const std::string &msg) -> LoggerOutputStream &;
+  auto operator<<(void *msg) -> LoggerOutputStream &;
+  static auto get(const std::string &channel, int level) -> LoggerOutputStream {
+    return LoggerOutputStream(channel, level);
+  }
 
 private:
-  static logger &GetInstance() {
-    static logger instance;
-    return instance;
-  }
-  boost_logger_class _logger_instance;
+  std::string channel;
+  int level;
 };
 
 /**
@@ -112,7 +114,7 @@ public:
   friend auto initialize_logging(const LoggingConfiguration &logging_configuration) -> void;
 
 protected:
-  virtual auto Configure(boost::log::settings &settings) const -> void;
+  virtual auto Configure(void *settings) const -> void;
 
 private:
   std::string name;
@@ -128,7 +130,7 @@ public:
 
 protected:
   typedef SinkConfiguration sink_configuration;
-  virtual auto Configure(boost::log::settings &settings) const -> void override;
+  virtual auto Configure(void *settings) const -> void override;
 
 private:
   const std::string destination = "Console";
@@ -151,7 +153,7 @@ public:
 
 protected:
   typedef SinkConfiguration sink_configuration;
-  virtual auto Configure(boost::log::settings &settings) const -> void override;
+  virtual auto Configure(void *settings) const -> void override;
 
 private:
   const std::string destination = "TextFile";
@@ -196,17 +198,17 @@ void caosdb_log_trace(const char *channel, const char *msg);
 } // namespace caosdb::logging
 
 #define CAOSDB_LOG_FATAL(Channel)                                                                  \
-  BOOST_LOG_CHANNEL_SEV(caosdb::logging::logger::get(), Channel, CAOSDB_LOG_LEVEL_FATAL)
+  caosdb::logging::LoggerOutputStream::get(Channel, CAOSDB_LOG_LEVEL_FATAL)
 #define CAOSDB_LOG_ERROR(Channel)                                                                  \
-  BOOST_LOG_CHANNEL_SEV(caosdb::logging::logger::get(), Channel, CAOSDB_LOG_LEVEL_ERROR)
+  caosdb::logging::LoggerOutputStream::get(Channel, CAOSDB_LOG_LEVEL_ERROR)
 #define CAOSDB_LOG_WARN(Channel)                                                                   \
-  BOOST_LOG_CHANNEL_SEV(caosdb::logging::logger::get(), Channel, CAOSDB_LOG_LEVEL_WARN)
+  caosdb::logging::LoggerOutputStream::get(Channel, CAOSDB_LOG_LEVEL_WARN)
 #define CAOSDB_LOG_INFO(Channel)                                                                   \
-  BOOST_LOG_CHANNEL_SEV(caosdb::logging::logger::get(), Channel, CAOSDB_LOG_LEVEL_INFO)
+  caosdb::logging::LoggerOutputStream::get(Channel, CAOSDB_LOG_LEVEL_INFO)
 #define CAOSDB_LOG_DEBUG(Channel)                                                                  \
-  BOOST_LOG_CHANNEL_SEV(caosdb::logging::logger::get(), Channel, CAOSDB_LOG_LEVEL_DEBUG)
+  caosdb::logging::LoggerOutputStream::get(Channel, CAOSDB_LOG_LEVEL_DEBUG)
 #define CAOSDB_LOG_TRACE(Channel)                                                                  \
-  BOOST_LOG_CHANNEL_SEV(caosdb::logging::logger::get(), Channel, CAOSDB_LOG_LEVEL_TRACE)
+  caosdb::logging::LoggerOutputStream::get(Channel, CAOSDB_LOG_LEVEL_TRACE)
 
 #define CAOSDB_LOG_ERROR_AND_RETURN_STATUS(Channel, StatusCode, Message)                           \
   CAOSDB_LOG_ERROR(Channel) << "StatusCode (" << StatusCode << ") "                                \
diff --git a/include/caosdb/transaction.h b/include/caosdb/transaction.h
index 0e11d3f1a5d9145795b2bdcd4e1c82c31e360aa2..ae0361276eb0ad1d5f282a0068ae99f9418b2f7c 100644
--- a/include/caosdb/transaction.h
+++ b/include/caosdb/transaction.h
@@ -21,25 +21,22 @@
 #ifndef CAOSDB_TRANSACTION_H
 #define CAOSDB_TRANSACTION_H
 
-#include "caosdb/entity.h"                            // for Entity, FileDe...
-#include "caosdb/entity/v1/main.grpc.pb.h"            // for EntityTransact...
-#include "caosdb/entity/v1/main.pb.h"                 // for MultiTransacti...
-#include "caosdb/handler_interface.h"                 // for HandlerInterface
-#include "caosdb/transaction_handler.h"               // for EntityTransactionHandler
-#include "caosdb/logging.h"                           // for CAOSDB_LOG_ERR...
-#include "caosdb/protobuf_helper.h"                   // for get_arena
-#include "caosdb/status_code.h"                       // for StatusCode
-#include "caosdb/transaction_status.h"                // for StatusCode
-#include <boost/log/core/record.hpp>                  // for record
-#include <boost/log/sources/record_ostream.hpp>       // for basic_record_o...
-#include <boost/preprocessor/seq/limits/enum_256.hpp> // for BOOST_PP_SEQ_E...
-#include <boost/preprocessor/seq/limits/size_256.hpp> // for BOOST_PP_SEQ_S...
-#include <google/protobuf/arena.h>                    // for Arena
-#include <google/protobuf/util/json_util.h>           // for MessageToJsonS...
-#include <grpcpp/impl/codegen/completion_queue.h>     // for CompletionQueue
-#include <algorithm>                                  // for max
-#include <iterator>                                   // for iterator, next
-#include <map>                                        // for map
+#include "caosdb/entity.h"                        // for Entity, FileDe...
+#include "caosdb/entity/v1/main.grpc.pb.h"        // for EntityTransact...
+#include "caosdb/entity/v1/main.pb.h"             // for MultiTransacti...
+#include "caosdb/file_descriptor.h"               // for FileDescriptor
+#include "caosdb/handler_interface.h"             // for HandlerInterface
+#include "caosdb/transaction_handler.h"           // for EntityTransactionHandler
+#include "caosdb/logging.h"                       // for CAOSDB_LOG_ERR...
+#include "caosdb/protobuf_helper.h"               // for get_arena
+#include "caosdb/status_code.h"                   // for StatusCode
+#include "caosdb/transaction_status.h"            // for StatusCode
+#include <google/protobuf/arena.h>                // for Arena
+#include <google/protobuf/util/json_util.h>       // for MessageToJsonS...
+#include <grpcpp/impl/codegen/completion_queue.h> // for CompletionQueue
+#include <algorithm>                              // for max
+#include <iterator>                               // for iterator, next
+#include <map>                                    // for map
 // IWYU pragma: no_include <ext/alloc_traits.h>
 #include <memory>  // for unique_ptr
 #include <string>  // for string
diff --git a/include/caosdb/utility.h b/include/caosdb/utility.h
index 0a4d65e883ccfb6cc8f41d1c412bef5433b89417..13e3dfeb99dc5415a733d5b6dcea852705b1662d 100644
--- a/include/caosdb/utility.h
+++ b/include/caosdb/utility.h
@@ -21,27 +21,15 @@
 
 #ifndef CAOSDB_UTILS_H
 #define CAOSDB_UTILS_H
-#include "caosdb/data_type.h"                 // for AtomicDataType
-#include "caosdb/entity.h"                    // for Importance, Role
-#include <boost/beast/core/detail/base64.hpp> // for encoded_size
-#include <boost/beast/core/detail/base64.ipp> // for encode
-#include <boost/filesystem/string_file.hpp>   // for load_string_file
-#include <boost/json/stream_parser.hpp>       // for stream_parser
-#include <boost/json/value.hpp>               // for value
-#include <boost/lexical_cast.hpp>             // for lexical_cast
-#include <cassert>                            // for assert
-#include <cstdlib>                            // for getenv
-#include <filesystem>                         // for path
-#include <fstream>                            // for basic_istream<>::__ist...
-#include <memory>                             // for allocator, unique_ptr
-#include <stdexcept>                          // for logic_error
-#include <string>                             // for string, operator+, cha...
-#include <type_traits>                        // for underlying_type_t
-#include <typeinfo>                           // for type_info
+#include "caosdb/data_type.h" // for AtomicDataType
+#include "caosdb/entity.h"    // for Importance, Role
+#include <cstdlib>            // for getenv
+#include <filesystem>         // for path
+#include <fstream>            // for basic_istream<>::__ist...
+#include <memory>             // for shared_ptr
+#include <string>             // for string, operator+, cha...
 
 namespace caosdb::utility {
-using boost::json::stream_parser;
-using boost::json::value;
 using std::ifstream;
 using std::filesystem::exists;
 using std::filesystem::path;
@@ -49,12 +37,7 @@ using std::filesystem::path;
 /**
  * @brief Get the name of the enum value.  May be useful for higher-order CaosDB clients.
  */
-template <typename Enum> auto getEnumNameFromValue(Enum v) -> std::string {
-  if (std::is_same_v<std::underlying_type_t<Enum>, int>) {
-    return boost::lexical_cast<std::string>(static_cast<int>(v));
-  }
-  throw std::logic_error(std::string("Enum type ") + typeid(v).name() + " not implemented.");
-}
+template <typename Enum> auto getEnumNameFromValue(Enum v) -> std::string;
 
 // Forward declaration of specializations
 template <>
@@ -84,11 +67,7 @@ auto getEnumValueFromName<caosdb::entity::Role>(const std::string &name) -> caos
 /**
  * @brief Read a text file into a string and return the file's content.
  */
-inline auto load_string_file(const path &file_path) -> std::string {
-  std::string result;
-  boost::filesystem::load_string_file(file_path.string(), result);
-  return result;
-}
+auto load_string_file(const path &file_path) -> std::string;
 
 /**
  * @brief Return the environment variable KEY, or FALLBACK if it does not exist.
@@ -115,37 +94,82 @@ inline auto get_env_fallback(const std::string &key, const std::string &fallback
 }
 
 /**
- * @brief Encode string as base64
+ * @brief JsonValue is a thin wrapper around a implementation specific
+ * third-party json object (e.g. boost).
  */
-inline auto base64_encode(const std::string &plain) -> std::string {
-  auto size_plain = plain.size();
-  auto size_encoded = boost::beast::detail::base64::encoded_size(size_plain);
-
-  std::unique_ptr<char[]> encoded(new char[size_encoded]);
-  boost::beast::detail::base64::encode(encoded.get(), plain.c_str(), size_plain);
-
-  // the encoded char[] is not null terminated, so explicitely set the length
-  return std::string(encoded.get(), encoded.get() + size_encoded);
-}
-
-inline auto load_json_file(const path &json_file) -> value {
-  assert(exists(json_file));
+class JsonValue {
+public:
+  /**
+   * Default Constructor.
+   *
+   * Creates an empty wrapper where `wrapped` is nullptr.
+   */
+  JsonValue() : JsonValue(nullptr) {}
+  /**
+   * Constructor.
+   *
+   * By calling this constructor the ownership of the `wrapped` parameter is
+   * transferred to this object.
+   */
+  JsonValue(void *wrapped);
+  /**
+   * Destructor.
+   *
+   * Also deletes the `wrapped` object.
+   */
+  ~JsonValue();
+
+  /**
+   * Copy Constructor.
+   *
+   * Also copies the `wrapped` object.
+   */
+  JsonValue(const JsonValue &other);
+
+  /**
+   * Copy Assigment.
+   *
+   * Also copies the `wrapped` object.
+   */
+  auto operator=(const JsonValue &other) -> JsonValue &;
+
+  /**
+   * Move Constructor.
+   *
+   * Also moves the `wrapped` object.
+   */
+  JsonValue(JsonValue &&other) noexcept;
+
+  /**
+   * Move Assigment.
+   *
+   * Also moves the `wrapped` object.
+   */
+  auto operator=(JsonValue &&other) noexcept -> JsonValue &;
+
+  /**
+   * Reset this object.
+   *
+   * Also deletes `wrapped` sets it to the nullptr.
+   */
+  auto Reset() -> void;
+
+  /**
+   * An object which represents a JSON value. The object's class is an
+   * implementation detail.
+   */
+  std::shared_ptr<void> wrapped;
+};
 
-  constexpr auto buffer_size = std::size_t(4096);
-  auto stream = ifstream(json_file);
-  stream.exceptions(std::ios_base::badbit);
-
-  stream_parser parser;
-  auto result = std::string();
-  auto buffer = std::string(buffer_size, '\0');
-  while (stream.read(&buffer[0], buffer_size)) {
-    parser.write(buffer.c_str(), stream.gcount());
-  }
-  parser.write(buffer.c_str(), stream.gcount());
+/**
+ * @brief Load json object from a json file and return it.
+ */
+auto load_json_file(const path &json_file) -> JsonValue;
 
-  assert(parser.done());
-  return parser.release();
-}
+/**
+ * @brief Encode string as base64
+ */
+auto base64_encode(const std::string &plain) -> std::string;
 
 inline auto get_home_directory() -> const path {
   const auto *const home = getenv("HOME");
diff --git a/proto b/proto
index 533c8e7341d0659e3cc43d834793a7a965703f55..0b301401cf28d7a3edeb2c55e418f072b83cf5a7 160000
--- a/proto
+++ b/proto
@@ -1 +1 @@
-Subproject commit 533c8e7341d0659e3cc43d834793a7a965703f55
+Subproject commit 0b301401cf28d7a3edeb2c55e418f072b83cf5a7
diff --git a/src/caosdb/configuration.cpp b/src/caosdb/configuration.cpp
index 90cc97b3cebc1b39a1b376805ae73cc068173ef7..e1ffb23b3b1a2db5ecea79588c237bb36e79b1e1 100644
--- a/src/caosdb/configuration.cpp
+++ b/src/caosdb/configuration.cpp
@@ -19,35 +19,55 @@
  *
  */
 #include "caosdb/configuration.h"
-#include "caosdb/authentication.h"                     // for Authenticator
-#include "caosdb/connection.h"                         // for ConnectionManager
-#include "caosdb/constants.h"                          // for LIBCAOSDB_CONF...
-#include "caosdb/exceptions.h"                         // for ConfigurationE...
-#include "caosdb/log_level.h"                          // for CAOSDB_DEFAULT...
-#include "caosdb/status_code.h"                        // for StatusCode
-#include "caosdb/utility.h"                            // for get_home_direc...
-#include <boost/json/impl/object.hpp>                  // for object::at
-#include <boost/json/object.hpp>                       // for object, objec...
-#include <boost/json/string.hpp>                       // for string
-#include <boost/json/string_view.hpp>                  // for string_view
-#include <boost/json/value.hpp>                        // for value, key_va...
-#include <boost/json/value_ref.hpp>                    // for object
-#include <boost/log/core/record.hpp>                   // for record
-#include <boost/log/detail/attachable_sstream_buf.hpp> // for basic_ostring...
-#include <boost/log/sources/record_ostream.hpp>        // for basic_record_o...
-#include <boost/preprocessor/seq/limits/enum_256.hpp>  // for BOOST_PP_SEQ_E...
-#include <boost/preprocessor/seq/limits/size_256.hpp>  // for BOOST_PP_SEQ_S...
-#include <cassert>                                     // for assert
-#include <cstdlib>                                     // for getenv
-#include <cstring>                                     // for strcmp
-#include <exception>                                   // IWYU pragma: keep
+#include "caosdb/authentication.h"    // for Authenticator
+#include "caosdb/connection.h"        // for ConnectionManager
+#include "caosdb/constants.h"         // for LIBCAOSDB_CONF...
+#include "caosdb/exceptions.h"        // for ConfigurationE...
+#include "caosdb/log_level.h"         // for CAOSDB_DEFAULT...
+#include "caosdb/logging.h"           // for SinkConfiguration, Loggin...
+#include "caosdb/status_code.h"       // for StatusCode
+#include "caosdb/utility.h"           // for get_home_direc...
+#include <boost/json/impl/object.hpp> // for object::at
+#include <boost/json/object.hpp>      // for object, objec...
+#include <boost/json/string.hpp>      // for string
+#include <boost/json/string_view.hpp> // for string_view
+#include <boost/json/value.hpp>       // for value, key_va...
+#include <boost/json/value_ref.hpp>   // for object
+#include <cassert>                    // for assert
+#include <cstdlib>                    // for getenv
+#include <cstring>                    // for strcmp
+#include <exception>                  // IWYU pragma: keep
 // IWYU pragma: no_include <bits/exception.h>
 #include <grpcpp/security/credentials.h> // for SslCredentials
 #include <iterator>                      // for next
 #include <map>                           // for map
-#include <sstream>                       // for basic_stringb...
 #include <stdexcept>                     // for out_of_range
 #include <string>                        // for string, operator+
+#include <utility>                       // for move
+
+// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
+#define WRAPPED_JSON_CONFIGURATION(obj)                                                            \
+  (static_cast<value *>((obj)->json_configuration.wrapped.get()))
+
+// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
+#define GET_CONNECTIONS                                                                            \
+  if (!this->json_configuration.wrapped) {                                                         \
+    throw ConfigurationError("This CaosDB client has not been configured.");                       \
+  }                                                                                                \
+  assert(WRAPPED_JSON_CONFIGURATION(this)->is_object());                                           \
+  const auto &configuration = WRAPPED_JSON_CONFIGURATION(this)->as_object();                       \
+  if (!configuration.contains("connections")) {                                                    \
+    throw ConfigurationError("This CaosDB client hasn't any configured connections.");             \
+  }                                                                                                \
+  const auto &connections_value = configuration.at("connections");                                 \
+  if (connections_value.is_null()) {                                                               \
+    throw ConfigurationError("This CaosDB client hasn't any configured connections.");             \
+  }                                                                                                \
+  assert(connections_value.is_object());                                                           \
+  const auto &connections = connections_value.as_object();                                         \
+  if (connections.empty()) {                                                                       \
+    throw ConfigurationError("This CaosDB client hasn't any configured connections.");             \
+  }
 
 namespace caosdb::configuration {
 using boost::json::object;
@@ -78,18 +98,15 @@ auto PemFileCertificateProvider::GetCertificatePem() const -> std::string {
   return this->certificate_provider;
 }
 
-PemCertificateProvider::PemCertificateProvider(const std::string &certificate_provider) {
-  this->certificate_provider = certificate_provider;
-}
+PemCertificateProvider::PemCertificateProvider(std::string certificate_provider)
+  : certificate_provider(std::move(certificate_provider)) {}
 
 auto PemCertificateProvider::GetCertificatePem() const -> std::string {
   return this->certificate_provider;
 }
 
-ConnectionConfiguration::ConnectionConfiguration(const std::string &host, int port) {
-  this->host = host;
-  this->port = port;
-}
+ConnectionConfiguration::ConnectionConfiguration(std::string host, int port)
+  : host(std::move(host)), port(port) {}
 
 auto ConnectionConfiguration::GetHost() const -> std::string { return this->host; }
 
@@ -159,8 +176,7 @@ auto TlsConnectionConfiguration::ToString() const -> std::string {
          "," + this->certificate_provider + ")";
 }
 
-auto ConnectionConfigurationHelper::CreateCertificateProvider(const object &from) const
-  -> std::unique_ptr<CertificateProvider> {
+auto CreateCertificateProvider(const object &from) -> std::unique_ptr<CertificateProvider> {
   std::unique_ptr<CertificateProvider> certificate_provider;
   if (from.contains("server_certificate_path")) {
     const value &path_str = from.at("server_certificate_path");
@@ -176,8 +192,7 @@ auto ConnectionConfigurationHelper::CreateCertificateProvider(const object &from
   return certificate_provider;
 }
 
-auto ConnectionConfigurationHelper::CreateAuthenticator(const object &from) const
-  -> std::unique_ptr<Authenticator> {
+auto CreateAuthenticator(const object &from) -> std::unique_ptr<Authenticator> {
   std::unique_ptr<Authenticator> authenticator;
   if (from.contains("authentication")) {
     assert(from.at("authentication").is_object());
@@ -205,9 +220,9 @@ auto ConnectionConfigurationHelper::CreateAuthenticator(const object &from) cons
   return authenticator;
 }
 
-auto ConnectionConfigurationHelper::CreateConnectionConfiguration(
-  const bool tls, const std::string &host, const int port,
-  const CertificateProvider *certificate_provider, const Authenticator *authenticator) const
+auto CreateConnectionConfiguration(const bool tls, const std::string &host, const int port,
+                                   const CertificateProvider *certificate_provider,
+                                   const Authenticator *authenticator)
   -> std::unique_ptr<ConnectionConfiguration> {
   if (tls) {
     if (certificate_provider != nullptr && authenticator != nullptr) {
@@ -228,7 +243,7 @@ auto ConnectionConfigurationHelper::CreateConnectionConfiguration(
   }
 }
 
-auto ConnectionConfigurationHelper::IsTls(const object &from) const -> bool {
+auto IsTls(const object &from) -> bool {
   bool tls = true;
   if (from.contains("tls")) {
     auto tls_switch = from.at("tls");
@@ -238,8 +253,7 @@ auto ConnectionConfigurationHelper::IsTls(const object &from) const -> bool {
   return tls;
 }
 
-auto ConnectionConfigurationHelper::CreateConnectionConfiguration(const object &from) const
-  -> std::unique_ptr<ConnectionConfiguration> {
+auto CreateConnectionConfiguration(const object &from) -> std::unique_ptr<ConnectionConfiguration> {
   assert(from.contains("host"));
   const auto &host = from.at("host");
   assert(host.is_string());
@@ -259,25 +273,19 @@ auto ConnectionConfigurationHelper::CreateConnectionConfiguration(const object &
                                        certificate_provider.get(), authenticator.get());
 }
 
-auto LoggingConfigurationHelper::CreateConsoleSinkConfiguration(const object & /*from*/,
-                                                                const std::string &name,
-                                                                int level) const
+auto CreateConsoleSinkConfiguration(const object & /*from*/, const std::string &name, int level)
   -> std::shared_ptr<caosdb::logging::SinkConfiguration> {
   auto result = std::make_shared<ConsoleSinkConfiguration>(name, level);
   return result;
 }
 
-auto LoggingConfigurationHelper::CreateSyslogSinkConfiguration(const object & /*from*/,
-                                                               const std::string &name,
-                                                               int level) const
+auto CreateSyslogSinkConfiguration(const object & /*from*/, const std::string &name, int level)
   -> std::shared_ptr<caosdb::logging::SinkConfiguration> {
   auto result = std::make_shared<SyslogSinkConfiguration>(name, level);
   return result;
 }
 
-auto LoggingConfigurationHelper::CreateFileSinkConfiguration(const object &from,
-                                                             const std::string &name,
-                                                             int level) const
+auto CreateFileSinkConfiguration(const object &from, const std::string &name, int level)
   -> std::shared_ptr<caosdb::logging::SinkConfiguration> {
   auto result = std::make_shared<FileSinkConfiguration>(name, level);
   if (from.contains("directory")) {
@@ -286,9 +294,21 @@ auto LoggingConfigurationHelper::CreateFileSinkConfiguration(const object &from,
   return result;
 }
 
-auto LoggingConfigurationHelper::CreateSinkConfiguration(const object &from,
-                                                         const std::string &name,
-                                                         int default_level) const
+auto ConvertLogLevel(const std::string &string_level) -> int {
+  static std::map<std::string, int> log_level_names = {
+    {"", CAOSDB_DEFAULT_LOG_LEVEL},    {"off", CAOSDB_LOG_LEVEL_OFF},
+    {"fatal", CAOSDB_LOG_LEVEL_FATAL}, {"error", CAOSDB_LOG_LEVEL_ERROR},
+    {"warn", CAOSDB_LOG_LEVEL_WARN},   {"info", CAOSDB_LOG_LEVEL_INFO},
+    {"debug", CAOSDB_LOG_LEVEL_DEBUG}, {"trace", CAOSDB_LOG_LEVEL_TRACE},
+    {"all", CAOSDB_LOG_LEVEL_ALL}};
+  try {
+    return log_level_names.at(string_level);
+  } catch (const std::out_of_range &exc) {
+    throw ConfigurationError("Unknown log level: " + string_level);
+  }
+}
+
+auto CreateSinkConfiguration(const object &from, const std::string &name, int default_level)
   -> std::shared_ptr<caosdb::logging::SinkConfiguration> {
   assert(from.contains("destination"));
   const auto &destination = std::string(from.at("destination").as_string().c_str());
@@ -307,22 +327,7 @@ auto LoggingConfigurationHelper::CreateSinkConfiguration(const object &from,
   }
 }
 
-auto LoggingConfigurationHelper::ConvertLogLevel(const std::string &string_level) const -> int {
-  static std::map<std::string, int> log_level_names = {
-    {"", CAOSDB_DEFAULT_LOG_LEVEL},    {"off", CAOSDB_LOG_LEVEL_OFF},
-    {"fatal", CAOSDB_LOG_LEVEL_FATAL}, {"error", CAOSDB_LOG_LEVEL_ERROR},
-    {"warn", CAOSDB_LOG_LEVEL_WARN},   {"info", CAOSDB_LOG_LEVEL_INFO},
-    {"debug", CAOSDB_LOG_LEVEL_DEBUG}, {"trace", CAOSDB_LOG_LEVEL_TRACE},
-    {"all", CAOSDB_LOG_LEVEL_ALL}};
-  try {
-    return log_level_names.at(string_level);
-  } catch (const std::out_of_range &exc) {
-    throw ConfigurationError("Unknown log level: " + string_level);
-  }
-}
-
-auto LoggingConfigurationHelper::CreateLoggingConfiguration(const object &from) const
-  -> LoggingConfiguration {
+auto CreateLoggingConfiguration(const object &from) -> LoggingConfiguration {
   auto default_level_str =
     from.contains("level") ? std::string(from.at("level").as_string().c_str()) : "";
   int default_level = ConvertLogLevel(default_level_str);
@@ -364,7 +369,7 @@ auto ConfigurationManager::mReset() noexcept -> int {
 
 auto ConfigurationManager::mClear() noexcept -> int {
   try {
-    json_configuration = value(nullptr);
+    json_configuration.Reset();
     ConnectionManager::Reset();
     return StatusCode::SUCCESS;
   } catch (const caosdb::exceptions::Exception &exc) {
@@ -377,7 +382,7 @@ auto ConfigurationManager::mClear() noexcept -> int {
 }
 
 auto ConfigurationManager::mLoadSingleJSONConfiguration(const path &json_file) -> void {
-  if (!json_configuration.is_null()) {
+  if (json_configuration.wrapped) {
     throw ConfigurationError("This CaosDB client has already been configured.");
   }
   if (!exists(json_file)) {
@@ -389,22 +394,27 @@ auto ConfigurationManager::mLoadSingleJSONConfiguration(const path &json_file) -
 
 auto ConfigurationManager::mGetConnectionConfiguration(const std::string &name) const
   -> std::unique_ptr<ConnectionConfiguration> {
-  auto connection_json = GetConnection(name);
-  return connection_configuration_helper.CreateConnectionConfiguration(connection_json);
+  GET_CONNECTIONS
+  if (connections.contains(name)) {
+    const auto &result_connection = connections.at(name);
+    assert(result_connection.is_object());
+    return CreateConnectionConfiguration(result_connection.as_object());
+  }
+  throw ConfigurationError("The connection '" + name + "' has not been defined.");
 }
 
 auto ConfigurationManager::mGetDefaultConnectionName() const -> std::string {
-  auto connections = GetConnections();
+  GET_CONNECTIONS
   if (connections.contains("default")) {
     auto default_connection = connections.at("default");
     if (default_connection.is_object()) {
       // the name is actually "default"
-      return std::string("default");
+      return {"default"};
     } else {
       assert(default_connection.is_string());
       auto default_connection_name = default_connection.as_string();
       // return the string value of connections.default
-      return std::string(default_connection_name.c_str());
+      return {default_connection_name.c_str()};
     }
   }
   if (connections.size() == 1) {
@@ -414,41 +424,6 @@ auto ConfigurationManager::mGetDefaultConnectionName() const -> std::string {
   throw ConfigurationError("Could not determine the default connection.");
 }
 
-auto ConfigurationManager::GetConfiguration() const -> const object & {
-  if (json_configuration.is_null()) {
-    throw ConfigurationError("This CaosDB client has not been configured.");
-  }
-  assert(json_configuration.is_object());
-  return json_configuration.as_object();
-}
-
-auto ConfigurationManager::GetConnections() const -> const object & {
-  const auto &configuration = GetConfiguration();
-  if (!configuration.contains("connections")) {
-    throw ConfigurationError("This CaosDB client hasn't any configured connections.");
-  }
-  const auto &connections_value = configuration.at("connections");
-  if (connections_value.is_null()) {
-    throw ConfigurationError("This CaosDB client hasn't any configured connections.");
-  }
-  assert(connections_value.is_object());
-  const auto &connections_object = connections_value.as_object();
-  if (connections_object.empty()) {
-    throw ConfigurationError("This CaosDB client hasn't any configured connections.");
-  }
-  return connections_object;
-}
-
-auto ConfigurationManager::GetConnection(const std::string &name) const -> const object & {
-  const auto &connections = GetConnections();
-  if (connections.contains(name)) {
-    const auto &result_connection = connections.at(name);
-    assert(result_connection.is_object());
-    return result_connection.as_object();
-  }
-  throw ConfigurationError("The connection '" + name + "' has not been defined.");
-}
-
 // TODO(tf) This has apparently a cognitive complexity of 34>25 (threshold).
 auto ConfigurationManager::InitializeDefaults() -> int { // NOLINT
 
@@ -496,11 +471,10 @@ auto ConfigurationManager::InitializeDefaults() -> int { // NOLINT
   }
 
   // Logging in the configuration leads to additional content.
-  if (this->json_configuration.is_object() &&
-      this->json_configuration.as_object().contains("logging")) {
+  if (this->json_configuration.wrapped && WRAPPED_JSON_CONFIGURATION(this)->is_object() &&
+      WRAPPED_JSON_CONFIGURATION(this)->as_object().contains("logging")) {
     LoggingConfiguration logging_configuration =
-      logging_configuration_helper.CreateLoggingConfiguration(
-        json_configuration.at("logging").as_object());
+      CreateLoggingConfiguration(WRAPPED_JSON_CONFIGURATION(this)->at("logging").as_object());
     logging::initialize_logging(logging_configuration);
   } else {
     logging::initialize_logging_defaults();
@@ -508,8 +482,9 @@ auto ConfigurationManager::InitializeDefaults() -> int { // NOLINT
                                     "We are using the default configuration";
   }
 
-  if (configuration_file_path != nullptr && this->json_configuration.is_object()) {
-    CAOSDB_LOG_INFO(logger_name) << "Loaded configuration from " << *(configuration_file_path.get())
+  if (configuration_file_path != nullptr && this->json_configuration.wrapped &&
+      WRAPPED_JSON_CONFIGURATION(this)->is_object()) {
+    CAOSDB_LOG_INFO(logger_name) << "Loaded configuration from " << *(configuration_file_path)
                                  << ".";
   }
 
diff --git a/src/caosdb/entity.cpp b/src/caosdb/entity.cpp
index 127d5b4e41ef5b859bbb17d5ebcec1b2c678fa43..568cc5d97c38c8af0bf8fd632d93cb9b9bc4b2f1 100644
--- a/src/caosdb/entity.cpp
+++ b/src/caosdb/entity.cpp
@@ -25,7 +25,6 @@
 #include "caosdb/protobuf_helper.h"   // for get_arena
 #include "caosdb/value.h"             // for Value
 #include <google/protobuf/arena.h>    // for Arena
-#include <new>                        // for operator new
 
 namespace caosdb::entity {
 using ProtoParent = caosdb::entity::v1::Parent;
diff --git a/src/caosdb/file_transmission/download_request_handler.cpp b/src/caosdb/file_transmission/download_request_handler.cpp
index 23520e0d78c5c8c8606ad5acf7611ba7c4806fc4..6d2df655acde2cec564c1ac6bf308bac2c9eca82 100644
--- a/src/caosdb/file_transmission/download_request_handler.cpp
+++ b/src/caosdb/file_transmission/download_request_handler.cpp
@@ -47,16 +47,11 @@
  * > DEALINGS IN THE SOFTWARE.
  */
 #include "caosdb/file_transmission/download_request_handler.h"
-#include "caosdb/logging.h"                            // for CAOSDB_LOG_TRACE
-#include "caosdb/protobuf_helper.h"                    // for get_arena
-#include "caosdb/status_code.h"                        // for GENERIC_RPC_E...
-#include "caosdb/transaction_status.h"                 // for TransactionStatus
-#include <boost/log/core/record.hpp>                   // for record
-#include <boost/log/detail/attachable_sstream_buf.hpp> // for basic_ostring...
-#include <boost/log/sources/record_ostream.hpp>        // for basic_record_...
-#include <boost/preprocessor/seq/limits/enum_256.hpp>  // for BOOST_PP_SEQ_...
-#include <boost/preprocessor/seq/limits/size_256.hpp>  // for BOOST_PP_SEQ_...
-#include <exception>                                   // IWYU pragma: keep
+#include "caosdb/logging.h"            // for CAOSDB_LOG_TRACE
+#include "caosdb/protobuf_helper.h"    // for get_arena
+#include "caosdb/status_code.h"        // for GENERIC_RPC_E...
+#include "caosdb/transaction_status.h" // for TransactionStatus
+#include <exception>                   // IWYU pragma: keep
 // IWYU pragma: no_include <bits/exception.h>
 #include <filesystem>                             // for operator<<, path
 #include <google/protobuf/arena.h>                // for Arena
@@ -65,7 +60,6 @@
 #include <grpcpp/impl/codegen/completion_queue.h> // for CompletionQueue
 #include <grpcpp/impl/codegen/status.h>           // for Status
 #include <grpcpp/impl/codegen/status_code_enum.h> // for OK, UNAUTHENT...
-#include <sstream>                                // for streamsize
 #include <stdexcept>                              // for runtime_error
 #include <string>                                 // for string, opera...
 #include <utility>                                // for move
diff --git a/src/caosdb/file_transmission/register_file_upload_handler.cpp b/src/caosdb/file_transmission/register_file_upload_handler.cpp
index 7b5c18c83729060768d882132067c5c8dd496d67..9460d187e883d843dae21c9e4e3ba00376ecbb01 100644
--- a/src/caosdb/file_transmission/register_file_upload_handler.cpp
+++ b/src/caosdb/file_transmission/register_file_upload_handler.cpp
@@ -47,13 +47,9 @@
  * > DEALINGS IN THE SOFTWARE.
  */
 #include "caosdb/file_transmission/register_file_upload_handler.h"
-#include "caosdb/logging.h"                           // for CAOSDB_LOG_TRACE
-#include <boost/log/core/record.hpp>                  // for record
-#include <boost/log/sources/record_ostream.hpp>       // for basic_record_...
-#include <boost/preprocessor/seq/limits/enum_256.hpp> // for BOOST_PP_SEQ_...
-#include <boost/preprocessor/seq/limits/size_256.hpp> // for BOOST_PP_SEQ_...
-#include <grpcpp/impl/codegen/async_unary_call.h>     // for ClientAsyncRes...
-#include <grpcpp/impl/codegen/completion_queue.h>     // for CompletionQueue
+#include "caosdb/logging.h"                       // for CAOSDB_LOG_TRACE
+#include <grpcpp/impl/codegen/async_unary_call.h> // for ClientAsyncRes...
+#include <grpcpp/impl/codegen/completion_queue.h> // for CompletionQueue
 
 namespace caosdb::transaction {
 
diff --git a/src/caosdb/file_transmission/upload_request_handler.cpp b/src/caosdb/file_transmission/upload_request_handler.cpp
index 71f1106b78397a435638a0a1695bb86cb02a3edc..2f2d2c08db213bea30a3b2635b15d7eb38e249a2 100644
--- a/src/caosdb/file_transmission/upload_request_handler.cpp
+++ b/src/caosdb/file_transmission/upload_request_handler.cpp
@@ -47,18 +47,13 @@
  * > DEALINGS IN THE SOFTWARE.
  */
 #include "caosdb/file_transmission/upload_request_handler.h"
-#include "caosdb/logging.h"                            // for CAOSDB_LOG_ERROR
-#include "caosdb/protobuf_helper.h"                    // for get_arena
-#include "caosdb/status_code.h"                        // for GENERIC_RPC_E...
-#include "caosdb/transaction_status.h"                 // for TransactionStatus
-#include <algorithm>                                   // for min
-#include <boost/log/core/record.hpp>                   // for record
-#include <boost/log/detail/attachable_sstream_buf.hpp> // for basic_ostring...
-#include <boost/log/sources/record_ostream.hpp>        // for basic_record_...
-#include <boost/preprocessor/seq/limits/enum_256.hpp>  // for BOOST_PP_SEQ_...
-#include <boost/preprocessor/seq/limits/size_256.hpp>  // for BOOST_PP_SEQ_...
-#include <cstdint>                                     // for uint64_t
-#include <exception>                                   // IWYU pragma: keep
+#include "caosdb/logging.h"            // for CAOSDB_LOG_ERROR
+#include "caosdb/protobuf_helper.h"    // for get_arena
+#include "caosdb/status_code.h"        // for GENERIC_RPC_E...
+#include "caosdb/transaction_status.h" // for TransactionStatus
+#include <algorithm>                   // for min
+#include <cstdint>                     // for uint64_t
+#include <exception>                   // IWYU pragma: keep
 // IWYU pragma: no_include <bits/exception.h>
 #include <filesystem>                             // for operator<<, path
 #include <google/protobuf/arena.h>                // for Arena
@@ -68,7 +63,6 @@
 #include <grpcpp/impl/codegen/completion_queue.h> // for CompletionQueue
 #include <grpcpp/impl/codegen/status.h>           // for Status
 #include <grpcpp/impl/codegen/status_code_enum.h> // for OK, UNAUTHENT...
-#include <sstream>                                // for streamsize
 #include <string>                                 // for basic_string
 #include <utility>                                // for move
 
@@ -154,7 +148,7 @@ void UploadRequestHandler::handleSendingHeaderState() {
 }
 
 void UploadRequestHandler::handleSendingFileState() {
-  const uint64_t DefaultChunkSize = 4 * 1024; // 4K
+  const auto DefaultChunkSize = static_cast<uint64_t>(4 * 1024); // 4K
 
   auto chunkSize = std::min(DefaultChunkSize, bytesToSend_);
 
diff --git a/src/caosdb/logging.cpp b/src/caosdb/logging.cpp
index 22cda0b65f5428fe485f62972fde3aac70f84080..cdd505877850bc0adc06b15a85f80fdc9ce3a653 100644
--- a/src/caosdb/logging.cpp
+++ b/src/caosdb/logging.cpp
@@ -25,25 +25,86 @@
 #include <boost/log/attributes/clock.hpp>
 #include <boost/log/core/core.hpp> // for core
 #include <boost/log/core/record.hpp>
+#include <boost/log/detail/attachable_sstream_buf.hpp>
 #include <boost/log/sources/record_ostream.hpp>
 #include <boost/log/sources/severity_channel_logger.hpp>
 #include <boost/log/utility/setup/from_settings.hpp>
 #include <boost/log/utility/setup/settings.hpp>
-#include <boost/move/utility_core.hpp> // for move
 #include <boost/multi_index/detail/bidir_node_iterator.hpp>
 #include <boost/operators.hpp>
 #include <boost/preprocessor/seq/limits/enum_256.hpp>
 #include <boost/preprocessor/seq/limits/size_256.hpp>
 #include <boost/property_tree/detail/exception_implementation.hpp>
+#include <boost/smart_ptr/intrusive_ptr.hpp>
+#include <boost/smart_ptr/intrusive_ref_counter.hpp>
 #include <boost/smart_ptr/shared_ptr.hpp>
-#include <boost/tuple/detail/tuple_basic.hpp> // for get
+#include <cstdint> // for uint64_t
 #include <memory>
+#include <ostream> // for ostream
 #include <sstream>
 #include <string>
 #include <utility> // for move
 #include <vector>
 
 namespace caosdb::logging {
+using boost_logger_class = boost::log::sources::severity_channel_logger_mt<int, std::string>;
+
+class logger {
+public:
+  static auto get() -> boost_logger_class & { return logger::GetInstance()._logger_instance; }
+
+private:
+  static logger &GetInstance() {
+    static logger instance;
+    return instance;
+  }
+  boost_logger_class _logger_instance;
+};
+
+LoggerOutputStream::LoggerOutputStream(std::string channel, int level)
+  : channel(std::move(channel)), level(level) {}
+
+auto LoggerOutputStream::operator<<(std::streambuf *msg) -> LoggerOutputStream & {
+  BOOST_LOG_CHANNEL_SEV(caosdb::logging::logger::get(), channel, this->level) << msg;
+
+  return *this;
+}
+
+auto LoggerOutputStream::operator<<(int msg) -> LoggerOutputStream & {
+  BOOST_LOG_CHANNEL_SEV(caosdb::logging::logger::get(), channel, this->level) << msg;
+
+  return *this;
+}
+
+auto LoggerOutputStream::operator<<(int64_t msg) -> LoggerOutputStream & {
+  BOOST_LOG_CHANNEL_SEV(caosdb::logging::logger::get(), channel, this->level) << msg;
+
+  return *this;
+}
+
+auto LoggerOutputStream::operator<<(uint64_t msg) -> LoggerOutputStream & {
+  BOOST_LOG_CHANNEL_SEV(caosdb::logging::logger::get(), channel, this->level) << msg;
+
+  return *this;
+}
+
+auto LoggerOutputStream::operator<<(const char *msg) -> LoggerOutputStream & {
+  BOOST_LOG_CHANNEL_SEV(caosdb::logging::logger::get(), channel, this->level) << msg;
+
+  return *this;
+}
+
+auto LoggerOutputStream::operator<<(const std::string &msg) -> LoggerOutputStream & {
+  BOOST_LOG_CHANNEL_SEV(caosdb::logging::logger::get(), channel, this->level) << msg;
+
+  return *this;
+}
+
+auto LoggerOutputStream::operator<<(void *msg) -> LoggerOutputStream & {
+  BOOST_LOG_CHANNEL_SEV(caosdb::logging::logger::get(), channel, this->level) << msg;
+
+  return *this;
+}
 
 LoggingConfiguration::LoggingConfiguration(int level) : LevelConfiguration(level) {}
 
@@ -61,13 +122,14 @@ SinkConfiguration::SinkConfiguration(std::string name, int level)
 
 [[nodiscard]] auto SinkConfiguration::GetName() const -> const std::string & { return this->name; }
 
-auto SinkConfiguration::Configure(boost::log::settings &settings) const -> void {
-  CAOSDB_LOG_TRACE(logger_name) << "Enter SinkConfiguration::Configure(&settings)";
+auto SinkConfiguration::Configure(void *settings) const -> void {
+  CAOSDB_LOG_TRACE(logger_name) << "Enter SinkConfiguration::Configure(*settings)";
   auto sink = "Sinks." + GetName();
-  settings[sink]["Destination"] = GetDestination();
-  settings[sink]["Filter"] = "%Severity% >= " + std::to_string(GetLevel());
-  settings[sink]["AutoFlush"] = true;
-  settings[sink]["Format"] = "[%TimeStamp%][%Severity%] %Channel% - %Message%";
+  auto *boost_settings = static_cast<boost::log::settings *>(settings);
+  (*boost_settings)[sink]["Destination"] = GetDestination();
+  (*boost_settings)[sink]["Filter"] = "%Severity% >= " + std::to_string(GetLevel());
+  (*boost_settings)[sink]["AutoFlush"] = true;
+  (*boost_settings)[sink]["Format"] = "[%TimeStamp%][%Severity%] %Channel% - %Message%";
 }
 
 ConsoleSinkConfiguration::ConsoleSinkConfiguration(const std::string &name, int level)
@@ -78,8 +140,8 @@ ConsoleSinkConfiguration::ConsoleSinkConfiguration(const std::string &name, int
   return this->destination;
 }
 
-auto ConsoleSinkConfiguration::Configure(boost::log::settings &settings) const -> void {
-  CAOSDB_LOG_TRACE(logger_name) << "Enter ConsoleSinkConfiguration::Configure(&settings)";
+auto ConsoleSinkConfiguration::Configure(void *settings) const -> void {
+  CAOSDB_LOG_TRACE(logger_name) << "Enter ConsoleSinkConfiguration::Configure(*settings)";
   sink_configuration::Configure(settings);
 }
 
@@ -95,10 +157,11 @@ auto FileSinkConfiguration::SetDirectory(const std::string &directory) -> void {
   this->directory = std::string(directory);
 }
 
-auto FileSinkConfiguration::Configure(boost::log::settings &settings) const -> void {
-  CAOSDB_LOG_TRACE(logger_name) << "Enter FileSinkConfiguration::Configure(&settings)";
+auto FileSinkConfiguration::Configure(void *settings) const -> void {
+  CAOSDB_LOG_TRACE(logger_name) << "Enter FileSinkConfiguration::Configure(*settings)";
   sink_configuration::Configure(settings);
-  settings["Sink." + GetName() + ".Target"] = this->directory;
+  auto *boost_settings = static_cast<boost::log::settings *>(settings);
+  (*boost_settings)["Sink." + GetName() + ".Target"] = this->directory;
 }
 
 SyslogSinkConfiguration::SyslogSinkConfiguration(const std::string &name, int level)
@@ -127,7 +190,7 @@ auto initialize_logging_defaults() -> int {
   default_settings["Core.DisableLogging"] = false;
 
   for (const auto &sink : default_sinks) {
-    sink->Configure(default_settings);
+    sink->Configure(&default_settings);
   }
 
   boost::log::init_from_settings(default_settings);
@@ -158,7 +221,7 @@ auto initialize_logging(const LoggingConfiguration &configuration) -> void {
   new_settings["Core.DisableLogging"] = false;
 
   for (const auto &sink : configuration.GetSinks()) {
-    sink->Configure(new_settings);
+    sink->Configure(&new_settings);
   }
 
   boost::log::init_from_settings(new_settings);
@@ -167,27 +230,27 @@ auto initialize_logging(const LoggingConfiguration &configuration) -> void {
 }
 
 void caosdb_log_fatal(const char *channel, const char *msg) {
-  BOOST_LOG_CHANNEL_SEV(caosdb::logging::logger::get(), channel, CAOSDB_LOG_LEVEL_FATAL) << msg;
+  LoggerOutputStream::get(channel, CAOSDB_LOG_LEVEL_FATAL) << msg;
 }
 
 void caosdb_log_error(const char *channel, const char *msg) {
-  BOOST_LOG_CHANNEL_SEV(caosdb::logging::logger::get(), channel, CAOSDB_LOG_LEVEL_ERROR) << msg;
+  LoggerOutputStream::get(channel, CAOSDB_LOG_LEVEL_ERROR) << msg;
 }
 
 void caosdb_log_warn(const char *channel, const char *msg) {
-  BOOST_LOG_CHANNEL_SEV(caosdb::logging::logger::get(), channel, CAOSDB_LOG_LEVEL_WARN) << msg;
+  LoggerOutputStream::get(channel, CAOSDB_LOG_LEVEL_WARN) << msg;
 }
 
 void caosdb_log_info(const char *channel, const char *msg) {
-  BOOST_LOG_CHANNEL_SEV(caosdb::logging::logger::get(), channel, CAOSDB_LOG_LEVEL_INFO) << msg;
+  LoggerOutputStream::get(channel, CAOSDB_LOG_LEVEL_INFO) << msg;
 }
 
 void caosdb_log_debug(const char *channel, const char *msg) {
-  BOOST_LOG_CHANNEL_SEV(caosdb::logging::logger::get(), channel, CAOSDB_LOG_LEVEL_DEBUG) << msg;
+  LoggerOutputStream::get(channel, CAOSDB_LOG_LEVEL_DEBUG) << msg;
 }
 
 void caosdb_log_trace(const char *channel, const char *msg) {
-  BOOST_LOG_CHANNEL_SEV(caosdb::logging::logger::get(), channel, CAOSDB_LOG_LEVEL_TRACE) << msg;
+  LoggerOutputStream::get(channel, CAOSDB_LOG_LEVEL_TRACE) << msg;
 }
 
 } // namespace caosdb::logging
diff --git a/src/caosdb/transaction.cpp b/src/caosdb/transaction.cpp
index 4c4bbda601d358c60fffa0537532d28a3699bb86..e3e5ecff34a1e6200b508f337b2d80f4505359bf 100644
--- a/src/caosdb/transaction.cpp
+++ b/src/caosdb/transaction.cpp
@@ -28,22 +28,17 @@
 #include "caosdb/status_code.h"                                    // for StatusCode
 #include "caosdb/transaction_handler.h"                            // for EntityTransactionHandler
 #include <algorithm>                                               // for max
-#include <boost/log/core/record.hpp>                               // for record
-#include <boost/log/detail/attachable_sstream_buf.hpp>             // for basic_ostring...
-#include <boost/log/sources/record_ostream.hpp>                    // for basic_record_...
-#include <boost/preprocessor/seq/limits/enum_256.hpp>              // for BOOST_PP_SEQ_...
-#include <boost/preprocessor/seq/limits/size_256.hpp>              // for BOOST_PP_SEQ_...
+#include <exception>                                               // IWYU pragma: keep
+#include <filesystem>                                              // for operator<<, path
+#include <google/protobuf/arena.h>                                 // for Arena
+#include <grpc/impl/codegen/gpr_types.h>                           // for gpr_timespec
+#include <grpcpp/impl/codegen/completion_queue.h>                  // for CompletionQueue
+#include <map>                                                     // for map, operator!=
+#include <memory>                                                  // for unique_ptr
+#include <random>                                                  // for mt19937, rand...
+#include <utility>                                                 // for move, pair
 // IWYU pragma: no_include <bits/exception.h>
-#include <exception>                              // IWYU pragma: keep
-#include <filesystem>                             // for operator<<, path
-#include <google/protobuf/arena.h>                // for Arena
-#include <grpc/impl/codegen/gpr_types.h>          // for gpr_timespec
-#include <grpcpp/impl/codegen/completion_queue.h> // for CompletionQueue
-#include <map>                                    // for map, operator!=
-#include <memory>                                 // for unique_ptr
-#include <random>                                 // for mt19937, rand...
-#include <sstream>
-#include <utility> // for move, pair
+// IWYU pragma: no_include "net/proto2/public/repeated_field.h"
 
 namespace caosdb::transaction {
 using caosdb::entity::v1::EntityTransactionService;
@@ -89,12 +84,9 @@ MultiResultSet::MultiResultSet(std::vector<std::unique_ptr<Entity>> result_set)
 
 Transaction::Transaction(std::shared_ptr<EntityTransactionService::Stub> entity_service,
                          std::shared_ptr<FileTransmissionService::Stub> file_service)
-  : request(Arena::CreateMessage<MultiTransactionRequest>(GetArena())),
-    response(Arena::CreateMessage<MultiTransactionResponse>(GetArena())) {
-  this->entity_service = std::move(entity_service);
-  this->file_service = std::move(file_service);
-  this->query_count = -1;
-}
+  : entity_service(std::move(entity_service)), file_service(std::move(file_service)),
+    request(Arena::CreateMessage<MultiTransactionRequest>(GetArena())),
+    response(Arena::CreateMessage<MultiTransactionResponse>(GetArena())), query_count(-1) {}
 
 auto Transaction::RetrieveById(const std::string &id) noexcept -> StatusCode {
   ASSERT_CAN_ADD_RETRIEVAL
diff --git a/src/caosdb/transaction_handler.cpp b/src/caosdb/transaction_handler.cpp
index e97e626139dd967353491310627f96acefbdb8eb..fd2b527e47dc411290ef05d629899c335788bc36 100644
--- a/src/caosdb/transaction_handler.cpp
+++ b/src/caosdb/transaction_handler.cpp
@@ -1,15 +1,9 @@
 #include "caosdb/transaction_handler.h"
-#include "caosdb/logging.h"                            // for CAOSDB_LOG_TRACE
-#include <boost/log/core/record.hpp>                   // for record
-#include <boost/log/detail/attachable_sstream_buf.hpp> // for basic_ostring...
-#include <boost/log/sources/record_ostream.hpp>        // for basic_record_...
-#include <boost/preprocessor/seq/limits/enum_256.hpp>  // for BOOST_PP_SEQ_...
-#include <boost/preprocessor/seq/limits/size_256.hpp>  // for BOOST_PP_SEQ_...
-#include <exception>                                   // IWYU pragma: keep
+#include "caosdb/logging.h" // for CAOSDB_LOG_TRACE
+#include <exception>        // IWYU pragma: keep
 // IWYU pragma: no_include <bits/exception.h>
 #include <grpcpp/impl/codegen/async_unary_call.h> // for ClientAsyncRes...
 #include <grpcpp/impl/codegen/completion_queue.h> // for CompletionQueue
-#include <iosfwd>                                 // for streamsize
 
 namespace caosdb::transaction {
 
diff --git a/src/caosdb/unary_rpc_handler.cpp b/src/caosdb/unary_rpc_handler.cpp
index 9a61a534ec30da943f7637d9995a2595acf96804..86320ca2a94b0b67bd362e0e76fe0f31ddd78007 100644
--- a/src/caosdb/unary_rpc_handler.cpp
+++ b/src/caosdb/unary_rpc_handler.cpp
@@ -47,19 +47,13 @@
  * > DEALINGS IN THE SOFTWARE.
  */
 #include "caosdb/unary_rpc_handler.h"
-#include "caosdb/logging.h"                            // for CAOSDB_LOG_TRACE
-#include "caosdb/status_code.h"                        // for GENERIC_RPC_E...
-#include <boost/log/core/record.hpp>                   // for record
-#include <boost/log/detail/attachable_sstream_buf.hpp> // for basic_ostring...
-#include <boost/log/sources/record_ostream.hpp>        // for basic_record_...
-#include <boost/preprocessor/seq/limits/enum_256.hpp>  // for BOOST_PP_SEQ_...
-#include <boost/preprocessor/seq/limits/size_256.hpp>  // for BOOST_PP_SEQ_...
+#include "caosdb/logging.h"     // for CAOSDB_LOG_TRACE
+#include "caosdb/status_code.h" // for GENERIC_RPC_E...
 // IWYU pragma: no_include <bits/exception.h>
 #include <exception>                              // IWYU pragma: keep
 #include <grpcpp/impl/codegen/client_context.h>   // for ClientContext
 #include <grpcpp/impl/codegen/status.h>           // for Status
 #include <grpcpp/impl/codegen/status_code_enum.h> // for OK, UNAUTHENT...
-#include <iosfwd>                                 // for streamsize
 #include <string>                                 // for string, opera...
 
 namespace caosdb::transaction {
diff --git a/src/caosdb/utility.cpp b/src/caosdb/utility.cpp
index a4ed293adb6bd4fbfb10860e03185aeb567de163..ca7e1cbe9102763ed54763f7ca1dd271ed0b06db 100644
--- a/src/caosdb/utility.cpp
+++ b/src/caosdb/utility.cpp
@@ -19,18 +19,35 @@
  *
  */
 #include "caosdb/utility.h"
-#include "caosdb/data_type.h" // for AtomicDataType, atomicdatatype_names
-#include "caosdb/entity.h"    // for Importance, Role, importance_names
-#include <map>                // for map, operator!=, _Rb_tree_const_iterator
-#include <utility>            // for pair
+#include "caosdb/data_type.h"                 // for AtomicDataType, atomicdatatype_names
+#include "caosdb/entity.h"                    // for Importance, Role, importance_names
+#include <boost/beast/core/detail/base64.hpp> // for encoded_size
+#include <boost/beast/core/detail/base64.ipp> // for encode
+#include <boost/filesystem/string_file.hpp>   // for load_string_file
+#include <boost/json/stream_parser.hpp>       // for stream_parser
+#include <boost/json/value.hpp>               // for value
+#include <cassert>                            // for assert
+#include <map>                                // for map, operator!=, _Rb_tree_const_iterator
+#include <memory>                             // for allocator, unique_ptr
+#include <stdexcept>                          // for logic_error
+#include <type_traits>                        // for underlying_type_t
+#include <typeinfo>                           // for type_info
+#include <utility>                            // for pair
 
 namespace caosdb::utility {
 
+using boost::json::stream_parser;
+using boost::json::value;
 using caosdb::entity::AtomicDataType;
 using caosdb::entity::Importance;
 using caosdb::entity::Role;
 
-// using emap = std::map<int, std::string>;          // enum mapping
+template <typename Enum> auto getEnumNameFromValue(Enum v) -> std::string {
+  if (std::is_same_v<std::underlying_type_t<Enum>, int>) {
+    return std::to_string(static_cast<int>(v));
+  }
+  throw std::logic_error(std::string("Enum type ") + typeid(v).name() + " not implemented.");
+}
 
 // Enum helper template specializations //////////////////////////////////////
 template <> auto getEnumNameFromValue<Importance>(Importance v) -> std::string {
@@ -87,4 +104,82 @@ template <> auto getEnumValueFromName<Role>(const std::string &name) -> Role {
 
 // End of template specialization /////////////////////////////////////////////
 
+auto load_string_file(const path &file_path) -> std::string {
+  std::string result;
+  boost::filesystem::load_string_file(file_path.string(), result);
+  return result;
+}
+
+auto base64_encode(const std::string &plain) -> std::string {
+  auto size_plain = plain.size();
+  auto size_encoded = boost::beast::detail::base64::encoded_size(size_plain);
+
+  std::string result = std::string(size_encoded, '\0');
+  boost::beast::detail::base64::encode(&result[0], plain.c_str(), size_plain);
+
+  return result;
+}
+
+auto _load_json_file(const path &json_file) -> value {
+  assert(exists(json_file));
+
+  constexpr auto buffer_size = std::size_t(4096);
+  auto stream = ifstream(json_file);
+  stream.exceptions(std::ios_base::badbit);
+
+  stream_parser parser;
+  auto result = std::string();
+  auto buffer = std::string(buffer_size, '\0');
+  while (stream.read(&buffer[0], buffer_size)) {
+    parser.write(buffer.c_str(), stream.gcount());
+  }
+  parser.write(buffer.c_str(), stream.gcount());
+
+  assert(parser.done());
+  return parser.release();
+}
+
+auto load_json_file(const path &json_file) -> JsonValue {
+  return {new value(_load_json_file(json_file))};
+}
+
+JsonValue::JsonValue(void *wrapped) { this->wrapped.reset(static_cast<value *>(wrapped)); }
+
+JsonValue::~JsonValue() = default;
+
+auto JsonValue::Reset() -> void {
+  if (this->wrapped) {
+    this->wrapped.reset();
+  }
+}
+
+JsonValue::JsonValue(const JsonValue &other) {
+  if (other.wrapped) {
+    this->wrapped.reset(static_cast<value *>(other.wrapped.get()));
+  }
+}
+
+auto JsonValue::operator=(const JsonValue &other) -> JsonValue & {
+  if (this != &other) {
+    if (other.wrapped) {
+      this->wrapped = std::make_shared<value>(*(static_cast<value *>(other.wrapped.get())));
+    }
+  }
+  return *this;
+}
+
+JsonValue::JsonValue(JsonValue &&other) noexcept {
+  if (other.wrapped) {
+    this->wrapped = std::move(other.wrapped);
+  }
+}
+
+auto JsonValue::operator=(JsonValue &&other) noexcept -> JsonValue & {
+  if (this != &other) {
+    Reset();
+    this->wrapped = std::move(other.wrapped);
+  }
+  return *this;
+}
+
 } // namespace caosdb::utility
diff --git a/test/test_data_type.cpp b/test/test_data_type.cpp
index bccc853e283cb00fd6fd1b40838f5a8ac1faae64..6b7b8b6ea3d36135164d73c90e8f45693a49b1cc 100644
--- a/test/test_data_type.cpp
+++ b/test/test_data_type.cpp
@@ -20,23 +20,17 @@
  *
  */
 
-#include "caosdb/data_type.h"                          // for DataType, AtomicDataType
-#include "caosdb/entity.h"                             // for Entity
-#include "caosdb/entity/v1/main.pb.h"                  // for DataType, Ato...
-#include "caosdb/logging.h"                            // for CAOSDB_LOG_DEBUG
-#include "caosdb/protobuf_helper.h"                    // for CAOSDB_DEBUG_...
-#include <boost/log/core/record.hpp>                   // for record
-#include <boost/log/detail/attachable_sstream_buf.hpp> // for basic_ostring...
-#include <boost/log/sources/record_ostream.hpp>        // for operator<<
-#include <boost/preprocessor/seq/limits/enum_256.hpp>  // for BOOST_PP_SEQ_...
-#include <boost/preprocessor/seq/limits/size_256.hpp>  // for BOOST_PP_SEQ_...
-#include <gtest/gtest-message.h>                       // for Message
-#include <gtest/gtest-test-part.h>                     // for TestPartResult, SuiteApi...
-#include <gtest/gtest_pred_impl.h>                     // for AssertionResult, Test
-#include <iosfwd>                                      // for streamsize
-#include <map>                                         // for map, operator!=
-#include <string>                                      // for allocator
-#include <utility>                                     // for pair
+#include "caosdb/data_type.h"         // for DataType, AtomicDataType
+#include "caosdb/entity.h"            // for Entity
+#include "caosdb/entity/v1/main.pb.h" // for DataType, Ato...
+#include "caosdb/logging.h"           // for CAOSDB_LOG_DEBUG
+#include "caosdb/protobuf_helper.h"   // for CAOSDB_DEBUG_...
+#include <gtest/gtest-message.h>      // for Message
+#include <gtest/gtest-test-part.h>    // for TestPartResult, SuiteApi...
+#include <gtest/gtest_pred_impl.h>    // for AssertionResult, Test
+#include <map>                        // for map, operator!=
+#include <string>                     // for allocator
+#include <utility>                    // for pair
 
 namespace caosdb::entity {
 using ProtoEntity = caosdb::entity::v1::Entity;
diff --git a/test/test_entity.cpp b/test/test_entity.cpp
index 5f5aaaab4a5f6727f38ea30c0205ea8d79a925b1..a42e91781922c5e8b9530663b5bdbc53d4532fe3 100644
--- a/test/test_entity.cpp
+++ b/test/test_entity.cpp
@@ -39,6 +39,7 @@
 #include <stdexcept>                       // for out_of_range
 #include <string>                          // for operator+, to_string
 #include <utility>                         // for move
+// IWYU pragma: no_include "net/proto2/public/repeated_field.h"
 
 namespace caosdb::entity {
 using caosdb::entity::v1::IdResponse;
diff --git a/test/test_utility.cpp b/test/test_utility.cpp
index 3a9a420cee742c1001c727a6154452ee10e8d8fb..74db29afa798ccdbf9d4be45497e1a44762d630d 100644
--- a/test/test_utility.cpp
+++ b/test/test_utility.cpp
@@ -20,10 +20,7 @@
  *
  */
 
-#include "gmock/gmock-matchers.h"             // for ElementsAre, EXPECT_THAT
 #include "boost/beast/core/detail/base64.hpp" // for encoded_size
-#include "boost/json/object.hpp"              // for object
-#include "boost/json/value.hpp"               // for value
 #include "caosdb/data_type.h"                 // for atomicdatatype_names
 #include "caosdb/entity.h"                    // for importance_names, role...
 #include "caosdb/status_code.h"               // for get_status_description
@@ -38,7 +35,6 @@
 #include <utility>                            // for pair
 
 namespace caosdb::utility {
-using ::testing::ElementsAre;
 
 TEST(test_utility, base64_encode) {
   auto test_plain = std::string("admin:caosdb");
@@ -48,17 +44,6 @@ TEST(test_utility, base64_encode) {
   EXPECT_EQ(test_encoded, base64_encode(test_plain));
 }
 
-TEST(test_utility, test_load_json_file) {
-  auto json = load_json_file(TEST_DATA_DIR + "/test.json").as_object();
-
-  EXPECT_EQ(json["it"], "tests");
-  EXPECT_EQ(json["null values"], nullptr);
-  EXPECT_THAT(json["this"].as_array(), ElementsAre("is", "a", "test"));
-  EXPECT_THAT(json["numbers"].as_array(), ElementsAre(1, 2, 3.3));
-  auto sub = json["arrays and objects"].as_object();
-  EXPECT_THAT(sub["see?"].as_array(), ElementsAre(true, false));
-}
-
 TEST(test_utility, enum_names) {
   // All working enums
   for (const auto &entry : caosdb::entity::importance_names) {