diff --git a/src/abort.cpp b/src/abort.cpp
new file mode 100644
index 0000000..c612f2b
--- /dev/null
+++ b/src/abort.cpp
@@ -0,0 +1,31 @@
+/*
+   Copyright (c) 2018-2019 Nokia.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+#include <ostream>
+#include <sstream>
+#include <string>
+#include "private/abort.hpp"
+#include "private/createlogger.hpp"
+
+using namespace shareddatalayer;
+
+void shareddatalayer::logAndAbort(const std::string& file, int line, const std::string& message) noexcept
+{
+    std::ostringstream msg;
+    msg << "SHAREDDATALAYER_ABORT, file " << file << ", line " << line << ": " << message;
+    logErrorOnce(msg.str());
+    abort();
+}
diff --git a/src/asyncconnection.cpp b/src/asyncconnection.cpp
new file mode 100644
index 0000000..4acfead
--- /dev/null
+++ b/src/asyncconnection.cpp
@@ -0,0 +1,21 @@
+/*
+   Copyright (c) 2018-2019 Nokia.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+#include "private/asyncconnection.hpp"
+
+using namespace shareddatalayer;
+
+const char AsyncConnection::SEPARATOR(',');
diff --git a/src/asyncdummystorage.cpp b/src/asyncdummystorage.cpp
new file mode 100644
index 0000000..24e85a6
--- /dev/null
+++ b/src/asyncdummystorage.cpp
@@ -0,0 +1,86 @@
+/*
+   Copyright (c) 2018-2019 Nokia.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+#include "private/asyncdummystorage.hpp"
+#include <sys/eventfd.h>
+#include "private/engine.hpp"
+
+using namespace shareddatalayer;
+
+AsyncDummyStorage::AsyncDummyStorage(std::shared_ptr<Engine> engine):
+    engine(engine)
+{
+}
+
+int AsyncDummyStorage::fd() const
+{
+    return engine->fd();
+}
+
+void AsyncDummyStorage::handleEvents()
+{
+    engine->handleEvents();
+}
+
+void AsyncDummyStorage::postCallback(const Callback& callback)
+{
+    engine->postCallback(callback);
+}
+
+void AsyncDummyStorage::waitReadyAsync(const Namespace&, const ReadyAck& readyAck)
+{
+    postCallback(std::bind(readyAck, std::error_code()));
+}
+
+void AsyncDummyStorage::setAsync(const Namespace&, const DataMap&, const ModifyAck& modifyAck)
+{
+    postCallback(std::bind(modifyAck, std::error_code()));
+}
+
+void AsyncDummyStorage::setIfAsync(const Namespace&, const Key&, const Data&, const Data&, const ModifyIfAck& modifyIfAck)
+{
+    postCallback(std::bind(modifyIfAck, std::error_code(), true));
+}
+
+void AsyncDummyStorage::setIfNotExistsAsync(const Namespace&, const Key&, const Data&, const ModifyIfAck& modifyIfAck)
+{
+    postCallback(std::bind(modifyIfAck, std::error_code(), true));
+}
+
+void AsyncDummyStorage::getAsync(const Namespace&, const Keys&, const GetAck& getAck)
+{
+    postCallback(std::bind(getAck, std::error_code(), DataMap()));
+}
+
+void AsyncDummyStorage::removeAsync(const Namespace&, const Keys&, const ModifyAck& modifyAck)
+{
+    postCallback(std::bind(modifyAck, std::error_code()));
+}
+
+void AsyncDummyStorage::removeIfAsync(const Namespace&, const Key&, const Data&, const ModifyIfAck& modifyIfAck)
+{
+    postCallback(std::bind(modifyIfAck, std::error_code(), true));
+}
+
+void AsyncDummyStorage::findKeysAsync(const Namespace&, const std::string&, const FindKeysAck& findKeysAck)
+{
+    postCallback(std::bind(findKeysAck, std::error_code(), Keys()));
+}
+
+void AsyncDummyStorage::removeAllAsync(const Namespace&, const ModifyAck& modifyAck)
+{
+    postCallback(std::bind(modifyAck, std::error_code()));
+}
diff --git a/src/asyncstorage.cpp b/src/asyncstorage.cpp
new file mode 100644
index 0000000..3b6fe77
--- /dev/null
+++ b/src/asyncstorage.cpp
@@ -0,0 +1,53 @@
+/*
+   Copyright (c) 2018-2019 Nokia.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+#include <boost/optional.hpp>
+#include "config.h"
+#include "private/abort.hpp"
+#include "private/asyncconnection.hpp"
+#include "private/asyncstorageimpl.hpp"
+#include "private/createlogger.hpp"
+#include "private/engineimpl.hpp"
+#include "private/configurationreader.hpp"
+#include "private/databaseconfigurationimpl.hpp"
+#include "private/logger.hpp"
+#if HAVE_REDIS
+#include "private/redis/asyncredisstorage.hpp"
+#include "private/redis/asyncdatabasediscovery.hpp"
+#endif
+
+using namespace shareddatalayer;
+
+namespace
+{
+
+std::unique_ptr<shareddatalayer::AsyncStorage> createInstance(const boost::optional<shareddatalayer::AsyncConnection::PublisherId>& pId)
+{
+    auto engine(std::make_shared<EngineImpl>());
+    auto logger(createLogger(SDL_LOG_PREFIX));
+    /* clang compilation does not support make_unique */
+    return std::unique_ptr<AsyncStorageImpl>(new AsyncStorageImpl(engine, pId, logger));
+}
+
+}
+
+/* clang compilation produces undefined reference linker error without this */
+constexpr char AsyncStorage::SEPARATOR;
+
+std::unique_ptr<AsyncStorage> AsyncStorage::create()
+{
+    return createInstance(boost::none);
+}
diff --git a/src/asyncstorageimpl.cpp b/src/asyncstorageimpl.cpp
new file mode 100644
index 0000000..b17fcbd
--- /dev/null
+++ b/src/asyncstorageimpl.cpp
@@ -0,0 +1,167 @@
+/*
+   Copyright (c) 2018-2019 Nokia.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+#include "config.h"
+#include "private/error.hpp"
+#include "private/abort.hpp"
+#include "private/asyncstorageimpl.hpp"
+#include "private/configurationreader.hpp"
+#include "private/asyncdummystorage.hpp"
+#include "private/engine.hpp"
+#include "private/logger.hpp"
+#if HAVE_REDIS
+#include "private/redis/asyncdatabasediscovery.hpp"
+#include "private/redis/asyncredisstorage.hpp"
+#endif
+
+using namespace shareddatalayer;
+
+AsyncStorageImpl::AsyncStorageImpl(std::shared_ptr<Engine> engine,
+                                   const boost::optional<PublisherId>& pId,
+                                   std::shared_ptr<Logger> logger):
+    engine(engine),
+    databaseConfiguration(std::make_shared<DatabaseConfigurationImpl>()),
+    namespaceConfigurations(std::make_shared<NamespaceConfigurationsImpl>()),
+    publisherId(pId),
+    logger(logger)
+{
+    ConfigurationReader configurationReader(logger);
+    configurationReader.readDatabaseConfiguration(std::ref(*databaseConfiguration));
+    configurationReader.readNamespaceConfigurations(std::ref(*namespaceConfigurations));
+}
+
+// Meant for UT usage
+AsyncStorageImpl::AsyncStorageImpl(std::shared_ptr<Engine> engine,
+                                   const boost::optional<PublisherId>& pId,
+                                   std::shared_ptr<DatabaseConfiguration> databaseConfiguration,
+                                   std::shared_ptr<NamespaceConfigurations> namespaceConfigurations,
+                                   std::shared_ptr<Logger> logger):
+    engine(engine),
+    databaseConfiguration(databaseConfiguration),
+    namespaceConfigurations(namespaceConfigurations),
+    publisherId(pId),
+    logger(logger)
+{
+}
+
+AsyncStorage& AsyncStorageImpl::getRedisHandler()
+{
+#if HAVE_REDIS
+    static AsyncRedisStorage redisHandler{engine,
+                                          redis::AsyncDatabaseDiscovery::create(
+                                              engine,
+                                              boost::none,
+                                              std::ref(*databaseConfiguration),
+                                              logger),
+                                          publisherId,
+                                          namespaceConfigurations,
+                                          logger};
+
+    return redisHandler;
+#else
+    logger->error() << "Redis operations cannot be performed, Redis not enabled";
+    SHAREDDATALAYER_ABORT("Invalid configuration.");
+#endif
+}
+
+AsyncStorage& AsyncStorageImpl::getDummyHandler()
+{
+    static AsyncDummyStorage dummyHandler{engine};
+    return dummyHandler;
+}
+
+AsyncStorage& AsyncStorageImpl::getOperationHandler(const std::string& ns)
+{
+    if (namespaceConfigurations->isDbBackendUseEnabled(ns))
+        return getRedisHandler();
+
+    return getDummyHandler();
+}
+
+int AsyncStorageImpl::fd() const
+{
+    return engine->fd();
+}
+
+void AsyncStorageImpl::handleEvents()
+{
+    engine->handleEvents();
+}
+
+void AsyncStorageImpl::waitReadyAsync(const Namespace& ns,
+                                      const ReadyAck& readyAck)
+{
+    getOperationHandler(ns).waitReadyAsync(ns, readyAck);
+}
+
+void AsyncStorageImpl::setAsync(const Namespace& ns,
+                                const DataMap& dataMap,
+                                const ModifyAck& modifyAck)
+{
+    getOperationHandler(ns).setAsync(ns, dataMap, modifyAck);
+}
+
+void AsyncStorageImpl::setIfAsync(const Namespace& ns,
+                                  const Key& key,
+                                  const Data& oldData,
+                                  const Data& newData,
+                                  const ModifyIfAck& modifyIfAck)
+{
+    getOperationHandler(ns).setIfAsync(ns, key, oldData, newData, modifyIfAck);
+}
+
+void AsyncStorageImpl::removeIfAsync(const Namespace& ns,
+                                     const Key& key,
+                                     const Data& data,
+                                     const ModifyIfAck& modifyIfAck)
+{
+    getOperationHandler(ns).removeIfAsync(ns, key, data, modifyIfAck);
+}
+
+void AsyncStorageImpl::setIfNotExistsAsync(const Namespace& ns,
+                                           const Key& key,
+                                           const Data& data,
+                                           const ModifyIfAck& modifyIfAck)
+{
+    getOperationHandler(ns).setIfNotExistsAsync(ns, key, data, modifyIfAck);
+}
+
+void AsyncStorageImpl::getAsync(const Namespace& ns,
+                                const Keys& keys,
+                                const GetAck& getAck)
+{
+    getOperationHandler(ns).getAsync(ns, keys, getAck);
+}
+
+void AsyncStorageImpl::removeAsync(const Namespace& ns,
+                                   const Keys& keys,
+                                   const ModifyAck& modifyAck)
+{
+    getOperationHandler(ns).removeAsync(ns, keys, modifyAck);
+}
+
+void AsyncStorageImpl::findKeysAsync(const Namespace& ns,
+                                     const std::string& keyPrefix,
+                                     const FindKeysAck& findKeysAck)
+{
+    getOperationHandler(ns).findKeysAsync(ns, keyPrefix, findKeysAck);
+}
+
+void AsyncStorageImpl::removeAllAsync(const Namespace& ns,
+                                       const ModifyAck& modifyAck)
+{
+    getOperationHandler(ns).removeAllAsync(ns, modifyAck);
+}
diff --git a/src/backenderror.cpp b/src/backenderror.cpp
new file mode 100644
index 0000000..3086ea4
--- /dev/null
+++ b/src/backenderror.cpp
@@ -0,0 +1,24 @@
+/*
+   Copyright (c) 2018-2019 Nokia.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+#include <sdl/backenderror.hpp>
+
+using namespace shareddatalayer;
+
+BackendError::BackendError(const std::string& error):
+    Exception(error)
+{
+}
diff --git a/src/cli/commandmap.cpp b/src/cli/commandmap.cpp
new file mode 100644
index 0000000..e0e8304
--- /dev/null
+++ b/src/cli/commandmap.cpp
@@ -0,0 +1,185 @@
+#include "private/cli/commandmap.hpp"
+#include <sstream>
+#include <iomanip>
+#include <memory>
+#include <cstdlib>
+#include <boost/io/ios_state.hpp>
+
+using namespace shareddatalayer::cli;
+
+namespace
+{
+    std::string buildCommandNameAlreadyRegisteredError(const std::string& commandName)
+    {
+        std::ostringstream os;
+        os << "command name \"" << commandName << "\" already registered";
+        return os.str();
+    }
+
+    std::string buildUnknownCommandNameError(const std::string& commandName)
+    {
+        std::ostringstream os;
+        os << "unknown command: \"" << commandName << '\"';
+        return os.str();
+    }
+
+    std::string buildCategoryOffsetAlreadyRegisteredError(const std::string& commandName, int offset)
+    {
+        std::ostringstream os;
+        os << commandName << ": Offset " << offset << " already registered";
+        return os.str();
+    }
+
+    std::string getCategoryName(CommandMap::Category category)
+    {
+        switch (category)
+        {
+            case CommandMap::Category::UTIL:
+                return "Utility";
+            default:
+                return "Unknown";
+        }
+    }
+}
+
+CommandMap::CommandNameAlreadyRegistered::CommandNameAlreadyRegistered(const std::string& commandName):
+    Exception(buildCommandNameAlreadyRegisteredError(commandName))
+{
+}
+
+CommandMap::UnknownCommandName::UnknownCommandName(const std::string& commandName):
+    Exception(buildUnknownCommandNameError(commandName))
+{
+}
+
+CommandMap::CategoryOffsetAlreadyRegistered::CategoryOffsetAlreadyRegistered(const std::string& commandName, int offset):
+    Exception(buildCategoryOffsetAlreadyRegisteredError(commandName, offset))
+{
+}
+
+struct CommandMap::Info
+{
+    CommandFunction function;
+    std::string shortHelp;
+    std::string longHelp;
+    boost::program_options::options_description options;
+
+    Info(const CommandFunction& function,
+         const std::string& shortHelp,
+         const std::string& longHelp);
+};
+
+CommandMap::Info::Info(const CommandFunction& function,
+                       const std::string& shortHelp,
+                       const std::string& longHelp):
+    function(function),
+    shortHelp(shortHelp),
+    longHelp(longHelp)
+{
+}
+
+CommandMap::CommandMap()
+{
+}
+
+CommandMap::~CommandMap()
+{
+}
+
+boost::program_options::options_description&
+CommandMap::registerCommand(const std::string& commandName,
+                            const std::string& shortHelp,
+                            const std::string& longHelp,
+                            const CommandFunction& commandFunction,
+                            Category category,
+                            int categoryOffset)
+{
+    const auto ret(map.insert(std::make_pair(commandName, Info(commandFunction, shortHelp, longHelp))));
+    if (!ret.second)
+        throw CommandNameAlreadyRegistered(commandName);
+    const auto retCat(categoryMap.insert(std::make_pair(CategoryKey(category, categoryOffset), commandName)));
+    if (!retCat.second)
+        throw CategoryOffsetAlreadyRegistered(commandName, categoryOffset);
+    return ret.first->second.options;
+}
+
+std::vector<std::string> CommandMap::getCommandNames() const
+{
+    std::vector<std::string> ret;
+    for (const auto& i : map)
+        ret.push_back(i.first);
+    return ret;
+}
+
+const boost::program_options::options_description&
+CommandMap::getCommandOptions(const std::string& commandName) const
+{
+    const auto i(map.find(commandName));
+    if (i == map.end())
+        throw UnknownCommandName(commandName);
+    return i->second.options;
+}
+
+void CommandMap::shortHelp(std::ostream& out) const
+{
+    boost::io::ios_all_saver guard(out);
+    size_t maxWidth(0U);
+    Category currentCategory(Category::UNDEFINED);
+    for (const auto& i : map)
+        if (maxWidth < i.first.size())
+            maxWidth = i.first.size();
+    for (const auto& i : categoryMap)
+    {
+        if (currentCategory != i.first.first)
+        {
+            currentCategory = i.first.first;
+            out << std::endl;
+            out << getCategoryName(currentCategory) << " commands:" << std::endl;
+        }
+        out << std::left << std::setw(maxWidth + 2U) << i.second << map.at(i.second).shortHelp << '\n';
+    }
+}
+
+void CommandMap::longHelp(std::ostream& out, const std::string& commandName) const
+{
+    const auto i(map.find(commandName));
+    if (i == map.end())
+        throw UnknownCommandName(commandName);
+    out << i->first;
+    if (!i->second.options.options().empty())
+    {
+        out << " OPTIONS\n\n" << i->second.longHelp << "\n\nOptions:\n";
+        i->second.options.print(out);
+    }
+    else
+    {
+        out << "\n\n" << i->second.longHelp << '\n';
+    }
+}
+
+int CommandMap::execute(const std::string& commandName,
+                        std::ostream& out,
+                        std::ostream& err,
+                        const boost::program_options::variables_map& params,
+                        size_t count)
+{
+    const auto i(map.find(commandName));
+    if (i == map.end())
+    {
+        err << "unknown command: \"" << commandName << '\"' << std::endl;
+        return EXIT_FAILURE;
+    }
+    const auto& function(i->second.function);
+    int ret(EXIT_SUCCESS);
+    for (size_t i = 0U; i < count; ++i)
+        if ((ret = function(out, err, params)) != EXIT_SUCCESS)
+            break;
+    return ret;
+}
+
+CommandMap& CommandMap::getCommandMap() noexcept
+{
+    static CommandMap instance;
+    return instance;
+}
+
diff --git a/src/cli/commandparserandexecutor.cpp b/src/cli/commandparserandexecutor.cpp
new file mode 100644
index 0000000..b0d52bf
--- /dev/null
+++ b/src/cli/commandparserandexecutor.cpp
@@ -0,0 +1,176 @@
+#include "config.h"
+#include "private/cli/commandparserandexecutor.hpp"
+#include <ostream>
+#include <set>
+#include <string>
+#include <exception>
+#include <boost/program_options.hpp>
+#include "private/cli/commandmap.hpp"
+
+using namespace shareddatalayer;
+using namespace shareddatalayer::cli;
+namespace po = boost::program_options;
+
+namespace
+{
+    void outputBashCompletion(std::ostream& os,
+                              const po::options_description& commonOpts,
+                              CommandMap& commandMap)
+    {
+        const auto commandNames(commandMap.getCommandNames());
+        std::set<std::string> optionNames;
+        for (const auto& i : commonOpts.options())
+            optionNames.insert(i->long_name());
+        for (const auto& i : commandNames)
+            for (const auto& j : commandMap.getCommandOptions(i).options())
+                optionNames.insert(j->long_name());
+
+        os << "_sdltool()\n{\n    COMPREPLY=()\n    local commands=\"";
+        for (const auto& i : commandNames)
+            os << i << ' ';
+        os << "\"\n    local options=\"";
+        for (const auto& i : optionNames)
+            os << "--" << i << ' ';
+        os <<
+R"bash("
+    local cur="${COMP_WORDS[COMP_CWORD]}"
+
+    if [[ ${cur} == -* ]] ; then
+        COMPREPLY=( $(compgen -W "${options}" -- ${cur}) )
+        return 0
+    else
+        COMPREPLY=( $(compgen -W "${commands}" -- ${cur}) )
+        return 0
+    fi
+}
+complete -F _sdltool sdltool
+)bash"
+           << std::flush;
+    }
+
+    void printShortHelp(std::ostream& os,
+                        const po::options_description& commonOpts,
+                        CommandMap& commandMap)
+    {
+        os << "Usage: sdltool [OPTIONS] COMMAND [COMMAND SPECIFIC OPTIONS]\n\n";
+        commonOpts.print(os);
+        os << "\nAvailable commands:\n";
+        commandMap.shortHelp(os);
+    }
+
+    int privateParseAndExecute(int argc,
+                               char** argv,
+                               std::ostream& out,
+                               std::ostream& err,
+                               CommandMap& commandMap)
+    {
+        po::options_description commonHiddenOptsDescription("Common hidden options");
+        commonHiddenOptsDescription.add_options()
+            ("pos-command", po::value<std::string>(), "sdltool command to run")
+            ("pos-subargs", po::value<std::vector<std::string>>(), "Arguments for command");
+
+        po::options_description commonVisibleOptsDescription("Common options");
+        commonVisibleOptsDescription.add_options()
+            ("help", "Show help for COMMAND")
+            ("repeat", po::value<size_t>()->default_value(1U), "Times to repeat the command")
+            ("bash-completion", "Generate bash completion script")
+            ("version", "Show version information");
+
+        po::options_description commonOptsDescription("All common options");
+        commonOptsDescription.add(commonHiddenOptsDescription);
+        commonOptsDescription.add(commonVisibleOptsDescription);
+
+        po::positional_options_description commonPosOptsDescription;
+        commonPosOptsDescription
+            .add("pos-command", 1)
+            .add("pos-subargs", -1); // all positional arguments after 'command'
+
+        po::variables_map commonVarsMap;
+        po::parsed_options commonParsed(po::command_line_parser(argc, argv)
+                                        .options(commonOptsDescription)
+                                        .positional(commonPosOptsDescription)
+                                        .allow_unregistered()
+                                        .run());
+        po::store(commonParsed, commonVarsMap);
+        po::notify(commonVarsMap);
+
+        if (!commonVarsMap.count("pos-command"))
+        {
+            if (commonVarsMap.count("help"))
+            {
+                printShortHelp(out, commonVisibleOptsDescription, commandMap);
+                return EXIT_SUCCESS;
+            }
+            if (commonVarsMap.count("bash-completion"))
+            {
+                outputBashCompletion(out, commonVisibleOptsDescription, commandMap);
+                return EXIT_SUCCESS;
+            }
+            if (commonVarsMap.count("version"))
+            {
+                out << PACKAGE_STRING << std::endl;
+                return EXIT_SUCCESS;
+            }
+            err << "missing command\n\n";
+            printShortHelp(err, commonVisibleOptsDescription, commandMap);
+            return EXIT_FAILURE;
+        }
+
+        auto leftOverOpts = po::collect_unrecognized(commonParsed.options, po::include_positional);
+        if (!leftOverOpts.empty())
+            leftOverOpts.erase(leftOverOpts.begin());
+
+        const auto commandName(commonVarsMap["pos-command"].as<std::string>());
+
+        if (commonVarsMap.count("help"))
+        {
+            bool found(false);
+            try
+            {
+                commandMap.longHelp(out, commandName);
+                out << '\n';
+                found = true;
+            }
+            catch (const CommandMap::UnknownCommandName&)
+            {
+            }
+            if (!found)
+            {
+                err << "unknown command: \"" << commandName << "\"\n";
+                return EXIT_FAILURE;
+            }
+            return EXIT_SUCCESS;
+        }
+
+        const auto& commandOptions(commandMap.getCommandOptions(commandName));
+
+        po::variables_map subcmdVarsMap;
+        auto subcmdParsed(po::command_line_parser(leftOverOpts).options(commandOptions).run());
+        po::store(subcmdParsed, subcmdVarsMap);
+        po::notify(subcmdVarsMap);
+
+        return commandMap.execute(commandName,
+                                  out,
+                                  err,
+                                  subcmdVarsMap,
+                                  commonVarsMap["repeat"].as<size_t>());
+    }
+}
+
+int shareddatalayer::cli::parseAndExecute(int argc,
+                                         char** argv,
+                                         std::ostream& out,
+                                         std::ostream& err,
+                                         CommandMap& commandMap)
+{
+    try
+    {
+        return privateParseAndExecute(argc, argv, out, err, commandMap);
+    }
+    catch (const std::exception& e)
+    {
+        err << e.what() << std::endl;
+        return EXIT_FAILURE;
+    }
+}
+
diff --git a/src/cli/dumpconfigurationcommand.cpp b/src/cli/dumpconfigurationcommand.cpp
new file mode 100644
index 0000000..438f075
--- /dev/null
+++ b/src/cli/dumpconfigurationcommand.cpp
@@ -0,0 +1,83 @@
+#include <ostream>
+#include <cstdlib>
+#include <fstream>
+#include <string>
+#include <iostream>
+#include <boost/property_tree/ptree.hpp>
+#include <boost/property_tree/json_parser.hpp>
+#include "private/cli/commandmap.hpp"
+#include "private/configurationpaths.hpp"
+#include "private/configurationreader.hpp"
+
+using namespace shareddatalayer;
+using namespace shareddatalayer::cli;
+
+namespace
+{
+    bool parseConfiguration(const std::string& file)
+    {
+        boost::property_tree::ptree propertyTree;
+
+        try
+        {
+            boost::property_tree::read_json(file, propertyTree);
+        }
+        catch (const boost::property_tree::json_parser::json_parser_error& e)
+        {
+            std::ostringstream os;
+            os << "error in SDL configuration " << file << " at line " << e.line() << ": ";
+            os << e.message();
+            std::cerr << os.str().c_str() << std::endl;
+            return false;
+        }
+        return true;
+    }
+
+
+    int dumpConfigurationCommand(std::ostream& out)
+    {
+        std::string line;
+        bool status(true);
+
+        for (const auto& i : findConfigurationFiles( getDefaultConfDirectories() ))
+        {
+            std::ifstream file(i);
+
+            out << "File: " << i << std::endl;
+
+            unsigned int lineNum = 1;
+
+            if(file.is_open())
+            {
+                bool parseStatus = parseConfiguration(i);
+
+                if(status && !parseStatus)
+                    status = false;
+
+                while(getline(file, line))
+                    out << lineNum++ << ": " << line << std::endl;
+                file.close();
+            }
+        }
+
+        const auto var(DB_HOST_ENV_VAR_NAME);
+        const auto conf(getenv(var));
+        if (conf == nullptr)
+            out << var << " not set." << std::endl;
+        else
+            out << var  << ": " << conf << std::endl;
+
+        if(!status)
+        {
+            return EXIT_FAILURE;
+        }
+        return EXIT_SUCCESS;
+    }
+}
+
+AUTO_REGISTER_COMMAND(std::bind(dumpConfigurationCommand, std::placeholders::_1),
+                      "dump-configuration",
+                      "Dump configuration",
+                      "Find, parse and dump all shareddatalayer configuration files contents.",
+                      CommandMap::Category::UTIL, 30000);
+
diff --git a/src/cli/main.cpp b/src/cli/main.cpp
new file mode 100644
index 0000000..9d84536
--- /dev/null
+++ b/src/cli/main.cpp
@@ -0,0 +1,22 @@
+#include <iostream>
+#include <exception>
+#include <cstdlib>
+#include "private/cli/commandmap.hpp"
+#include "private/cli/commandparserandexecutor.hpp"
+
+using namespace shareddatalayer;
+using namespace shareddatalayer::cli;
+
+int main(int argc, char** argv)
+{
+    try
+    {
+        return parseAndExecute(argc, argv, std::cout, std::cerr, CommandMap::getCommandMap());
+    }
+    catch (const std::exception& e)
+    {
+        std::cerr << "unexpected error: " << e.what() << std::endl;
+        return EXIT_FAILURE;
+    }
+}
+
diff --git a/src/cli/testconnectivitycommand.cpp b/src/cli/testconnectivitycommand.cpp
new file mode 100644
index 0000000..7c4b2ad
--- /dev/null
+++ b/src/cli/testconnectivitycommand.cpp
@@ -0,0 +1,196 @@
+#include <ostream>
+#include <cstdlib>
+#include <fstream>
+#include <string>
+#include <iostream>
+#include <boost/property_tree/ptree.hpp>
+#include <boost/property_tree/json_parser.hpp>
+#include <chrono>
+#include <arpa/inet.h>
+#include <sdl/asyncstorage.hpp>
+#include <boost/asio.hpp>
+#include <thread>
+#include "private/cli/commandmap.hpp"
+#include "private/configurationpaths.hpp"
+#include "private/createlogger.hpp"
+#include "private/engineimpl.hpp"
+#include "private/databaseconfigurationimpl.hpp"
+#include "private/configurationreader.hpp"
+#include "private/redis/databaseinfo.hpp"
+#include "private/asyncstorageimpl.hpp"
+#include "private/redis/asyncredisstorage.hpp"
+
+using namespace shareddatalayer;
+using namespace shareddatalayer::cli;
+using namespace shareddatalayer::redis;
+
+namespace
+{
+    void handler(std::shared_ptr<shareddatalayer::AsyncStorage> sdl, boost::asio::posix::stream_descriptor& sd)
+    {
+        sdl->handleEvents();
+        sd.async_read_some(boost::asio::null_buffers(), std::bind(handler, sdl, std::ref(sd)));
+    }
+
+    std::shared_ptr<AsyncStorage> createStorage(const std::string& nsStr, std::ostream& out)
+    {
+        try
+        {
+        	std::shared_ptr<AsyncStorage> sdl(AsyncStorage::create());
+            boost::asio::io_service ios;
+            boost::asio::posix::stream_descriptor sd(ios);
+            sd.assign(sdl->fd());
+            sd.async_read_some(boost::asio::null_buffers(), std::bind(handler, sdl, std::ref(sd)));
+            sdl->waitReadyAsync(nsStr, [&ios](const std::error_code& error)
+                                {
+                                    if (error)
+                                        std::cerr << "SDL waitReadyAsync failed. Error:\n" << error.message() << std::endl;
+                                    ios.stop();
+                                });
+            ios.run();
+            sd.release();
+            out << "Storage to namespace " << nsStr << " created." << std::endl;
+            return sdl;
+        }
+        catch (const shareddatalayer::Exception& error)
+        {
+            out << "Storage create failed: " << error.what() << std::endl;
+        }
+        return nullptr;
+    }
+
+    std::string getHosts(const DatabaseConfiguration::Addresses& databaseAddresses)
+    {
+        std::string hosts("");
+        for (auto i(databaseAddresses.begin()); i != databaseAddresses.end(); ++i)
+            hosts = hosts + i->getHost() + " ";
+        return hosts;
+    }
+
+    std::string getPorts(const DatabaseConfiguration::Addresses& databaseAddresses)
+    {
+        std::string ports("");
+        for (auto i(databaseAddresses.begin()); i != databaseAddresses.end(); ++i)
+            ports = ports + std::to_string(ntohs(i->getPort())) + " ";
+        return ports;
+    }
+
+    void PrintStaticConfiguration(std::ostream& out)
+    {
+        auto engine(std::make_shared<EngineImpl>());
+        DatabaseConfigurationImpl databaseConfigurationImpl;
+        ConfigurationReader configurationReader(createLogger(SDL_LOG_PREFIX));
+        configurationReader.readDatabaseConfiguration(databaseConfigurationImpl);
+        auto staticAddresses(databaseConfigurationImpl.getServerAddresses());
+        auto defaultAddresses(databaseConfigurationImpl.getDefaultServerAddresses());
+        auto staticDbType(databaseConfigurationImpl.getDbType());
+        if (!staticAddresses.empty())
+        {
+            out << "\nStatic Server Addresses:" << std::endl;
+            out << "Static Host: " << getHosts(staticAddresses) << std::endl;
+            out << "Static Port: " << getPorts(staticAddresses) << std::endl;
+            if (staticDbType == DatabaseConfiguration::DbType::REDIS_CLUSTER)
+                out << "Static DB type: redis-cluster" << std::endl;
+            else if (staticDbType == DatabaseConfiguration::DbType::REDIS_STANDALONE)
+                out << "Static DB type: redis-standalone" << std::endl;
+            else
+                out << "Static DB type not defined" << std::endl;
+        }
+        if (!defaultAddresses.empty() && staticAddresses.empty())
+        {
+            out << "\nDefault Server Addresses:" << std::endl;
+            out << "Default Host: " << getHosts(defaultAddresses) << std::endl;
+            out << "Default Port: " << getPorts(defaultAddresses) << std::endl;
+        }
+        const auto var(DB_HOST_ENV_VAR_NAME);
+        const auto conf(getenv(var));
+        if (conf != nullptr)
+            out << var  << ": " << conf << std::endl;
+    }
+
+    void PrintDatabaseInfo(const DatabaseInfo& databaseInfo, std::ostream& out)
+    {
+        out << "Used database configuration (databaseInfo):" << std::endl;
+        out << "Host: " << getHosts(databaseInfo.hosts) << std::endl;
+        out << "Port: " << getPorts(databaseInfo.hosts) << std::endl;
+        switch (databaseInfo.type)
+        {
+            case DatabaseInfo::Type::SINGLE:
+                out << "Database type: SINGLE" << std::endl;
+                break;
+            case DatabaseInfo::Type::REDUNDANT:
+                out << "Database type: REDUNDANT" << std::endl;
+                break;
+            case DatabaseInfo::Type::CLUSTER:
+                out << "Database type: CLUSTER" << std::endl;
+                break;
+        }
+        switch (databaseInfo.discovery)
+        {
+            case DatabaseInfo::Discovery::HIREDIS:
+                out << "Discovery type:: HIREDIS" << std::endl;
+                PrintStaticConfiguration(out);
+                break;
+        }
+    }
+
+    [[noreturn]] void timeoutThread(const int& timeout)
+    {
+        std::this_thread::sleep_for(std::chrono::seconds(timeout));
+        std::cerr << "Storage create timeout, aborting after " << timeout << " seconds"<< std::endl;
+        PrintStaticConfiguration(std::cerr);
+        std::exit(EXIT_FAILURE);
+    }
+
+    void setTimeout(const int& timeout)
+    {
+        if (timeout)
+        {
+            std::thread t(timeoutThread, timeout);
+            t.detach();
+        }
+    }
+
+    int TestConnectivityCommand(std::ostream& out,
+                                const boost::program_options::variables_map& map)
+    {
+        const auto ns(map["ns"].as<std::string>());
+        const auto timeout(map["timeout"].as<int>());
+        setTimeout(timeout);
+        auto sdl(createStorage(ns, out));
+        if (sdl != nullptr)
+        {
+            auto asyncStorageImpl(std::dynamic_pointer_cast<AsyncStorageImpl>(sdl));
+            if (asyncStorageImpl != nullptr)
+            {
+            	AsyncStorage& operationalHandler(asyncStorageImpl->getOperationHandler(ns));
+            	AsyncRedisStorage* redisStorage = dynamic_cast<AsyncRedisStorage*>(&operationalHandler);
+                if (redisStorage != nullptr)
+                {
+                	auto databaseinfo (redisStorage->getDatabaseInfo());
+                	PrintDatabaseInfo(databaseinfo, out);
+                }
+                else
+                {
+                	// @TODO Improve output for the case if dummy backend is used.
+                    out << "Cannot get AsyncRedisStorage." << std::endl;
+                    return EXIT_FAILURE;
+                }
+            }
+            else
+            {
+                out << "Cannot get AsyncStorageImpl." << std::endl;
+                return EXIT_FAILURE;
+            }
+        }
+        return EXIT_SUCCESS;
+    }
+}
+
+AUTO_REGISTER_COMMAND(std::bind(TestConnectivityCommand, std::placeholders::_1, std::placeholders::_3),
+                      "test-connectivity",
+                      "Test SDL backend connectivity",
+                      "Check that SDL database backend is available and show discovered redis host address and port",
+                      CommandMap::Category::UTIL, 30020,
+                      ("ns", boost::program_options::value<std::string>()->default_value("sdltoolns"), "Used namespace")
+                      ("timeout", boost::program_options::value<int>()->default_value(0), "Timeout (in seconds), Default is no timeout"));
diff --git a/src/cli/testgetsetcommand.cpp b/src/cli/testgetsetcommand.cpp
new file mode 100644
index 0000000..81bdd1c
--- /dev/null
+++ b/src/cli/testgetsetcommand.cpp
@@ -0,0 +1,144 @@
+#include <ostream>
+#include <cstdlib>
+#include <fstream>
+#include <string>
+#include <iostream>
+#include <boost/property_tree/ptree.hpp>
+#include <boost/property_tree/json_parser.hpp>
+#include <chrono>
+#include <thread>
+#include "private/cli/commandmap.hpp"
+#include "private/configurationpaths.hpp"
+#include <sdl/syncstorage.hpp>
+
+using namespace shareddatalayer;
+using namespace shareddatalayer::cli;
+
+namespace
+{
+    std::shared_ptr<shareddatalayer::SyncStorage> createSyncStorage(std::ostream& out)
+    {
+        try
+        {
+            auto sdl(shareddatalayer::SyncStorage::create());
+            return sdl;
+        }
+        catch (const shareddatalayer::Exception& error)
+        {
+            out << "SyncStorage create failed: " << error.what() << std::endl;
+        }
+
+        out << "Test suspended!" << std::endl;
+        return nullptr;
+    }
+
+    void execRemoveAll(shareddatalayer::SyncStorage& sdl, const std::string& nsStr, std::ostream& out)
+    {
+        try
+        {
+            sdl.removeAll(nsStr);
+        }
+        catch (const shareddatalayer::Exception& error)
+        {
+            out << "removeAll failed: " << error.what() << std::endl;
+        }
+    }
+
+    void execSet(shareddatalayer::SyncStorage& sdl, const std::string& nsStr, const std::string& key, const std::vector<uint8_t>& val, std::ostream& out)
+    {
+        try
+        {
+            sdl.set(nsStr, { { key, val } });
+        }
+        catch (const shareddatalayer::Exception& error)
+        {
+            out << "Set " << key << " failed: " << error.what() << std::endl;
+        }
+    }
+
+    void execGet(shareddatalayer::SyncStorage& sdl, const std::string& nsStr, const std::string& key, const std::vector<uint8_t>& val, std::ostream& out)
+    {
+        try
+        {
+            auto map(sdl.get(nsStr, { key }));
+            auto i(map.find(key));
+            if (i == map.end())
+                out << "Get " << key << ": Not found!" << std::endl;
+            else if (i->second != val)
+                out << "Get " << key << ": Wrong value!" << std::endl;
+        }
+        catch (const shareddatalayer::Exception& error)
+        {
+            out << "Get " << key << " failed: " << error.what() << std::endl;
+        }
+    }
+
+    void timeoutThread(const int& timeout)
+    {
+        std::this_thread::sleep_for(std::chrono::seconds(timeout));
+        std::cerr << "SyncStorage create timeout, aborting after " << timeout << " seconds"<< std::endl;
+        std::exit(EXIT_FAILURE);
+    }
+
+    void setTimeout(const int& timeout)
+    {
+        if (timeout)
+        {
+            std::thread t(timeoutThread, timeout);
+            t.detach();
+        }
+    }
+
+    int TestGetSetCommand(std::ostream& out, const boost::program_options::variables_map& map)
+    {
+        auto keyCount(map["key-count"].as<int>());
+        const auto timeout(map["timeout"].as<int>());
+        auto ns("sdltoolns");
+        setTimeout(timeout);
+        auto sdl(createSyncStorage(out));
+        if (sdl == nullptr)
+            return EXIT_FAILURE;
+
+        out << "namespace\t"
+            << "key\t"
+            << "value\t"
+            << "Write\tRead" << std::endl;
+
+        for (uint8_t val(0); 0 < keyCount--; ++val)
+        {
+            auto key("key_" + std::to_string(val));
+
+            auto wStart(std::chrono::high_resolution_clock::now());
+            execSet(std::ref(*sdl), ns, key, {val}, out);
+            auto wEnd(std::chrono::high_resolution_clock::now());
+            auto writeLatency_us = std::chrono::duration_cast<std::chrono::microseconds>(wEnd - wStart);
+
+            auto rStart(std::chrono::high_resolution_clock::now());
+            execGet(std::ref(*sdl), ns, key, {val}, out);
+            auto rEnd(std::chrono::high_resolution_clock::now());
+            auto readLatency_us = std::chrono::duration_cast<std::chrono::microseconds>(rEnd - rStart);
+
+            out << ns << '\t'
+                << key << '\t'
+                << std::dec << static_cast<int>(val) << "\t"
+                << std::dec << writeLatency_us.count() << "\t"
+                << std::dec << readLatency_us.count() << std::endl;
+        }
+
+        auto start(std::chrono::high_resolution_clock::now());
+        execRemoveAll(std::ref(*sdl), ns, out);
+        auto end(std::chrono::high_resolution_clock::now());
+        auto used_us = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
+        out << "All test keys removed in " << used_us.count() << " microseconds" << std::endl;
+
+        return EXIT_SUCCESS;
+    }
+}
+
+AUTO_REGISTER_COMMAND(std::bind(TestGetSetCommand, std::placeholders::_1, std::placeholders::_3),
+                      "test-get-set",
+                      "Write and read to DB and check latency",
+                      "Check that basic SDL api commands (set/get) works normally and measure latency.",
+                      CommandMap::Category::UTIL, 30010,
+                      ("key-count", boost::program_options::value<int>()->default_value(10), "Number of write/read keys")
+                      ("timeout", boost::program_options::value<int>()->default_value(0), "Timeout (in seconds), Default is no timeout"));
diff --git a/src/configurationpaths.cpp b/src/configurationpaths.cpp
new file mode 100644
index 0000000..7ffaabb
--- /dev/null
+++ b/src/configurationpaths.cpp
@@ -0,0 +1,59 @@
+/*
+   Copyright (c) 2018-2019 Nokia.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+#include "config.h"
+#include "private/configurationpaths.hpp"
+#include <algorithm>
+#include <boost/filesystem.hpp>
+#include <boost/range/iterator_range.hpp>
+#include <boost/algorithm/string/predicate.hpp>
+
+using namespace shareddatalayer;
+
+namespace
+{
+    void findConfigurationFilesFromDirectory(const std::string& path, std::vector<std::string>& paths)
+    {
+        try
+        {
+            for(const auto& i : boost::make_iterator_range(boost::filesystem::directory_iterator(path), { }))
+            {
+                const auto filename(i.path().filename().native());
+                if ((!boost::filesystem::is_directory(i.path())) &&
+                    (filename[0] != '.') &&
+                    (boost::algorithm::ends_with(filename, ".json")))
+                    paths.push_back(i.path().native());
+            }
+        }
+        catch (const boost::filesystem::filesystem_error &)
+        {
+        }
+    }
+}
+
+Directories shareddatalayer::getDefaultConfDirectories()
+{
+    return Directories({ SDL_CONF_DIR, "/run/" PACKAGE_NAME ".d" });
+}
+
+Files shareddatalayer::findConfigurationFiles(const Directories& directories)
+{
+    std::vector<std::string> paths;
+    for (const auto& i : directories)
+        findConfigurationFilesFromDirectory(i, paths);
+    std::sort(paths.begin(), paths.end());
+    return paths;
+}
diff --git a/src/configurationreader.cpp b/src/configurationreader.cpp
new file mode 100644
index 0000000..85ab627
--- /dev/null
+++ b/src/configurationreader.cpp
@@ -0,0 +1,323 @@
+/*
+   Copyright (c) 2018-2019 Nokia.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+#include "private/abort.hpp"
+#include "private/configurationreader.hpp"
+#include <boost/property_tree/json_parser.hpp>
+#include <sdl/exception.hpp>
+#include "private/createlogger.hpp"
+#include "private/databaseconfiguration.hpp"
+#include "private/logger.hpp"
+#include "private/namespaceconfigurations.hpp"
+#include "private/namespacevalidator.hpp"
+#include "private/system.hpp"
+
+using namespace shareddatalayer;
+
+namespace
+{
+    template <typename T>
+    T get(const boost::property_tree::ptree& ptree, const std::string& param, const std::string& sourceName)
+    {
+        try
+        {
+            return ptree.get<T>(param);
+        }
+        catch (const boost::property_tree::ptree_bad_path&)
+        {
+            std::ostringstream os;
+            os << "Configuration error in " << sourceName << ": "
+               << "missing \"" << param << '\"';
+            throw Exception(os.str());
+        }
+        catch (const boost::property_tree::ptree_bad_data& e)
+        {
+            std::ostringstream os;
+            os << "Configuration error in " << sourceName << ": "
+               << "invalid \"" << param << "\": \"" << e.data<boost::property_tree::ptree::data_type>() << '\"';
+            throw Exception(os.str());
+        }
+    }
+
+    void validateAndSetDbType(const std::string& type, DatabaseConfiguration& databaseConfiguration,
+                              const std::string& sourceName)
+    {
+        try
+        {
+            databaseConfiguration.checkAndApplyDbType(type);
+        }
+        catch (const std::exception& e)
+        {
+            std::ostringstream os;
+            os << "Configuration error in " << sourceName << ": "
+               << e.what();
+            throw Exception(os.str());
+        }
+    }
+
+    void validateAndSetDbServerAddress(const std::string& address, DatabaseConfiguration& databaseConfiguration,
+                                       const std::string& sourceName)
+    {
+        try
+        {
+            databaseConfiguration.checkAndApplyServerAddress(address);
+        }
+        catch (const std::exception& e)
+        {
+            std::ostringstream os;
+            os << "Configuration error in " << sourceName << ": "
+               << "invalid \"address\": \"" << address << "\" " << e.what();
+            throw Exception(os.str());
+        }
+    }
+
+    void parseDatabaseServerConfiguration(DatabaseConfiguration& databaseConfiguration,
+                                          const boost::property_tree::ptree& ptree,
+                                          const std::string& sourceName)
+    {
+        const auto address(get<std::string>(ptree, "address", sourceName));
+        validateAndSetDbServerAddress(address, databaseConfiguration, sourceName);
+    }
+
+    void parseDatabaseServersConfiguration(DatabaseConfiguration& databaseConfiguration,
+                                           const boost::property_tree::ptree& ptree,
+                                           const std::string& sourceName)
+    {
+        const auto servers(ptree.get_child_optional("servers"));
+        if (servers)
+            for(const auto& server : *servers)
+                parseDatabaseServerConfiguration(databaseConfiguration, server.second, sourceName);
+        else
+        {
+            std::ostringstream os;
+            os << "Configuration error in " << sourceName << ": "
+               << "missing \"servers\"";
+            throw Exception(os.str());
+        }
+    }
+
+    void parseDatabaseConfiguration(DatabaseConfiguration& databaseConfiguration,
+                                    const boost::property_tree::ptree& ptree,
+                                    const std::string& sourceName)
+    {
+        const auto type(get<std::string>(ptree, "type", sourceName));
+        validateAndSetDbType(type, databaseConfiguration, sourceName);
+
+        parseDatabaseServersConfiguration(databaseConfiguration, ptree, sourceName);
+    }
+
+    void parseDatabaseConfigurationTree(DatabaseConfiguration& databaseConfiguration,
+                                        const boost::optional<boost::property_tree::ptree>& databaseConfigurationPtree,
+                                        const std::string& sourceName)
+    {
+        if (databaseConfigurationPtree)
+            parseDatabaseConfiguration(databaseConfiguration, *databaseConfigurationPtree, sourceName);
+    }
+
+    void parseDatabaseServersConfigurationFromString(DatabaseConfiguration& databaseConfiguration,
+                                                     const std::string& serverConfiguration,
+                                                     const std::string& sourceName)
+    {
+        size_t base(0);
+        auto done(false);
+        do
+        {
+            auto split = serverConfiguration.find(',', base);
+            done = std::string::npos == split;
+            validateAndSetDbServerAddress(serverConfiguration.substr(base, done ? std::string::npos : split-base),
+                                          databaseConfiguration,
+                                          sourceName);
+            base = split+1;
+        } while (!done);
+    }
+
+    void validateNamespacePrefix(const std::string& prefix,
+                                 const std::string& sourceName)
+    {
+        if (!isValidNamespaceSyntax(prefix))
+        {
+            std::ostringstream os;
+            os << "Configuration error in " << sourceName << ": "
+               << "\"namespacePrefix\": \"" << prefix << "\""
+               << " contains some of these disallowed characters: "
+               << getDisallowedCharactersInNamespace();
+            throw Exception(os.str());
+        }
+    }
+
+    void validateEnableNotifications(bool enableNotifications, bool useDbBackend,
+                                     const std::string& sourceName)
+    {
+        if (enableNotifications && !useDbBackend)
+        {
+            std::ostringstream os;
+            os << "Configuration error in " << sourceName << ": "
+               << "\"enableNotifications\" cannot be true, when \"useDbBackend\" is false";
+            throw Exception(os.str());
+        }
+    }
+
+    void parseNsConfiguration(NamespaceConfigurations& namespaceConfigurations,
+                              const std::string& namespacePrefix,
+                              const boost::property_tree::ptree& ptree,
+                              const std::string& sourceName)
+    {
+        const auto useDbBackend(get<bool>(ptree, "useDbBackend", sourceName));
+        const auto enableNotifications(get<bool>(ptree, "enableNotifications", sourceName));
+
+        validateNamespacePrefix(namespacePrefix, sourceName);
+        validateEnableNotifications(enableNotifications, useDbBackend, sourceName);
+
+        namespaceConfigurations.addNamespaceConfiguration({namespacePrefix, useDbBackend, enableNotifications, sourceName});
+    }
+
+    void parseNsConfigurationMap(NamespaceConfigurations& namespaceConfigurations,
+                                 std::unordered_map<std::string, std::pair<boost::property_tree::ptree, std::string>>& namespaceConfigurationMap)
+    {
+        for (const auto &namespaceConfigurationMapItem : namespaceConfigurationMap )
+            parseNsConfiguration(namespaceConfigurations, namespaceConfigurationMapItem.first, namespaceConfigurationMapItem.second.first, namespaceConfigurationMapItem.second.second);
+    }
+}
+
+ConfigurationReader::ConfigurationReader(std::shared_ptr<Logger> logger):
+    ConfigurationReader(getDefaultConfDirectories(), System::getSystem(), logger)
+{
+}
+
+ConfigurationReader::ConfigurationReader(const Directories& directories,
+                                         System& system,
+                                         std::shared_ptr<Logger> logger):
+	dbHostEnvVariableName(DB_HOST_ENV_VAR_NAME),
+	dbHostEnvVariableValue({}),
+	dbPortEnvVariableName(DB_PORT_ENV_VAR_NAME),
+	dbPortEnvVariableValue({}),
+    jsonDatabaseConfiguration(boost::none),
+    logger(logger)
+{
+    auto envStr = system.getenv(dbHostEnvVariableName.c_str());
+    if (envStr)
+    {
+        dbHostEnvVariableValue = envStr;
+        sourceForDatabaseConfiguration = dbHostEnvVariableName;
+        auto envStr = system.getenv(dbPortEnvVariableName.c_str());
+        if (envStr)
+            dbPortEnvVariableValue = envStr;
+    }
+
+    readConfigurationFromDirectories(directories);
+}
+
+ConfigurationReader::~ConfigurationReader()
+{
+}
+
+void ConfigurationReader::readConfigurationFromDirectories(const Directories& directories)
+{
+    for (const auto& i : findConfigurationFiles(directories))
+        readConfiguration(i, i);
+}
+
+void ConfigurationReader::readConfigurationFromInputStream(const std::istream& input)
+{
+    jsonNamespaceConfigurations.clear();
+    readConfiguration(const_cast<std::istream&>(input), "<istream>");
+}
+
+template<typename T>
+void ConfigurationReader::readConfiguration(T& input, const std::string& currentSourceName)
+{
+    boost::property_tree::ptree propertyTree;
+
+    try
+    {
+        boost::property_tree::read_json(input, propertyTree);
+    }
+    catch (const boost::property_tree::json_parser::json_parser_error& e)
+    {
+        std::ostringstream os;
+        os << "error in SDL configuration " << currentSourceName << " at line " << e.line() << ": ";
+        os << e.message();
+        logger->error() << os.str();
+        throw Exception(os.str());
+    }
+
+    // Environment variable configuration overrides json configuration
+    if (sourceForDatabaseConfiguration != dbHostEnvVariableName)
+    {
+        const auto databaseConfiguration(propertyTree.get_child_optional("database"));
+        if (databaseConfiguration)
+        {
+            jsonDatabaseConfiguration = databaseConfiguration;
+            sourceForDatabaseConfiguration = currentSourceName;
+        }
+    }
+
+    const auto namespaceConfigurations(propertyTree.get_child_optional("sharedDataLayer"));
+    if (namespaceConfigurations)
+    {
+        for(const auto& namespaceConfiguration : *namespaceConfigurations)
+        {
+            const auto namespacePrefix = get<std::string>(namespaceConfiguration.second, "namespacePrefix", currentSourceName);
+            jsonNamespaceConfigurations[namespacePrefix] = std::make_pair(namespaceConfiguration.second, currentSourceName);
+        }
+    }
+}
+
+void ConfigurationReader::readDatabaseConfiguration(DatabaseConfiguration& databaseConfiguration)
+{
+    if (!databaseConfiguration.isEmpty())
+        SHAREDDATALAYER_ABORT("Database configuration can be read only to empty container");
+
+    try
+    {
+        if (sourceForDatabaseConfiguration == dbHostEnvVariableName)
+        {
+            // Currently hard coded to redis-standalone, because RIC dbaas does not support Redis cluster configuration.
+        	validateAndSetDbType("redis-standalone", databaseConfiguration, sourceForDatabaseConfiguration);
+        	if (dbPortEnvVariableValue.empty())
+        		parseDatabaseServersConfigurationFromString(databaseConfiguration, dbHostEnvVariableValue, sourceForDatabaseConfiguration);
+        	else
+        		parseDatabaseServersConfigurationFromString(databaseConfiguration, dbHostEnvVariableValue + ":" + dbPortEnvVariableValue, sourceForDatabaseConfiguration);
+        }
+        else
+            parseDatabaseConfigurationTree(databaseConfiguration, jsonDatabaseConfiguration, sourceForDatabaseConfiguration);
+    }
+    catch (const std::exception& e)
+    {
+        logger->error() << e.what();
+        throw;
+    }
+}
+
+void ConfigurationReader::readNamespaceConfigurations(NamespaceConfigurations& namespaceConfigurations)
+{
+    if (!namespaceConfigurations.isEmpty())
+        SHAREDDATALAYER_ABORT("Namespace configurations can be read only to empty container");
+
+    try
+    {
+        parseNsConfigurationMap(namespaceConfigurations, jsonNamespaceConfigurations);
+    }
+    catch(const std::exception& e)
+    {
+        logger->error() << e.what();
+        throw;
+    }
+}
+
+
+template void ConfigurationReader::readConfiguration(const std::string&, const std::string&);
+template void ConfigurationReader::readConfiguration(std::istream&, const std::string&);
diff --git a/src/createlogger.cpp b/src/createlogger.cpp
new file mode 100644
index 0000000..cd85f02
--- /dev/null
+++ b/src/createlogger.cpp
@@ -0,0 +1,52 @@
+/*
+   Copyright (c) 2018-2019 Nokia.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+#include "config.h"
+#include <memory>
+#include <string>
+#include "private/createlogger.hpp"
+#if HAVE_SYSTEMLOGGER
+#include "private/systemlogger.hpp"
+#endif
+
+using namespace shareddatalayer;
+
+std::shared_ptr<Logger> shareddatalayer::createLogger(const std::string& prefix)
+{
+#if HAVE_SYSTEMLOGGER
+    return std::shared_ptr<Logger>(new SystemLogger(prefix));
+#else
+#error "Need to compile with at least one logging backend"
+#endif
+}
+
+void shareddatalayer::logDebugOnce(const std::string& msg) noexcept
+{
+    auto logger(createLogger(SDL_LOG_PREFIX));
+    logger->debug() << msg;
+}
+
+void shareddatalayer::logErrorOnce(const std::string& msg) noexcept
+{
+    auto logger(createLogger(SDL_LOG_PREFIX));
+    logger->error() << msg;
+}
+
+void shareddatalayer::logInfoOnce(const std::string& msg) noexcept
+{
+    auto logger(createLogger(SDL_LOG_PREFIX));
+    logger->info() << msg;
+}
diff --git a/src/databaseconfiguration.cpp b/src/databaseconfiguration.cpp
new file mode 100644
index 0000000..f51203b
--- /dev/null
+++ b/src/databaseconfiguration.cpp
@@ -0,0 +1,37 @@
+/*
+   Copyright (c) 2018-2019 Nokia.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+#include "private/databaseconfiguration.hpp"
+#include <sstream>
+
+using namespace shareddatalayer;
+
+namespace
+{
+    std::string buildInvalidDbTypeError(const std::string& type)
+    {
+        std::ostringstream os;
+        os << "invalid database type: '" << type << "'. ";
+        os << "Allowed types are: 'redis-standalone' or 'redis-cluster'";
+        return os.str();
+    }
+}
+
+DatabaseConfiguration::InvalidDbType::InvalidDbType(const std::string& type):
+    Exception(buildInvalidDbTypeError(type))
+{
+}
+
diff --git a/src/databaseconfigurationimpl.cpp b/src/databaseconfigurationimpl.cpp
new file mode 100644
index 0000000..f1fb2be
--- /dev/null
+++ b/src/databaseconfigurationimpl.cpp
@@ -0,0 +1,75 @@
+/*
+   Copyright (c) 2018-2019 Nokia.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+#include "private/databaseconfigurationimpl.hpp"
+#include <arpa/inet.h>
+
+using namespace shareddatalayer;
+
+namespace
+{
+    const std::string& getDefaultHost()
+    {
+        static const std::string defaultHost("localhost");
+        return defaultHost;
+    }
+
+    const uint16_t DEFAULT_PORT(6379U);
+}
+
+DatabaseConfigurationImpl::DatabaseConfigurationImpl():
+    dbType(DbType::UNKNOWN)
+{
+}
+
+DatabaseConfigurationImpl::~DatabaseConfigurationImpl()
+{
+}
+
+void DatabaseConfigurationImpl::checkAndApplyDbType(const std::string& type)
+{
+    if (type == "redis-standalone")
+        dbType = DatabaseConfiguration::DbType::REDIS_STANDALONE;
+    else if (type == "redis-cluster")
+        dbType = DatabaseConfiguration::DbType::REDIS_CLUSTER;
+    else
+        throw DatabaseConfiguration::InvalidDbType(type);
+}
+
+DatabaseConfiguration::DbType DatabaseConfigurationImpl::getDbType() const
+{
+   return dbType;
+}
+
+void DatabaseConfigurationImpl::checkAndApplyServerAddress(const std::string& address)
+{
+    serverAddresses.push_back(HostAndPort(address, htons(DEFAULT_PORT)));
+}
+
+bool DatabaseConfigurationImpl::isEmpty() const
+{
+    return serverAddresses.empty();
+}
+
+DatabaseConfiguration::Addresses DatabaseConfigurationImpl::getServerAddresses() const
+{
+    return serverAddresses;
+}
+
+DatabaseConfiguration::Addresses DatabaseConfigurationImpl::getDefaultServerAddresses() const
+{
+    return { HostAndPort(getDefaultHost(), htons(DEFAULT_PORT)) };
+}
diff --git a/src/emptynamespace.cpp b/src/emptynamespace.cpp
new file mode 100644
index 0000000..8ec4ebb
--- /dev/null
+++ b/src/emptynamespace.cpp
@@ -0,0 +1,24 @@
+/*
+   Copyright (c) 2018-2019 Nokia.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+#include <sdl/emptynamespace.hpp>
+
+using namespace shareddatalayer;
+
+EmptyNamespace::EmptyNamespace():
+    Exception("empty namespace string given")
+{
+}
diff --git a/src/engine.cpp b/src/engine.cpp
new file mode 100644
index 0000000..0e2c067
--- /dev/null
+++ b/src/engine.cpp
@@ -0,0 +1,25 @@
+/*
+   Copyright (c) 2018-2019 Nokia.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+#include "private/engine.hpp"
+#include <sys/epoll.h>
+
+using namespace shareddatalayer;
+
+const unsigned int Engine::EVENT_IN(EPOLLIN);
+const unsigned int Engine::EVENT_OUT(EPOLLOUT);
+const unsigned int Engine::EVENT_ERR(EPOLLERR);
+const unsigned int Engine::EVENT_HUP(EPOLLHUP);
diff --git a/src/engineimpl.cpp b/src/engineimpl.cpp
new file mode 100644
index 0000000..07bbe53
--- /dev/null
+++ b/src/engineimpl.cpp
@@ -0,0 +1,155 @@
+/*
+   Copyright (c) 2018-2019 Nokia.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+#include "private/engineimpl.hpp"
+#include "private/abort.hpp"
+#include "private/timerfd.hpp"
+#include "private/eventfd.hpp"
+#include "private/system.hpp"
+
+using namespace shareddatalayer;
+
+EngineImpl::EngineImpl():
+    EngineImpl(System::getSystem())
+{
+}
+
+EngineImpl::EngineImpl(System& system):
+    system(system),
+    stopped(false),
+    epollFD(system, system.epoll_create1(EPOLL_CLOEXEC))
+{
+}
+
+EngineImpl::~EngineImpl()
+{
+}
+
+void EngineImpl::handleEvents()
+{
+    if (!handlers.empty())
+        epollWait(0);
+}
+
+void EngineImpl::epollWait(int timeout)
+{
+    ebuffer.resize(handlers.size());
+    const int count(system.epoll_wait(epollFD, ebuffer.data(), static_cast<int>(ebuffer.size()), timeout));
+    if (count <= 0)
+        return;
+    ebuffer.resize(count);
+    for (const auto& i : ebuffer)
+        if (i.data.fd != -1)
+            callHandler(i);
+}
+
+void EngineImpl::callHandler(const epoll_event& e)
+{
+    handlers[e.data.fd](e.events);
+}
+
+void EngineImpl::addMonitoredFD(int fd, unsigned int events, const EventHandler& eh)
+{
+    if (handlers.find(fd) != handlers.end())
+        SHAREDDATALAYER_ABORT("Monitored fd has already been added");
+
+    epoll_event e = { };
+    e.events = events;
+    e.data.fd = fd;
+    system.epoll_ctl(epollFD, EPOLL_CTL_ADD, fd, &e);
+    handlers.insert(std::make_pair(fd, eh));
+}
+
+void EngineImpl::addMonitoredFD(FileDescriptor& fd, unsigned int events, const EventHandler& eh)
+{
+    int native(fd);
+    addMonitoredFD(native, events, eh);
+
+    fd.atClose([this] (int fd)
+        {
+             deleteMonitoredFD(fd);
+        });
+}
+
+void EngineImpl::modifyMonitoredFD(int fd, unsigned int events)
+{
+    if (handlers.find(fd) == handlers.end())
+        SHAREDDATALAYER_ABORT("Modified monitored fd does not exist");
+
+    epoll_event e = { };
+    e.events = events;
+    e.data.fd = fd;
+    system.epoll_ctl(epollFD, EPOLL_CTL_MOD, fd, &e);
+}
+
+void EngineImpl::deleteMonitoredFD(int fd)
+{
+    const auto i(handlers.find(fd));
+    if (i == handlers.end())
+        SHAREDDATALAYER_ABORT("Monitored (to be deleted) fd does not exist");
+
+    handlers.erase(i);
+    for (auto& i : ebuffer)
+        if (i.data.fd == fd)
+        {
+            i.data.fd = -1;
+            break;
+        }
+    system.epoll_ctl(epollFD, EPOLL_CTL_DEL, fd, nullptr);
+}
+
+void EngineImpl::armTimer(Timer& timer, const Timer::Duration& duration, const Timer::Callback& cb)
+{
+    getTimerFD().arm(timer, duration, cb);
+}
+
+void EngineImpl::disarmTimer(const Timer& timer)
+{
+    getTimerFD().disarm(timer);
+}
+
+void EngineImpl::postCallback(const Callback& callback)
+{
+    getEventFD().post(callback);
+}
+
+void EngineImpl::run()
+{
+    while (!stopped)
+        epollWait(-1);
+    stopped = false;
+}
+
+void EngineImpl::stop()
+{
+    postCallback([this] () { stopped = true; });
+}
+
+TimerFD& EngineImpl::getTimerFD()
+{
+    if (!timerFD)
+        timerFD.reset(new TimerFD(system, *this));
+
+    return *timerFD;
+}
+
+EventFD& EngineImpl::getEventFD()
+{
+    if (!eventFD)
+        eventFD.reset(new EventFD(system, *this));
+
+    return *eventFD;
+}
diff --git a/src/error.cpp b/src/error.cpp
new file mode 100644
index 0000000..347e651
--- /dev/null
+++ b/src/error.cpp
@@ -0,0 +1,182 @@
+/*
+   Copyright (c) 2018-2019 Nokia.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+#include <sstream>
+#include "private/createlogger.hpp"
+#include "private/error.hpp"
+
+using namespace shareddatalayer;
+using namespace shareddatalayer::redis;
+
+namespace
+{
+    /* Error codes under this category are not set directly. All SDL implementation specific error codes can be
+     * mapped to these error codes. These error codes are further on mapped to error codes which are available to
+     * SDL clients (shareddatalayer::Error category).
+     * We could directly map implementation specific error codes to client error codes but having this intermediate
+     * mapping gives some benefits:
+     *  - We can easily provide more error categories for clients (e.g. severity, etc.) than just client error code
+     *    classification if needed.
+     *  - We can implement SDL internal error handling logic based on these internal error codes if needed.
+     *  - If implementation specific error would be directly mapped to client error codes, mapping implementation would
+     *    easily be quite complicated (especially if the amount of implementation specific errors/error categories increases).
+     */
+    class InternalErrorCategory : public std::error_category
+    {
+    public:
+      InternalErrorCategory() = default;
+      const char* name() const noexcept override;
+      std::string message(int condition) const override;
+    };
+
+    const char* InternalErrorCategory::name() const noexcept
+    {
+        return "SDL-internal-errorcodes";
+    }
+
+    std::string InternalErrorCategory::message(int) const
+    {
+        return "Only for SDL internal usage.";
+    }
+
+    const std::error_category& getInternalErrorCategory() noexcept
+    {
+        static const InternalErrorCategory theInternalErrorCategory;
+        return theInternalErrorCategory;
+    }
+
+    /* This error category is used by both AsyncHiredisCommandDispatcher and AsyncHiredisClusterCommandDispatcher,
+     * thus it is defined here. Error categories related to single class are defined in the files of the corresponding class.
+     * AsyncHiredisCommandDispatcher and AsyncHiredisClusterCommandDispatcher can use common error category as error
+     * handling is identical in those two classes. Also, only one of those classes is always used at a time (depending
+     * on deployment).
+     */
+    class AsyncRedisCommandDispatcherErrorCategory: public std::error_category
+    {
+    public:
+        AsyncRedisCommandDispatcherErrorCategory() = default;
+
+        const char* name() const noexcept override;
+
+        std::string message(int condition) const override;
+
+        std::error_condition default_error_condition(int condition) const noexcept override;
+    };
+
+    const char* AsyncRedisCommandDispatcherErrorCategory::name() const noexcept
+    {
+        /* As the correct dispacther is selected during runtime, we do not known here (without additional implementation)
+         * which dispatcher (redis/rediscluster) is currently in use. At least for now, we do not indicate in error
+         * category name the exact dispacther type but return the same name for all dispatchers.
+         * Main reason for this decision was that in error investigation situations we anyway need to have some other efficient
+         * way to figure out what kind of deployment was used as there can be error situations which do not generate any error
+         * code. Thus it was not seen worth the errort to implement correct dispatcher name display to error category name.
+         * Detailed dispacther name display can be added later if a need for that arises.
+         */
+        return "asyncrediscommanddispatcher";
+    }
+
+    std::string AsyncRedisCommandDispatcherErrorCategory::message(int condition) const
+    {
+        switch (static_cast<AsyncRedisCommandDispatcherErrorCode>(condition))
+        {
+            case AsyncRedisCommandDispatcherErrorCode::SUCCESS:
+                return std::error_code().message();
+            case AsyncRedisCommandDispatcherErrorCode::CONNECTION_LOST:
+                return "redis connection lost";
+            case AsyncRedisCommandDispatcherErrorCode::PROTOCOL_ERROR:
+                return "redis protocol error";
+            case AsyncRedisCommandDispatcherErrorCode::OUT_OF_MEMORY:
+                return "redis out of memory";
+            case AsyncRedisCommandDispatcherErrorCode::DATASET_LOADING:
+                return "redis dataset still being loaded into memory";
+            case AsyncRedisCommandDispatcherErrorCode::NOT_CONNECTED:
+                return "not connected to redis, SDL operation not started";
+            case AsyncRedisCommandDispatcherErrorCode::UNKNOWN_ERROR:
+                return "redis error";
+            case AsyncRedisCommandDispatcherErrorCode::IO_ERROR:
+                return "redis I/O error";
+            case AsyncRedisCommandDispatcherErrorCode::END_MARKER:
+                logErrorOnce("AsyncRedisCommandDispatcherErrorCode::END_MARKER is not meant to be queried (it is only for enum loop control)");
+                return "unsupported error code for message()";
+            default:
+                return "description missing for AsyncRedisCommandDispatcherErrorCategory error: " + std::to_string(condition);
+        }
+    }
+
+    std::error_condition AsyncRedisCommandDispatcherErrorCategory::default_error_condition(int condition) const noexcept
+    {
+        switch (static_cast<AsyncRedisCommandDispatcherErrorCode>(condition))
+        {
+            case AsyncRedisCommandDispatcherErrorCode::SUCCESS:
+                return InternalError::SUCCESS;
+            case AsyncRedisCommandDispatcherErrorCode::CONNECTION_LOST:
+                return InternalError::BACKEND_CONNECTION_LOST;
+            case AsyncRedisCommandDispatcherErrorCode::PROTOCOL_ERROR:
+                return InternalError::BACKEND_REJECTED_REQUEST;
+            case AsyncRedisCommandDispatcherErrorCode::OUT_OF_MEMORY:
+                return InternalError::BACKEND_ERROR;
+            case AsyncRedisCommandDispatcherErrorCode::DATASET_LOADING:
+                return InternalError::BACKEND_NOT_READY;
+            case AsyncRedisCommandDispatcherErrorCode::NOT_CONNECTED:
+                return InternalError::SDL_NOT_CONNECTED_TO_BACKEND;
+            case AsyncRedisCommandDispatcherErrorCode::UNKNOWN_ERROR:
+                return InternalError::BACKEND_ERROR;
+            case AsyncRedisCommandDispatcherErrorCode::IO_ERROR:
+                return InternalError::BACKEND_ERROR;
+            case AsyncRedisCommandDispatcherErrorCode::END_MARKER:
+                logErrorOnce("AsyncRedisCommandDispatcherErrorCode::END_MARKER is not meant to be mapped to InternalError (it is only for enum loop control)");
+                return InternalError::SDL_ERROR_CODE_LOGIC_ERROR;
+            default:
+                std::ostringstream msg;
+                msg << "default error condition missing for AsyncRedisCommandDispatcherErrorCategory error:  "
+                    << condition;
+                logErrorOnce(msg.str());
+                return InternalError::SDL_ERROR_CODE_LOGIC_ERROR;
+        }
+    }
+
+    const std::error_category& getAsyncRedisCommandDispatcherErrorCategory() noexcept
+    {
+        static const AsyncRedisCommandDispatcherErrorCategory theAsyncRedisCommandDispatcherErrorCategory;
+        return theAsyncRedisCommandDispatcherErrorCategory;
+    }
+}
+
+namespace shareddatalayer
+{
+    std::error_condition make_error_condition(InternalError errorCode)
+    {
+      return {static_cast<int>(errorCode), getInternalErrorCategory()};
+    }
+
+    namespace redis
+    {
+        std::error_code make_error_code(AsyncRedisCommandDispatcherErrorCode errorCode)
+        {
+            return std::error_code(static_cast<int>(errorCode), getAsyncRedisCommandDispatcherErrorCategory());
+        }
+
+        AsyncRedisCommandDispatcherErrorCode& operator++ (AsyncRedisCommandDispatcherErrorCode& ecEnum)
+        {
+            if (ecEnum == AsyncRedisCommandDispatcherErrorCode::END_MARKER)
+                throw std::out_of_range("for AsyncRedisCommandDispatcherErrorCode& operator ++");
+
+            ecEnum = AsyncRedisCommandDispatcherErrorCode(static_cast<std::underlying_type<AsyncRedisCommandDispatcherErrorCode>::type>(ecEnum) + 1);
+            return ecEnum;
+        }
+    }
+}
diff --git a/src/errorqueries.cpp b/src/errorqueries.cpp
new file mode 100644
index 0000000..55ba2c1
--- /dev/null
+++ b/src/errorqueries.cpp
@@ -0,0 +1,120 @@
+/*
+   Copyright (c) 2018-2019 Nokia.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+#include <sstream>
+#include "config.h"
+#include <sdl/errorqueries.hpp>
+#include "private/createlogger.hpp"
+#include "private/error.hpp"
+
+using namespace shareddatalayer;
+
+namespace
+{
+    class SharedDataLayerErrorCategory : public std::error_category
+    {
+    public:
+      SharedDataLayerErrorCategory() = default;
+      const char* name() const noexcept override;
+      std::string message(int condition) const override;
+      bool equivalent(const std::error_code& ec, int condition) const noexcept override;
+    };
+
+    const char* SharedDataLayerErrorCategory::name() const noexcept
+    {
+        return "shareddatalayer-errorcodes";
+    }
+
+    std::string SharedDataLayerErrorCategory::message(int condition) const
+    {
+        switch (static_cast<shareddatalayer::Error>(condition))
+        {
+            case shareddatalayer::Error::SUCCESS:
+                return std::error_code().message();
+            case shareddatalayer::Error::NOT_CONNECTED:
+                return "shareddatalayer not connected to backend data storage";
+            case shareddatalayer::Error::OPERATION_INTERRUPTED:
+                return "shareddatalayer sent the request to backend data storage but did not receive reply";
+            case shareddatalayer::Error::BACKEND_FAILURE:
+                return "backend data storage failed to process the request";
+            case shareddatalayer::Error::REJECTED_BY_BACKEND:
+                return "backend data storage rejected the request";
+            case shareddatalayer::Error::REJECTED_BY_SDL:
+                return "SDL rejected the request";
+            default:
+                return "description missing for SharedDataLayerErrorCategory error: " + std::to_string(condition);
+        }
+    }
+
+    const std::error_category& getSharedDataLayerErrorCategory() noexcept
+    {
+        static const SharedDataLayerErrorCategory theSharedDataLayerErrorCategory;
+        return theSharedDataLayerErrorCategory;
+    }
+
+
+    bool SharedDataLayerErrorCategory::equivalent(const std::error_code& ec, int condition) const noexcept
+    {
+        /* Reasoning for possibly not self-evident mappings:
+            - InternalError::BACKEND_NOT_READY is mapped to shareddatalayer::Error::NOT_CONNECTED
+              even though we are connected to backend in that situation. Client handling for InternalError::BACKEND_NOT_READY
+              situation is identical than handling for other shareddatalayer::Error::NOT_CONNECTED client error cases.
+              To have minimal amount of  client error codes we map it to that.
+            - InternalError::SDL_ERROR_CODE_LOGIC_ERROR is mapped to shareddatalayer::Error::BACKEND_FAILURE.
+              That internal failure should never happen. If it does happen, we cannot know here which kind of error
+              has really happened. Thus we map to the most severe client error code (other places will write logs about this).
+         */
+        switch (static_cast<shareddatalayer::Error>(condition))
+        {
+            case shareddatalayer::Error::SUCCESS:
+                return ec == InternalError::SUCCESS ||
+                       ec == std::error_code();
+            case shareddatalayer::Error::NOT_CONNECTED:
+                return ec == InternalError::SDL_NOT_CONNECTED_TO_BACKEND ||
+                       ec == InternalError::BACKEND_NOT_READY ||
+                       ec == InternalError::SDL_NOT_READY;
+            case shareddatalayer::Error::OPERATION_INTERRUPTED:
+                return ec == InternalError::BACKEND_CONNECTION_LOST;
+            case shareddatalayer::Error::BACKEND_FAILURE:
+                return ec == InternalError::BACKEND_ERROR ||
+                       ec == InternalError::SDL_ERROR_CODE_LOGIC_ERROR;
+            case shareddatalayer::Error::REJECTED_BY_BACKEND:
+                return ec == InternalError::BACKEND_REJECTED_REQUEST;
+            case shareddatalayer::Error::REJECTED_BY_SDL:
+                return ec == InternalError::SDL_RECEIVED_INVALID_PARAMETER;
+            default:
+                /* Since clients can compare shareddatalayer::Error conditions against any std::error_code based ec, this error log
+                 * can occur without fault in SDL implementation. If error log appears:
+                 *  - First check is the problematic ec set in SDL implementation
+                 *      - If yes, do needed updates to SDL (update error mappings for given ec or change SDL to set some error_code)
+                 *      - If no, ask client to check why they are comparing non-SDL originated error_code against shareddatalayer::Error
+                 */
+                std::ostringstream msg;
+                msg << "SharedDataLayerErrorCategory::equivalent no mapping for error: " << ec.category().name()
+                    << ec.value();
+                logErrorOnce(msg.str());
+                return false;
+        }
+    }
+}
+
+namespace shareddatalayer
+{
+    std::error_condition make_error_condition(shareddatalayer::Error errorCode)
+    {
+      return {static_cast<int>(errorCode), getSharedDataLayerErrorCategory()};
+    }
+}
diff --git a/src/eventfd.cpp b/src/eventfd.cpp
new file mode 100644
index 0000000..6a0b14a
--- /dev/null
+++ b/src/eventfd.cpp
@@ -0,0 +1,96 @@
+/*
+   Copyright (c) 2018-2019 Nokia.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+#include "private/eventfd.hpp"
+#include <sys/eventfd.h>
+#include "private/abort.hpp"
+#include "private/engine.hpp"
+#include "private/system.hpp"
+
+using namespace shareddatalayer;
+
+namespace
+{
+    /*
+     * Simple wrapper for executing the given callback without expecting
+     * exceptions. If callback throws, we'll crash.
+     */
+    void execute(const EventFD::Callback& callback) noexcept
+    {
+        callback();
+    }
+}
+
+EventFD::EventFD(Engine& engine):
+    EventFD(System::getSystem(), engine)
+{
+}
+
+EventFD::EventFD(System& system, Engine& engine):
+    system(system),
+    fd(system, system.eventfd(0U, EFD_CLOEXEC | EFD_NONBLOCK))
+{
+    engine.addMonitoredFD(fd, Engine::EVENT_IN, std::bind(&EventFD::handleEvents, this));
+}
+
+EventFD::~EventFD()
+{
+}
+
+void EventFD::post(const Callback& callback)
+{
+    if (!callback)
+        SHAREDDATALAYER_ABORT("A null callback was provided");
+
+    atomicPushBack(callback);
+    static const uint64_t value(1U);
+    system.write(fd, &value, sizeof(value));
+}
+
+void EventFD::atomicPushBack(const Callback& callback)
+{
+    std::lock_guard<std::mutex> guard(callbacksMutex);
+    callbacks.push_back(callback);
+}
+
+EventFD::Callbacks EventFD::atomicPopAll()
+{
+    std::lock_guard<std::mutex> guard(callbacksMutex);
+    Callbacks extractedCallbacks;
+    std::swap(callbacks, extractedCallbacks);
+    return extractedCallbacks;
+}
+
+void EventFD::handleEvents()
+{
+    uint64_t value;
+    system.read(fd, &value, sizeof(value));
+    executeCallbacks();
+}
+
+void EventFD::executeCallbacks()
+{
+    Callbacks callbacks(atomicPopAll());
+    while (!callbacks.empty())
+        popAndExecuteFirstCallback(callbacks);
+}
+
+void EventFD::popAndExecuteFirstCallback(Callbacks& callbacks)
+{
+    const auto callback(callbacks.front());
+    callbacks.pop_front();
+    execute(callback);
+}
diff --git a/src/exception.cpp b/src/exception.cpp
new file mode 100644
index 0000000..0c8da72
--- /dev/null
+++ b/src/exception.cpp
@@ -0,0 +1,29 @@
+/*
+   Copyright (c) 2018-2019 Nokia.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+#include <sdl/exception.hpp>
+
+using namespace shareddatalayer;
+
+Exception::Exception(const std::string& message):
+    std::runtime_error(message)
+{
+}
+
+Exception::Exception(const char* message):
+    std::runtime_error(message)
+{
+}
diff --git a/src/filedescriptor.cpp b/src/filedescriptor.cpp
new file mode 100644
index 0000000..10dec70
--- /dev/null
+++ b/src/filedescriptor.cpp
@@ -0,0 +1,77 @@
+/*
+   Copyright (c) 2018-2019 Nokia.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+#include "private/filedescriptor.hpp"
+#include "private/system.hpp"
+
+using namespace shareddatalayer;
+
+namespace
+{
+    int moveFD(int& fd)
+    {
+        const int ret(fd);
+        fd = -1;
+        return ret;
+    }
+}
+
+FileDescriptor::FileDescriptor(int fd) noexcept:
+    FileDescriptor(System::getSystem(), fd)
+{
+}
+
+FileDescriptor::FileDescriptor(System& system, int fd) noexcept:
+    system(&system),
+    fd(fd)
+{
+}
+
+FileDescriptor::FileDescriptor(FileDescriptor&& fd) noexcept:
+    system(fd.system),
+    fd(moveFD(fd.fd)),
+    atCloseCb(std::move(fd.atCloseCb))
+{
+}
+
+FileDescriptor& FileDescriptor::operator = (FileDescriptor&& fd) noexcept
+{
+    close();
+    system = fd.system;
+    this->fd = moveFD(fd.fd);
+    atCloseCb = std::move(fd.atCloseCb);
+    return *this;
+}
+
+FileDescriptor::~FileDescriptor()
+{
+    close();
+}
+
+void FileDescriptor::atClose(std::function<void(int)> atCloseCb)
+{
+    this->atCloseCb = atCloseCb;
+}
+
+void FileDescriptor::close()
+{
+    if (fd < 0)
+        return;
+    if (atCloseCb)
+        atCloseCb(fd);
+    system->close(fd);
+    fd = -1;
+}
diff --git a/src/hostandport.cpp b/src/hostandport.cpp
new file mode 100644
index 0000000..de045ed
--- /dev/null
+++ b/src/hostandport.cpp
@@ -0,0 +1,158 @@
+/*
+   Copyright (c) 2018-2019 Nokia.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+#include "private/hostandport.hpp"
+#include <sstream>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <boost/lexical_cast.hpp>
+
+using namespace shareddatalayer;
+
+namespace
+{
+    uint16_t stringToPort(const std::string& port)
+    {
+        if (port.empty())
+            throw HostAndPort::EmptyPort();
+        try
+        {
+            return htons(boost::lexical_cast<uint16_t>(port));
+        }
+        catch (const boost::bad_lexical_cast&)
+        {
+            char buf[1024];
+            servent resultbuf = { };
+            servent *result(nullptr);
+            getservbyname_r(port.c_str(), nullptr, &resultbuf, buf, sizeof(buf), &result);
+            if (result == nullptr)
+                throw HostAndPort::InvalidPort(port);
+            return static_cast<uint16_t>(result->s_port);
+        }
+    }
+
+    bool isInBrackets(const std::string& str)
+    {
+        return ((!str.empty()) && (str.front() == '[') && (str.back() == ']'));
+    }
+
+    std::string removeBrackets(const std::string& str)
+    {
+        return str.substr(1U, str.size() - 2U);
+    }
+
+    bool isLiteralIPv6(const std::string& str)
+    {
+        in6_addr tmp;
+        return inet_pton(AF_INET6, str.c_str(), &tmp) == 1;
+    }
+
+    std::string buildInvalidPortError(const std::string& port)
+    {
+        std::ostringstream os;
+        os << "invalid port: " << port;
+        return os.str();
+    }
+}
+
+HostAndPort::InvalidPort::InvalidPort(const std::string& port):
+    Exception(buildInvalidPortError(port))
+{
+}
+
+HostAndPort::EmptyPort::EmptyPort():
+    Exception("empty port")
+{
+}
+
+HostAndPort::EmptyHost::EmptyHost():
+    Exception("empty host")
+{
+}
+
+HostAndPort::HostAndPort(const std::string& addressAndOptionalPort, uint16_t defaultPort)
+{
+    if (isInBrackets(addressAndOptionalPort))
+        parse(removeBrackets(addressAndOptionalPort), defaultPort);
+    else
+        parse(addressAndOptionalPort, defaultPort);
+}
+
+void HostAndPort::parse(const std::string& addressAndOptionalPort, uint16_t defaultPort)
+{
+    const auto pos(addressAndOptionalPort.rfind(':'));
+    if (pos == std::string::npos)
+    {
+        host = addressAndOptionalPort;
+        port = defaultPort;
+        literalIPv6 = false;
+    }
+    else if (isLiteralIPv6(addressAndOptionalPort))
+    {
+        host = addressAndOptionalPort;
+        port = defaultPort;
+        literalIPv6 = true;
+    }
+    else
+    {
+        host = addressAndOptionalPort.substr(0, pos);
+        if (isInBrackets(host))
+            host = removeBrackets(host);
+        literalIPv6 = isLiteralIPv6(host);
+        port = stringToPort(addressAndOptionalPort.substr(pos + 1U, addressAndOptionalPort.size() - pos - 1U));
+    }
+    if (host.empty())
+        throw EmptyHost();
+}
+
+const std::string& HostAndPort::getHost() const
+{
+    return host;
+}
+
+uint16_t HostAndPort::getPort() const
+{
+    return port;
+}
+
+std::string HostAndPort::getString() const
+{
+    std::ostringstream os;
+    if (literalIPv6)
+        os << '[' << host << "]:" << ntohs(port);
+    else
+        os << host << ':' << ntohs(port);
+    return os.str();
+}
+
+bool HostAndPort::operator==(const HostAndPort& hp) const
+{
+    return this->getPort() == hp.getPort() && this->getHost() == hp.getHost();
+}
+
+bool HostAndPort::operator!=(const HostAndPort& hp) const
+{
+    return !(hp == *this);
+}
+
+bool HostAndPort::operator<(const HostAndPort& hp) const
+{
+    if (this->getHost() == hp.getHost())
+        return this->getPort() < hp.getPort();
+    else
+        return this->getHost() < hp.getHost();
+}
diff --git a/src/invalidnamespace.cpp b/src/invalidnamespace.cpp
new file mode 100644
index 0000000..988d2ee
--- /dev/null
+++ b/src/invalidnamespace.cpp
@@ -0,0 +1,36 @@
+/*
+   Copyright (c) 2018-2019 Nokia.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+#include <sdl/invalidnamespace.hpp>
+#include <sstream>
+#include "private/namespacevalidator.hpp"
+
+using namespace shareddatalayer;
+
+namespace
+{
+    std::string buildErrorMessage(const std::string& ns)
+    {
+        std::ostringstream oss;
+        oss << "namespace string: \"" << ns << "\" is invalid. Disallowed characters: " << getDisallowedCharactersInNamespace();
+        return oss.str();
+    }
+}
+
+InvalidNamespace::InvalidNamespace(const std::string& ns):
+    Exception(buildErrorMessage(ns))
+{
+}
diff --git a/src/namespaceconfigurationsimpl.cpp b/src/namespaceconfigurationsimpl.cpp
new file mode 100644
index 0000000..7a4692c
--- /dev/null
+++ b/src/namespaceconfigurationsimpl.cpp
@@ -0,0 +1,118 @@
+/*
+   Copyright (c) 2018-2019 Nokia.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+#include "private/abort.hpp"
+#include "private/namespaceconfigurationsimpl.hpp"
+#include <sstream>
+#include <iomanip>
+
+using namespace shareddatalayer;
+
+namespace
+{
+    const NamespaceConfiguration getDefaultNamespaceConfiguration()
+    {
+        return {"", true, false, "<default>"};
+    }
+}
+
+NamespaceConfigurationsImpl::NamespaceConfigurationsImpl():
+    namespaceConfigurations({getDefaultNamespaceConfiguration()}),
+    //Current implementation assumes that this index is zero. If changing the index, do needed modifications to implementation.
+    defaultConfigurationIndex(0),
+    namespaceConfigurationsLookupTable()
+{
+}
+
+NamespaceConfigurationsImpl::~NamespaceConfigurationsImpl()
+{
+}
+
+void NamespaceConfigurationsImpl::addNamespaceConfiguration(const NamespaceConfiguration& namespaceConfiguration)
+{
+    if (!namespaceConfigurationsLookupTable.empty())
+        SHAREDDATALAYER_ABORT("Cannot add namespace configurations after lookup table is initialized");
+
+    namespaceConfigurations.push_back(namespaceConfiguration);
+}
+
+std::string NamespaceConfigurationsImpl::getDescription(const std::string& ns) const
+{
+    NamespaceConfiguration namespaceConfiguration = findConfigurationForNamespace(ns);
+    std::string sourceInfo = namespaceConfiguration.sourceName;
+
+    if (!namespaceConfiguration.namespacePrefix.empty())
+        sourceInfo += (" prefix: " + namespaceConfiguration.namespacePrefix);
+
+    std::ostringstream os;
+    os << std::boolalpha;
+    os << sourceInfo << ", ";
+    os << "useDbBackend: " << namespaceConfiguration.dbBackendIsUsed << ", ";
+    os << "enableNotifications: " << namespaceConfiguration.notificationsAreEnabled;
+    return os.str();
+}
+
+bool NamespaceConfigurationsImpl::isDbBackendUseEnabled(const std::string& ns) const
+{
+    return findConfigurationForNamespace(ns).dbBackendIsUsed;
+}
+
+bool NamespaceConfigurationsImpl::areNotificationsEnabled(const std::string& ns) const
+{
+    return findConfigurationForNamespace(ns).notificationsAreEnabled;
+}
+
+const NamespaceConfiguration& NamespaceConfigurationsImpl::findConfigurationForNamespace(const std::string& ns) const
+{
+    if (namespaceConfigurationsLookupTable.count(ns) > 0)
+        return namespaceConfigurations.at(namespaceConfigurationsLookupTable.at(ns));
+
+    size_t longestMatchingPrefixLen(0);
+    std::vector<int>::size_type foundIndex(0);
+    bool configurationFound(false);
+
+    for(std::vector<int>::size_type i = (defaultConfigurationIndex + 1); i < namespaceConfigurations.size(); i++)
+    {
+        const auto prefixLen(namespaceConfigurations[i].namespacePrefix.length());
+
+        if (ns.compare(0, prefixLen, namespaceConfigurations[i].namespacePrefix) == 0)
+        {
+            if (prefixLen >= longestMatchingPrefixLen)
+            {
+                configurationFound = true;
+                foundIndex = i;
+                longestMatchingPrefixLen = prefixLen;
+            }
+        }
+    }
+
+    if (!configurationFound)
+        foundIndex = defaultConfigurationIndex;
+
+    namespaceConfigurationsLookupTable[ns] = foundIndex;
+    return namespaceConfigurations[foundIndex];
+}
+
+bool NamespaceConfigurationsImpl::isEmpty() const
+{
+    /* Empty when contains only default configuration */
+    return namespaceConfigurations.size() == 1;
+}
+
+bool NamespaceConfigurationsImpl::isNamespaceInLookupTable(const std::string& ns) const
+{
+    return namespaceConfigurationsLookupTable.count(ns) > 0;
+}
diff --git a/src/namespacevalidator.cpp b/src/namespacevalidator.cpp
new file mode 100644
index 0000000..7e14d00
--- /dev/null
+++ b/src/namespacevalidator.cpp
@@ -0,0 +1,48 @@
+/*
+   Copyright (c) 2018-2019 Nokia.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+#include "private/namespacevalidator.hpp"
+#include <sdl/emptynamespace.hpp>
+#include <sdl/invalidnamespace.hpp>
+#include "private/asyncconnection.hpp"
+
+
+namespace shareddatalayer
+{
+    const std::string& getDisallowedCharactersInNamespace()
+    {
+        static const std::string disallowedCharacters{AsyncConnection::SEPARATOR, '{', '}'};
+        return disallowedCharacters;
+    }
+
+    bool isValidNamespaceSyntax(const Namespace& ns)
+    {
+        return (ns.find_first_of(getDisallowedCharactersInNamespace()) == std::string::npos);
+    }
+
+    void validateNamespace(const Namespace& ns)
+    {
+        if (ns.empty())
+            throw EmptyNamespace();
+        else if (!isValidNamespaceSyntax(ns))
+            throw InvalidNamespace(ns);
+    }
+
+    bool isValidNamespace(const Namespace& ns)
+    {
+        return (!ns.empty() && isValidNamespaceSyntax(ns));
+    }
+}
diff --git a/src/notconnected.cpp b/src/notconnected.cpp
new file mode 100644
index 0000000..a15ae7c
--- /dev/null
+++ b/src/notconnected.cpp
@@ -0,0 +1,24 @@
+/*
+   Copyright (c) 2018-2019 Nokia.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+#include <sdl/notconnected.hpp>
+
+using namespace shareddatalayer;
+
+NotConnected::NotConnected(const std::string& error):
+    Exception(error)
+{
+}
diff --git a/src/operationinterrupted.cpp b/src/operationinterrupted.cpp
new file mode 100644
index 0000000..46141a3
--- /dev/null
+++ b/src/operationinterrupted.cpp
@@ -0,0 +1,24 @@
+/*
+   Copyright (c) 2018-2019 Nokia.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+#include <sdl/operationinterrupted.hpp>
+
+using namespace shareddatalayer;
+
+OperationInterrupted::OperationInterrupted(const std::string& error):
+    Exception(error)
+{
+}
diff --git a/src/publisherid.cpp b/src/publisherid.cpp
new file mode 100644
index 0000000..c8fd52a
--- /dev/null
+++ b/src/publisherid.cpp
@@ -0,0 +1,19 @@
+/*
+   Copyright (c) 2018-2019 Nokia.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+#include <sdl/publisherid.hpp>
+
+const shareddatalayer::PublisherId shareddatalayer::NO_PUBLISHER("shareddatalayer::NO_PUBLISHER");
diff --git a/src/redis/asynccommanddispatcher.cpp b/src/redis/asynccommanddispatcher.cpp
new file mode 100644
index 0000000..25ec890
--- /dev/null
+++ b/src/redis/asynccommanddispatcher.cpp
@@ -0,0 +1,67 @@
+/*
+   Copyright (c) 2018-2019 Nokia.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+#include "private/redis/asynccommanddispatcher.hpp"
+#include <cstdlib>
+#include "config.h"
+#include "private/redis/databaseinfo.hpp"
+#if HAVE_HIREDIS_VIP
+#include "private/redis/asynchiredisclustercommanddispatcher.hpp"
+#include "private/redis/asynchirediscommanddispatcher.hpp"
+#elif HAVE_HIREDIS
+#include "private/redis/asynchirediscommanddispatcher.hpp"
+#endif
+#include "private/abort.hpp"
+#include "private/engine.hpp"
+
+using namespace shareddatalayer::redis;
+
+std::shared_ptr<AsyncCommandDispatcher> AsyncCommandDispatcher::create(Engine& engine,
+                                                                       const DatabaseInfo& databaseInfo,
+                                                                       std::shared_ptr<ContentsBuilder> contentsBuilder,
+                                                                       bool usePermanentCommandCallbacks,
+                                                                       std::shared_ptr<Logger> logger)
+{
+#if HAVE_HIREDIS_VIP
+    if (databaseInfo.type == DatabaseInfo::Type::CLUSTER)
+    {
+        return std::make_shared<AsyncHiredisClusterCommandDispatcher>(engine,
+                                                                      databaseInfo.ns,
+                                                                      databaseInfo.hosts,
+                                                                      contentsBuilder,
+                                                                      usePermanentCommandCallbacks,
+                                                                      logger);
+    }
+    else
+        return std::make_shared<AsyncHiredisCommandDispatcher>(engine,
+                                                               databaseInfo.hosts.at(0).getHost(),
+                                                               databaseInfo.hosts.at(0).getPort(),
+                                                               contentsBuilder,
+                                                               usePermanentCommandCallbacks,
+                                                               logger);
+#elif HAVE_HIREDIS
+    if (databaseInfo.type == DatabaseInfo::Type::CLUSTER)
+        SHAREDDATALAYER_ABORT("Not implemented.");
+    return std::make_shared<AsyncHiredisCommandDispatcher>(engine,
+                                                           databaseInfo.hosts.at(0).getHost(),
+                                                           databaseInfo.hosts.at(0).getPort(),
+                                                           contentsBuilder,
+                                                           usePermanentCommandCallbacks,
+                                                           logger);
+#else
+    SHAREDDATALAYER_ABORT("Not implemented.");
+#endif
+}
diff --git a/src/redis/asyncdatabasediscovery.cpp b/src/redis/asyncdatabasediscovery.cpp
new file mode 100644
index 0000000..892e7cc
--- /dev/null
+++ b/src/redis/asyncdatabasediscovery.cpp
@@ -0,0 +1,63 @@
+/*
+   Copyright (c) 2018-2019 Nokia.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+#include "private/redis/asyncdatabasediscovery.hpp"
+#include "private/databaseconfiguration.hpp"
+#include "private/logger.hpp"
+#include <cstdlib>
+#include "config.h"
+#if HAVE_HIREDIS
+#include "private/redis/asynchiredisdatabasediscovery.hpp"
+#endif
+#include "private/abort.hpp"
+
+using namespace shareddatalayer::redis;
+
+std::shared_ptr<AsyncDatabaseDiscovery> AsyncDatabaseDiscovery::create(std::shared_ptr<Engine> engine,
+                                                                       const boost::optional<Namespace>& ns,
+                                                                       const DatabaseConfiguration& staticDatabaseConfiguration,
+                                                                       std::shared_ptr<Logger> logger)
+{
+    auto staticAddresses(staticDatabaseConfiguration.getServerAddresses());
+
+    if (staticAddresses.empty())
+        staticAddresses = staticDatabaseConfiguration.getDefaultServerAddresses();
+
+    auto staticDbType(staticDatabaseConfiguration.getDbType());
+
+    if (staticDbType == DatabaseConfiguration::DbType::REDIS_CLUSTER)
+#if HAVE_HIREDIS_VIP
+        return std::make_shared<AsyncHiredisDatabaseDiscovery>(engine,
+                                                               ns,
+                                                               DatabaseInfo::Type::CLUSTER,
+                                                               staticAddresses,
+                                                               logger);
+#else
+        SHAREDDATALAYER_ABORT("No Hiredis vip for Redis cluster configuration");
+#endif
+    else
+#if HAVE_HIREDIS
+        return std::make_shared<AsyncHiredisDatabaseDiscovery>(engine,
+                                                               ns,
+                                                               DatabaseInfo::Type::SINGLE,
+                                                               staticAddresses,
+                                                               logger);
+#else
+        static_cast<void>(logger);
+        SHAREDDATALAYER_ABORT("No Hiredis");
+#endif
+}
+
diff --git a/src/redis/asynchiredisclustercommanddispatcher.cpp b/src/redis/asynchiredisclustercommanddispatcher.cpp
new file mode 100644
index 0000000..7270886
--- /dev/null
+++ b/src/redis/asynchiredisclustercommanddispatcher.cpp
@@ -0,0 +1,334 @@
+/*
+   Copyright (c) 2018-2019 Nokia.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+#include "private/redis/asynchiredisclustercommanddispatcher.hpp"
+#include <algorithm>
+#include <cstring>
+#include <cerrno>
+#include <sstream>
+#include "private/abort.hpp"
+#include "private/createlogger.hpp"
+#include "private/error.hpp"
+#include "private/logger.hpp"
+#include "private/redis/asyncredisreply.hpp"
+#include "private/redis/reply.hpp"
+#include "private/redis/hiredisclustersystem.hpp"
+#include "private/engine.hpp"
+#include "private/redis/hiredisclusterepolladapter.hpp"
+#include "private/redis/contents.hpp"
+#include "private/redis/redisgeneral.hpp"
+
+using namespace shareddatalayer;
+using namespace shareddatalayer::redis;
+
+namespace
+{
+    void connectCb(const redisClusterAsyncContext*, const redisAsyncContext* ac, int status)
+    {
+        if (!status)
+        {
+            std::ostringstream msg;
+            msg << "redis cluster instance connected, fd: " << ac->c.fd;
+            logDebugOnce(msg.str());
+        }
+    }
+
+    void disconnectCb(const redisClusterAsyncContext* acc, const redisAsyncContext* ac, int status)
+    {
+        if (status)
+        {
+            std::ostringstream msg;
+            msg << "redis cluster instance disconnected, fd: " << ac->c.fd
+                << ", status: " << ac->err;
+            logDebugOnce(msg.str());
+        }
+        auto instance(static_cast<AsyncHiredisClusterCommandDispatcher*>(acc->data));
+        instance->handleDisconnect(ac);
+    }
+
+    void cb(redisClusterAsyncContext* acc, void* rr, void* pd)
+    {
+        auto instance(static_cast<AsyncHiredisClusterCommandDispatcher*>(acc->data));
+        auto reply(static_cast<redisReply*>(rr));
+        auto cb(static_cast<AsyncHiredisClusterCommandDispatcher::CommandCb*>(pd));
+        if (instance->isClientCallbacksEnabled())
+            instance->handleReply(*cb, getRedisError(acc->err, acc->errstr, reply), reply);
+    }
+}
+
+AsyncHiredisClusterCommandDispatcher::AsyncHiredisClusterCommandDispatcher(Engine& engine,
+                                                                           const boost::optional<std::string>& ns,
+                                                                           const DatabaseConfiguration::Addresses& addresses,
+                                                                           std::shared_ptr<ContentsBuilder> contentsBuilder,
+                                                                           bool usePermanentCommandCallbacks,
+                                                                           std::shared_ptr<Logger> logger):
+    AsyncHiredisClusterCommandDispatcher(engine,
+                                         ns,
+                                         addresses,
+                                         contentsBuilder,
+                                         usePermanentCommandCallbacks,
+                                         HiredisClusterSystem::getInstance(),
+                                         std::make_shared<HiredisClusterEpollAdapter>(engine),
+                                         logger)
+{
+}
+
+AsyncHiredisClusterCommandDispatcher::AsyncHiredisClusterCommandDispatcher(Engine& engine,
+                                                                           const boost::optional<std::string>& ns,
+                                                                           const DatabaseConfiguration::Addresses& addresses,
+                                                                           std::shared_ptr<ContentsBuilder> contentsBuilder,
+                                                                           bool usePermanentCommandCallbacks,
+                                                                           HiredisClusterSystem& hiredisClusterSystem,
+                                                                           std::shared_ptr<HiredisClusterEpollAdapter> adapter,
+                                                                           std::shared_ptr<Logger> logger):
+    engine(engine),
+    initialNamespace(ns),
+    addresses(addresses),
+    contentsBuilder(contentsBuilder),
+    usePermanentCommandCallbacks(usePermanentCommandCallbacks),
+    hiredisClusterSystem(hiredisClusterSystem),
+    adapter(adapter),
+    acc(nullptr),
+    serviceState(ServiceState::DISCONNECTED),
+    clientCallbacksEnabled(true),
+    connectionRetryTimer(engine),
+    connectionRetryTimerDuration(std::chrono::seconds(1)),
+    logger(logger)
+{
+    connect();
+}
+
+AsyncHiredisClusterCommandDispatcher::~AsyncHiredisClusterCommandDispatcher()
+{
+    disconnectHiredisCluster();
+}
+
+void AsyncHiredisClusterCommandDispatcher::connect()
+{
+    // Disconnect and free possibly (in re-connecting scenarios) already existing Redis cluster context.
+    disconnectHiredisCluster();
+    acc = hiredisClusterSystem.redisClusterAsyncConnect(formatToClusterSyntax(addresses).c_str(),
+                                                        HIRCLUSTER_FLAG_ROUTE_USE_SLOTS);
+    if (acc == nullptr)
+    {
+        logger->error() << "SDL: connecting to redis cluster failed, null context returned";
+        armConnectionRetryTimer();
+        return;
+    }
+    if (acc->err)
+    {
+        logger->error() << "SDL: connecting to redis cluster failed, error: " << acc->err;
+        armConnectionRetryTimer();
+        return;
+    }
+    acc->data = this;
+    adapter->setup(acc);
+    hiredisClusterSystem.redisClusterAsyncSetConnectCallback(acc, connectCb);
+    hiredisClusterSystem.redisClusterAsyncSetDisconnectCallback(acc, disconnectCb);
+    verifyConnection();
+}
+
+void AsyncHiredisClusterCommandDispatcher::verifyConnection()
+{
+    /* redisClusterAsyncConnect only queries available cluster nodes but it does
+     * not connect to any cluster node (as it does not know to which node it should connect to).
+     * As we use same cluster node for one SDL namespace (namespace is a hash tag), it is already
+     * determined to which cluster node this instance will connect to. We do initial operation
+     * to get connection to right redis node established already now. This also verifies that
+     * connection really works. When Redis has max amount of users, it will still accept new
+     * connections but is will close them immediately. Therefore, we need to verify that just
+     * established connection really works.
+     */
+    /* Connection setup/verification is now done by doing redis command list query. Because we anyway
+     * need to verify that Redis has required commands, we can now combine these two operations
+     * (command list query and connection setup/verification). If either one of the functionalities
+     * is not needed in the future and it is removed, remember to still leave the other one.
+     */
+    /* Non namespace-specific command list query can be used for connection setup purposes,
+     * because SDL uses redisClusterAsyncCommandArgvWithKey which adds namespace to all
+     * commands dispacthed.
+     */
+
+    /* If initial namespace was not given during dispatcher creation (multi namespace API),
+     * verification is sent to hardcoded namespace. This works for verification purposes
+     * because in our environment cluster is configured to operate only if all nodes
+     * are working (so we can do verification to any node). However, this is not optimal
+     * because we do not necessarily connect to such cluster node which will later be
+     * used by client. Also our cluster configuration can change. This needs to be
+     * optimized later (perhaps to connect to all nodes). */
+    std::string nsForVerification;
+    if (initialNamespace)
+        nsForVerification = *initialNamespace;
+    else
+        nsForVerification = "namespace";
+
+    dispatchAsync(std::bind(&AsyncHiredisClusterCommandDispatcher::verifyConnectionReply,
+                            this,
+                            std::placeholders::_1,
+                            std::placeholders::_2),
+                  nsForVerification,
+                  contentsBuilder->build("COMMAND"),
+                  false);
+}
+
+void AsyncHiredisClusterCommandDispatcher::verifyConnectionReply(const std::error_code& error, const redis::Reply& reply)
+{
+    if(error)
+    {
+        logger->error() << "AsyncHiredisClusterCommandDispatcher: connection verification failed: "
+                        << error.message();
+        armConnectionRetryTimer();
+    }
+    else
+    {
+        if (checkRedisModuleCommands(parseCommandListReply(reply)))
+            setConnected();
+        else
+            SHAREDDATALAYER_ABORT("Required Redis module extension commands not available.");
+    }
+}
+
+void AsyncHiredisClusterCommandDispatcher::waitConnectedAsync(const ConnectAck& connectAck)
+{
+    this->connectAck = connectAck;
+    if (serviceState == ServiceState::CONNECTED)
+        engine.postCallback(connectAck);
+}
+
+void AsyncHiredisClusterCommandDispatcher::registerDisconnectCb(const DisconnectCb& disconnectCb)
+{
+    disconnectCallback = disconnectCb;
+}
+
+void AsyncHiredisClusterCommandDispatcher::dispatchAsync(const CommandCb& commandCb,
+                                                         const AsyncConnection::Namespace& ns,
+                                                         const Contents& contents)
+{
+    dispatchAsync(commandCb, ns, contents, true);
+}
+
+void AsyncHiredisClusterCommandDispatcher::dispatchAsync(const CommandCb& commandCb,
+                                                         const AsyncConnection::Namespace& ns,
+                                                         const Contents& contents,
+                                                         bool checkConnectionState)
+{
+    if (checkConnectionState && serviceState != ServiceState::CONNECTED)
+    {
+        engine.postCallback(std::bind(&AsyncHiredisClusterCommandDispatcher::callCommandCbWithError,
+                                       this,
+                                       commandCb,
+                                       std::error_code(AsyncRedisCommandDispatcherErrorCode::NOT_CONNECTED)));
+        return;
+    }
+    cbs.push_back(commandCb);
+    std::vector<const char*> chars;
+    std::transform(contents.stack.begin(), contents.stack.end(),
+                   std::back_inserter(chars), [](const std::string& str){ return str.c_str(); });
+    if (hiredisClusterSystem.redisClusterAsyncCommandArgvWithKey(acc, cb, &cbs.back(), ns.c_str(), static_cast<int>(ns.size()),
+                                                                 static_cast<int>(contents.stack.size()), &chars[0],
+                                                                 &contents.sizes[0]) != REDIS_OK)
+    {
+        removeCb(cbs.back());
+        engine.postCallback(std::bind(&AsyncHiredisClusterCommandDispatcher::callCommandCbWithError,
+                                       this,
+                                       commandCb,
+                                       getRedisError(acc->err, acc->errstr, nullptr)));
+    }
+}
+
+void AsyncHiredisClusterCommandDispatcher::disableCommandCallbacks()
+{
+    clientCallbacksEnabled = false;
+}
+
+void AsyncHiredisClusterCommandDispatcher::callCommandCbWithError(const CommandCb& commandCb, const std::error_code& error)
+{
+    commandCb(error, AsyncRedisReply());
+}
+
+void AsyncHiredisClusterCommandDispatcher::setConnected()
+{
+    serviceState = ServiceState::CONNECTED;
+
+    if (connectAck)
+    {
+        connectAck();
+        connectAck = ConnectAck();
+    }
+}
+
+void AsyncHiredisClusterCommandDispatcher::armConnectionRetryTimer()
+{
+    connectionRetryTimer.arm(connectionRetryTimerDuration,
+                             [this] () { connect(); });
+
+}
+
+void AsyncHiredisClusterCommandDispatcher::handleReply(const CommandCb& commandCb,
+                                                       const std::error_code& error,
+                                                       const redisReply* rr)
+{
+    if (!isValidCb(commandCb))
+        SHAREDDATALAYER_ABORT("Invalid callback function.");
+    if (error)
+        commandCb(error, AsyncRedisReply());
+    else
+        commandCb(error, AsyncRedisReply(*rr));
+    if (!usePermanentCommandCallbacks)
+        removeCb(commandCb);
+}
+
+bool AsyncHiredisClusterCommandDispatcher::isClientCallbacksEnabled() const
+{
+    return clientCallbacksEnabled;
+}
+
+bool AsyncHiredisClusterCommandDispatcher::isValidCb(const CommandCb& commandCb)
+{
+    for (auto i(cbs.begin()); i != cbs.end(); ++i)
+        if (&*i == &commandCb)
+            return true;
+    return false;
+}
+
+void AsyncHiredisClusterCommandDispatcher::removeCb(const CommandCb& commandCb)
+{
+    for (auto i(cbs.begin()); i != cbs.end(); ++i)
+        if (&*i == &commandCb)
+        {
+            cbs.erase(i);
+            break;
+        }
+}
+
+void AsyncHiredisClusterCommandDispatcher::handleDisconnect(const redisAsyncContext* ac)
+{
+    adapter->detach(ac);
+
+    if (disconnectCallback)
+        disconnectCallback();
+}
+
+void AsyncHiredisClusterCommandDispatcher::disconnectHiredisCluster()
+{
+    /* hiredis sometimes crashes if redisClusterAsyncFree is called without being connected (even
+     * if acc is a valid pointer).
+     */
+    if (serviceState == ServiceState::CONNECTED)
+        hiredisClusterSystem.redisClusterAsyncFree(acc);
+
+    serviceState = ServiceState::DISCONNECTED;
+}
diff --git a/src/redis/asynchirediscommanddispatcher.cpp b/src/redis/asynchirediscommanddispatcher.cpp
new file mode 100644
index 0000000..e4195a9
--- /dev/null
+++ b/src/redis/asynchirediscommanddispatcher.cpp
@@ -0,0 +1,328 @@
+/*
+   Copyright (c) 2018-2019 Nokia.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+#include "private/redis/asynchirediscommanddispatcher.hpp"
+#include <algorithm>
+#include <cstring>
+#include <cerrno>
+#include <sstream>
+#include <arpa/inet.h>
+#include "private/abort.hpp"
+#include "private/createlogger.hpp"
+#include "private/engine.hpp"
+#include "private/error.hpp"
+#include "private/logger.hpp"
+#include "private/redis/asyncredisreply.hpp"
+#include "private/redis/reply.hpp"
+#include "private/redis/hiredissystem.hpp"
+#include "private/redis/hiredisepolladapter.hpp"
+#include "private/redis/contents.hpp"
+#include "private/redis/redisgeneral.hpp"
+
+using namespace shareddatalayer;
+using namespace shareddatalayer::redis;
+
+namespace
+{
+    void connectCb(const redisAsyncContext* ac, int status)
+    {
+        bool isConnected = !status;
+        auto instance(static_cast<AsyncHiredisCommandDispatcher*>(ac->data));
+
+        if (isConnected)
+        {
+            std::ostringstream msg;
+            msg << "redis connected, fd: " << ac->c.fd;
+            logInfoOnce(msg.str());
+            instance->verifyConnection();
+        }
+        else
+            instance->setDisconnected();
+
+    }
+
+    void disconnectCb(const redisAsyncContext* ac, int status)
+    {
+        if (status) {
+            std::ostringstream msg;
+            msg << "redis disconnected, status: " << ac->err << ", " << ac->errstr << ", fd: " << ac->c.fd;
+            logErrorOnce(msg.str());
+        }
+        auto instance(static_cast<AsyncHiredisCommandDispatcher*>(ac->data));
+        instance->setDisconnected();
+    }
+
+    void cb(redisAsyncContext* ac, void* rr, void* pd)
+    {
+        auto instance(static_cast<AsyncHiredisCommandDispatcher*>(ac->data));
+        auto reply(static_cast<redisReply*>(rr));
+        auto cb(static_cast<AsyncHiredisCommandDispatcher::CommandCb*>(pd));
+        if (instance->isClientCallbacksEnabled())
+            instance->handleReply(*cb, getRedisError(ac->err, ac->errstr, reply), reply);
+    }
+}
+
+AsyncHiredisCommandDispatcher::AsyncHiredisCommandDispatcher(Engine& engine,
+                                                             const std::string& address,
+                                                             uint16_t port,
+                                                             std::shared_ptr<ContentsBuilder> contentsBuilder,
+                                                             bool usePermanentCommandCallbacks,
+                                                             std::shared_ptr<Logger> logger):
+    AsyncHiredisCommandDispatcher(engine,
+                                  address,
+                                  port,
+                                  contentsBuilder,
+                                  usePermanentCommandCallbacks,
+                                  HiredisSystem::getHiredisSystem(),
+                                  std::make_shared<HiredisEpollAdapter>(engine),
+                                  logger)
+{
+}
+
+AsyncHiredisCommandDispatcher::AsyncHiredisCommandDispatcher(Engine& engine,
+                                                             const std::string& address,
+                                                             uint16_t port,
+                                                             std::shared_ptr<ContentsBuilder> contentsBuilder,
+                                                             bool usePermanentCommandCallbacks,
+                                                             HiredisSystem& hiredisSystem,
+                                                             std::shared_ptr<HiredisEpollAdapter> adapter,
+                                                             std::shared_ptr<Logger> logger):
+    engine(engine),
+    address(address),
+    port(ntohs(port)),
+    contentsBuilder(contentsBuilder),
+    usePermanentCommandCallbacks(usePermanentCommandCallbacks),
+    hiredisSystem(hiredisSystem),
+    adapter(adapter),
+    ac(nullptr),
+    serviceState(ServiceState::DISCONNECTED),
+    clientCallbacksEnabled(true),
+    connectionRetryTimer(engine),
+    connectionRetryTimerDuration(std::chrono::seconds(1)),
+    connectionVerificationRetryTimerDuration(std::chrono::seconds(10)),
+    logger(logger)
+
+{
+    connect();
+}
+
+AsyncHiredisCommandDispatcher::~AsyncHiredisCommandDispatcher()
+{
+    disconnectHiredis();
+}
+
+void AsyncHiredisCommandDispatcher::connect()
+{
+    ac = hiredisSystem.redisAsyncConnect(address.c_str(), port);
+    if (ac == nullptr || ac->err)
+    {
+        setDisconnected();
+        return;
+    }
+    ac->data = this;
+    adapter->attach(ac);
+    hiredisSystem.redisAsyncSetConnectCallback(ac, connectCb);
+    hiredisSystem.redisAsyncSetDisconnectCallback(ac, disconnectCb);
+}
+
+void AsyncHiredisCommandDispatcher::verifyConnection()
+{
+   /* When Redis has max amount of users, it will still accept new connections but will
+    * close them immediately. Therefore, we need to verify that just established connection
+    * really works. This prevents calling client readyAck callback for a connection that
+    * will be terminated immediately.
+    */
+    /* Connection verification is now done by doing redis command list query. Because we anyway
+     * need to verify that Redis has required commands, we can now combine these two operations
+     * (command list query and connection verification). If either one of the functionalities
+     * is not needed in the future and it is removed, remember to still leave the other one.
+     */
+    serviceState = ServiceState::CONNECTION_VERIFICATION;
+    /* Disarm retry timer as now we are connected to hiredis. This ensures timer disarm if
+     * we are spontaneously connected to redis while timer is running. If connection verification
+     * fails, timer is armed again (normal handling in connection verification).
+     */
+    connectionRetryTimer.disarm();
+    dispatchAsync(std::bind(&AsyncHiredisCommandDispatcher::verifyConnectionReply,
+                            this,
+                            std::placeholders::_1,
+                            std::placeholders::_2),
+                  contentsBuilder->build("COMMAND"),
+                  false);
+}
+
+void AsyncHiredisCommandDispatcher::verifyConnectionReply(const std::error_code& error,
+                                                          const redis::Reply& reply)
+{
+    if(error)
+    {
+        logger->error() << "AsyncHiredisCommandDispatcher: connection verification failed: "
+                        << error.message();
+
+        if (!connectionRetryTimer.isArmed())
+        {
+            /* Typically if connection verification fails, hiredis will call disconnect callback and
+             * whole connection establishment procedure will be restarted via that. To ensure that
+             * we will retry verification even if connection would not be disconnected this timer
+             * is set. If connection is later disconnected, this timer is disarmed (when disconnect
+             * callback handling arms this timer again).
+             */
+            armConnectionRetryTimer(connectionVerificationRetryTimerDuration,
+                                    std::bind(&AsyncHiredisCommandDispatcher::verifyConnection, this));
+        }
+    }
+    else
+    {
+        if (checkRedisModuleCommands(parseCommandListReply(reply)))
+            setConnected();
+        else
+            SHAREDDATALAYER_ABORT("Required Redis module extension commands not available.");
+    }
+}
+
+void AsyncHiredisCommandDispatcher::waitConnectedAsync(const ConnectAck& connectAck)
+{
+    this->connectAck = connectAck;
+    if (serviceState == ServiceState::CONNECTED)
+        engine.postCallback(connectAck);
+}
+
+void AsyncHiredisCommandDispatcher::registerDisconnectCb(const DisconnectCb& disconnectCb)
+{
+    disconnectCallback = disconnectCb;
+}
+
+void AsyncHiredisCommandDispatcher::dispatchAsync(const CommandCb& commandCb,
+                                                  const AsyncConnection::Namespace&,
+                                                  const Contents& contents)
+{
+    dispatchAsync(commandCb, contents, true);
+}
+
+void AsyncHiredisCommandDispatcher::dispatchAsync(const CommandCb& commandCb,
+                                                  const Contents& contents,
+                                                  bool checkConnectionState)
+{
+    if (checkConnectionState && serviceState != ServiceState::CONNECTED)
+    {
+        engine.postCallback(std::bind(&AsyncHiredisCommandDispatcher::callCommandCbWithError,
+                                       this,
+                                       commandCb,
+                                       std::error_code(AsyncRedisCommandDispatcherErrorCode::NOT_CONNECTED)));
+        return;
+    }
+    cbs.push_back(commandCb);
+    std::vector<const char*> chars;
+    std::transform(contents.stack.begin(), contents.stack.end(),
+                   std::back_inserter(chars), [](const std::string& str){ return str.c_str(); });
+    if (hiredisSystem.redisAsyncCommandArgv(ac, cb, &cbs.back(), static_cast<int>(contents.stack.size()),
+                                            &chars[0], &contents.sizes[0]) != REDIS_OK)
+    {
+        removeCb(cbs.back());
+        engine.postCallback(std::bind(&AsyncHiredisCommandDispatcher::callCommandCbWithError,
+                                       this,
+                                       commandCb,
+                                       getRedisError(ac->err, ac->errstr, nullptr)));
+    }
+}
+
+void AsyncHiredisCommandDispatcher::disableCommandCallbacks()
+{
+    clientCallbacksEnabled = false;
+}
+
+void AsyncHiredisCommandDispatcher::callCommandCbWithError(const CommandCb& commandCb,
+                                                           const std::error_code& error)
+{
+    commandCb(error, AsyncRedisReply());
+}
+
+void AsyncHiredisCommandDispatcher::setConnected()
+{
+    serviceState = ServiceState::CONNECTED;
+
+    if (connectAck)
+    {
+        connectAck();
+        connectAck = ConnectAck();
+    }
+}
+
+void AsyncHiredisCommandDispatcher::setDisconnected()
+{
+    serviceState = ServiceState::DISCONNECTED;
+
+    if (disconnectCallback)
+        disconnectCallback();
+
+    armConnectionRetryTimer(connectionRetryTimerDuration,
+                            std::bind(&AsyncHiredisCommandDispatcher::connect, this));
+}
+
+void AsyncHiredisCommandDispatcher::handleReply(const CommandCb& commandCb,
+                                                const std::error_code& error,
+                                                const redisReply* rr)
+{
+    if (!isValidCb(commandCb))
+        SHAREDDATALAYER_ABORT("Invalid callback function.");
+    if (error)
+        commandCb(error, AsyncRedisReply());
+    else
+        commandCb(error, AsyncRedisReply(*rr));
+    if (!usePermanentCommandCallbacks)
+        removeCb(commandCb);
+}
+
+bool AsyncHiredisCommandDispatcher::isClientCallbacksEnabled() const
+{
+    return clientCallbacksEnabled;
+}
+
+bool AsyncHiredisCommandDispatcher::isValidCb(const CommandCb& commandCb)
+{
+    for (auto i(cbs.begin()); i != cbs.end(); ++i)
+        if (&*i == &commandCb)
+            return true;
+    return false;
+}
+
+void AsyncHiredisCommandDispatcher::removeCb(const CommandCb& commandCb)
+{
+    for (auto i(cbs.begin()); i != cbs.end(); ++i)
+        if (&*i == &commandCb)
+        {
+            cbs.erase(i);
+            break;
+        }
+}
+
+void AsyncHiredisCommandDispatcher::disconnectHiredis()
+{
+    /* hiredis sometimes crashes if redisAsyncFree is called without being connected (even
+     * if ac is a valid pointer).
+     */
+    if (serviceState == ServiceState::CONNECTED || serviceState == ServiceState::CONNECTION_VERIFICATION)
+        hiredisSystem.redisAsyncFree(ac);
+
+    //disconnect callback handler will update serviceState
+}
+
+void AsyncHiredisCommandDispatcher::armConnectionRetryTimer(Timer::Duration duration,
+                                                            std::function<void()> retryAction)
+{
+    connectionRetryTimer.arm(duration,
+                             [retryAction] () { retryAction(); });
+}
diff --git a/src/redis/asynchiredisdatabasediscovery.cpp b/src/redis/asynchiredisdatabasediscovery.cpp
new file mode 100644
index 0000000..7060995
--- /dev/null
+++ b/src/redis/asynchiredisdatabasediscovery.cpp
@@ -0,0 +1,52 @@
+/*
+   Copyright (c) 2018-2019 Nokia.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+#include "private/asyncconnection.hpp"
+#include "private/redis/asynchiredisdatabasediscovery.hpp"
+#include "private/engine.hpp"
+#include "private/logger.hpp"
+#include "private/redis/asynccommanddispatcher.hpp"
+#include "private/redis/contentsbuilder.hpp"
+
+using namespace shareddatalayer;
+using namespace shareddatalayer::redis;
+
+AsyncHiredisDatabaseDiscovery::AsyncHiredisDatabaseDiscovery(std::shared_ptr<Engine> engine,
+                                                             const boost::optional<std::string>& ns,
+                                                             DatabaseInfo::Type databaseType,
+                                                             const DatabaseConfiguration::Addresses& databaseAddresses,
+                                                             std::shared_ptr<Logger> logger):
+    engine(engine),
+    ns(ns),
+    databaseType(databaseType),
+    databaseAddresses(databaseAddresses),
+    logger(logger)
+{
+}
+
+void AsyncHiredisDatabaseDiscovery::setStateChangedCb(const StateChangedCb& stateChangedCb)
+{
+    /* Note: Current implementation does not monitor possible database configuration changes.
+     * If that is needed, we would probably need to monitor json configuration file changes.
+     */
+    const DatabaseInfo databaseInfo = { databaseAddresses, databaseType, ns, DatabaseInfo::Discovery::HIREDIS };
+    engine->postCallback(std::bind(stateChangedCb,
+                                   databaseInfo));
+}
+
+void AsyncHiredisDatabaseDiscovery::clearStateChangedCb()
+{
+}
diff --git a/src/redis/asyncredisreply.cpp b/src/redis/asyncredisreply.cpp
new file mode 100644
index 0000000..cfa0fab
--- /dev/null
+++ b/src/redis/asyncredisreply.cpp
@@ -0,0 +1,89 @@
+/*
+   Copyright (c) 2018-2019 Nokia.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+#include "private/redis/asyncredisreply.hpp"
+
+using namespace shareddatalayer;
+using namespace shareddatalayer::redis;
+
+AsyncRedisReply::AsyncRedisReply():
+    type(Type::NIL),
+    integer(0),
+    dataItem { { }, 0 }
+{
+}
+
+AsyncRedisReply::AsyncRedisReply(const redisReply& rr):
+    integer(0),
+    dataItem { { }, 0 },
+    typeMap { { REDIS_REPLY_NIL, Type::NIL }, { REDIS_REPLY_INTEGER, Type::INTEGER },
+              { REDIS_REPLY_STATUS, Type::STATUS }, { REDIS_REPLY_STRING, Type::STRING },
+              { REDIS_REPLY_ARRAY, Type::ARRAY } }
+{
+    auto res(typeMap.find(rr.type));
+    if (res != typeMap.end())
+    {
+        type = res->second;
+        parseReply(rr);
+    }
+}
+
+AsyncRedisReply::Type AsyncRedisReply::getType() const
+{
+    return type;
+}
+
+long long AsyncRedisReply::getInteger() const
+{
+    return integer;
+}
+
+const AsyncRedisReply::DataItem* AsyncRedisReply::getString() const
+{
+    return &dataItem;
+}
+
+const AsyncRedisReply::ReplyVector* AsyncRedisReply::getArray() const
+{
+    return &replyVector;
+}
+
+void AsyncRedisReply::parseReply(const redisReply& rr)
+{
+    switch (type)
+    {
+        case Type::INTEGER:
+            integer = rr.integer;
+            break;
+        case Type::STATUS:
+        case Type::STRING:
+            dataItem.str = std::string(rr.str, static_cast<size_t>(rr.len));
+            dataItem.len = rr.len;
+            break;
+        case Type::ARRAY:
+            parseArray(rr);
+            break;
+        case Type::NIL:
+        default:
+            break;
+    }
+}
+
+void AsyncRedisReply::parseArray(const redisReply& rr)
+{
+    for (auto i(0U); i < rr.elements; ++i)
+        replyVector.push_back(std::make_shared<AsyncRedisReply>(*rr.element[i]));
+}
diff --git a/src/redis/asyncredisstorage.cpp b/src/redis/asyncredisstorage.cpp
new file mode 100644
index 0000000..22d4b2b
--- /dev/null
+++ b/src/redis/asyncredisstorage.cpp
@@ -0,0 +1,570 @@
+/*
+   Copyright (c) 2018-2019 Nokia.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+#include "config.h"
+#include <sstream>
+#include "private/error.hpp"
+#include <sdl/emptynamespace.hpp>
+#include <sdl/invalidnamespace.hpp>
+#include <sdl/publisherid.hpp>
+#include "private/abort.hpp"
+#include "private/createlogger.hpp"
+#include "private/engine.hpp"
+#include "private/logger.hpp"
+#include "private/namespacevalidator.hpp"
+#include "private/configurationreader.hpp"
+#include "private/redis/asynccommanddispatcher.hpp"
+#include "private/redis/asyncdatabasediscovery.hpp"
+#include "private/redis/asyncredisstorage.hpp"
+#include "private/redis/contents.hpp"
+#include "private/redis/contentsbuilder.hpp"
+#include "private/redis/redisgeneral.hpp"
+#include "private/redis/reply.hpp"
+
+using namespace shareddatalayer;
+using namespace shareddatalayer::redis;
+
+/*  TODO: This implementation contains lot of duplicated code with old API (asyncRedisConnection).
+ *  When this new API is fully ready and tested old API implementation could be changed to utilize this
+ *  (bit like sync API utilizes async API).
+ */
+
+namespace
+{
+    std::shared_ptr<AsyncCommandDispatcher> asyncCommandDispatcherCreator(Engine& engine,
+                                                                          const DatabaseInfo& databaseInfo,
+                                                                          std::shared_ptr<ContentsBuilder> contentsBuilder,
+                                                                          std::shared_ptr<Logger> logger)
+    {
+        return AsyncCommandDispatcher::create(engine,
+                                              databaseInfo,
+                                              contentsBuilder,
+                                              false,
+                                              logger);
+    }
+
+    class AsyncRedisStorageErrorCategory: public std::error_category
+    {
+    public:
+        AsyncRedisStorageErrorCategory() = default;
+
+        const char* name() const noexcept override;
+
+        std::string message(int condition) const override;
+
+        std::error_condition default_error_condition(int condition) const noexcept override;
+    };
+
+    const char* AsyncRedisStorageErrorCategory::name() const noexcept
+    {
+        return "asyncredisstorage";
+    }
+
+    std::string AsyncRedisStorageErrorCategory::message(int condition) const
+    {
+        switch (static_cast<AsyncRedisStorage::ErrorCode>(condition))
+        {
+            case AsyncRedisStorage::ErrorCode::SUCCESS:
+                return std::error_code().message();
+            case AsyncRedisStorage::ErrorCode::REDIS_NOT_YET_DISCOVERED:
+                return "connection to the underlying data storage not yet available";
+            case AsyncRedisStorage::ErrorCode::INVALID_NAMESPACE:
+                return "invalid namespace identifier passed to SDL API";
+            case AsyncRedisStorage::ErrorCode::END_MARKER:
+                logErrorOnce("AsyncRedisStorage::ErrorCode::END_MARKER is not meant to be queried (it is only for enum loop control)");
+                return "unsupported error code for message()";
+            default:
+                return "description missing for AsyncRedisStorageErrorCategory error: " + std::to_string(condition);
+        }
+    }
+
+    std::error_condition AsyncRedisStorageErrorCategory::default_error_condition(int condition) const noexcept
+    {
+        switch (static_cast<AsyncRedisStorage::ErrorCode>(condition))
+        {
+            case AsyncRedisStorage::ErrorCode::SUCCESS:
+                return InternalError::SUCCESS;
+            case AsyncRedisStorage::ErrorCode::REDIS_NOT_YET_DISCOVERED:
+                return InternalError::SDL_NOT_READY;
+            case AsyncRedisStorage::ErrorCode::INVALID_NAMESPACE:
+                return InternalError::SDL_RECEIVED_INVALID_PARAMETER;
+            case AsyncRedisStorage::ErrorCode::END_MARKER:
+                logErrorOnce("AsyncRedisStorage::ErrorCode::END_MARKER is not meant to be mapped to InternalError (it is only for enum loop control)");
+                return InternalError::SDL_ERROR_CODE_LOGIC_ERROR;
+            default:
+                std::ostringstream msg;
+                msg << "default error condition missing for AsyncRedisStorageErrorCategory error: "
+                    << condition;
+                logErrorOnce(msg.str());
+                return InternalError::SDL_ERROR_CODE_LOGIC_ERROR;
+        }
+    }
+
+    AsyncStorage::DataMap buildDataMap(const AsyncStorage::Keys& keys, const Reply::ReplyVector& replyVector)
+    {
+        AsyncStorage::DataMap dataMap;
+        auto i(0U);
+        for (const auto& j : keys)
+        {
+            if (replyVector[i]->getType() == Reply::Type::STRING)
+            {
+                AsyncStorage::Data data;
+                auto dataStr(replyVector[i]->getString());
+                for (ReplyStringLength k(0); k < dataStr->len; ++k)
+                    data.push_back(static_cast<uint8_t>(dataStr->str[static_cast<size_t>(k)]));
+                dataMap.insert({ j, data });
+            }
+            ++i;
+        }
+        return dataMap;
+    }
+
+    AsyncStorage::Key getKey(const Reply::DataItem& item)
+    {
+        std::string str(item.str.c_str(), static_cast<size_t>(item.len));
+        auto res(str.find(AsyncRedisStorage::SEPARATOR));
+        return str.substr(res + 1);
+    }
+
+    AsyncStorage::Keys getKeys(const Reply::ReplyVector& replyVector)
+    {
+        AsyncStorage::Keys keys;
+        for (const auto& i : replyVector)
+        {
+            if (i->getType() == Reply::Type::STRING)
+                keys.insert(getKey(*i->getString()));
+        }
+        return keys;
+    }
+
+    void escapeRedisSearchPatternCharacters(std::string& stringToProcess)
+    {
+        const std::string redisSearchPatternCharacters = R"(*?[]\)";
+
+        std::size_t foundPosition = stringToProcess.find_first_of(redisSearchPatternCharacters);
+
+        while (foundPosition != std::string::npos)
+        {
+            stringToProcess.insert(foundPosition, R"(\)");
+            foundPosition = stringToProcess.find_first_of(redisSearchPatternCharacters, foundPosition + 2);
+        }
+    }
+}
+
+AsyncRedisStorage::ErrorCode& shareddatalayer::operator++ (AsyncRedisStorage::ErrorCode& ecEnum)
+{
+    if (ecEnum == AsyncRedisStorage::ErrorCode::END_MARKER)
+        throw std::out_of_range("for AsyncRedisStorage::ErrorCode& operator ++");
+    ecEnum = AsyncRedisStorage::ErrorCode(static_cast<std::underlying_type<AsyncRedisStorage::ErrorCode>::type>(ecEnum) + 1);
+    return ecEnum;
+}
+
+std::error_code shareddatalayer::make_error_code(AsyncRedisStorage::ErrorCode errorCode)
+{
+    return std::error_code(static_cast<int>(errorCode), AsyncRedisStorage::errorCategory());
+}
+
+const std::error_category& AsyncRedisStorage::errorCategory() noexcept
+{
+    static const AsyncRedisStorageErrorCategory theAsyncRedisStorageErrorCategory;
+    return theAsyncRedisStorageErrorCategory;
+}
+
+AsyncRedisStorage::AsyncRedisStorage(std::shared_ptr<Engine> engine,
+                                     std::shared_ptr<AsyncDatabaseDiscovery> discovery,
+                                     const boost::optional<PublisherId>& pId,
+                                     std::shared_ptr<NamespaceConfigurations> namespaceConfigurations,
+                                     std::shared_ptr<Logger> logger):
+    AsyncRedisStorage(engine,
+                      discovery,
+                      pId,
+                      namespaceConfigurations,
+                      ::asyncCommandDispatcherCreator,
+                      std::make_shared<redis::ContentsBuilder>(SEPARATOR),
+                      logger)
+{
+}
+
+AsyncRedisStorage::AsyncRedisStorage(std::shared_ptr<Engine> engine,
+                                     std::shared_ptr<redis::AsyncDatabaseDiscovery> discovery,
+                                     const boost::optional<PublisherId>& pId,
+                                     std::shared_ptr<NamespaceConfigurations> namespaceConfigurations,
+                                     const AsyncCommandDispatcherCreator& asyncCommandDispatcherCreator,
+                                     std::shared_ptr<redis::ContentsBuilder> contentsBuilder,
+                                     std::shared_ptr<Logger> logger):
+    engine(engine),
+    dispatcher(nullptr),
+    discovery(discovery),
+    publisherId(pId),
+    asyncCommandDispatcherCreator(asyncCommandDispatcherCreator),
+    contentsBuilder(contentsBuilder),
+    namespaceConfigurations(namespaceConfigurations),
+    logger(logger)
+{
+    if(publisherId && (*publisherId).empty())
+    {
+        throw std::invalid_argument("AsyncRedisStorage: empty publisher ID string given");
+    }
+
+    discovery->setStateChangedCb([this](const redis::DatabaseInfo& databaseInfo)
+                                 {
+                                     serviceStateChanged(databaseInfo);
+                                 });
+}
+
+AsyncRedisStorage::~AsyncRedisStorage()
+{
+    if (discovery)
+        discovery->clearStateChangedCb();
+    if (dispatcher)
+        dispatcher->disableCommandCallbacks();
+}
+
+redis::DatabaseInfo& AsyncRedisStorage::getDatabaseInfo()
+{
+    return dbInfo;
+}
+
+void AsyncRedisStorage::serviceStateChanged(const redis::DatabaseInfo& newDatabaseInfo)
+{
+    dispatcher = asyncCommandDispatcherCreator(*engine,
+                                               newDatabaseInfo,
+                                               contentsBuilder,
+                                               logger);
+    if (readyAck)
+        dispatcher->waitConnectedAsync([this]()
+                                       {
+                                           readyAck(std::error_code());
+                                           readyAck = ReadyAck();
+                                       });
+    dbInfo = newDatabaseInfo;
+}
+
+int AsyncRedisStorage::fd() const
+{
+    return engine->fd();
+}
+
+void AsyncRedisStorage::handleEvents()
+{
+    engine->handleEvents();
+}
+
+bool AsyncRedisStorage::canOperationBePerformed(const Namespace& ns,
+                                                boost::optional<bool> noKeysGiven,
+                                                std::error_code& ecToReturn)
+{
+    if (!::isValidNamespace(ns))
+    {
+        logErrorOnce("Invalid namespace identifier: " + ns + " passed to SDL");
+        ecToReturn = std::error_code(ErrorCode::INVALID_NAMESPACE);
+        return false;
+    }
+    if (noKeysGiven && *noKeysGiven)
+    {
+        ecToReturn = std::error_code();
+        return false;
+    }
+    if (!dispatcher)
+    {
+        ecToReturn = std::error_code(ErrorCode::REDIS_NOT_YET_DISCOVERED);
+        return false;
+    }
+
+    ecToReturn = std::error_code();
+    return true;
+}
+
+void AsyncRedisStorage::waitReadyAsync(const Namespace&,
+                                       const ReadyAck& readyAck)
+{
+    if (dispatcher)
+        dispatcher->waitConnectedAsync([readyAck]()
+                                       {
+                                           readyAck(std::error_code());
+                                       });
+    else
+        this->readyAck = readyAck;
+}
+
+void AsyncRedisStorage::setAsync(const Namespace& ns,
+                                 const DataMap& dataMap,
+                                 const ModifyAck& modifyAck)
+{
+    std::error_code ec;
+
+    if (!canOperationBePerformed(ns, dataMap.empty(), ec))
+    {
+        engine->postCallback(std::bind(modifyAck, ec));
+        return;
+    }
+
+    if (namespaceConfigurations->areNotificationsEnabled(ns))
+        dispatcher->dispatchAsync(std::bind(&AsyncRedisStorage::modificationCommandCallback,
+                                            this,
+                                            std::placeholders::_1,
+                                            std::placeholders::_2,
+                                            modifyAck),
+                                  ns,
+                                  contentsBuilder->build("MSETPUB", ns, dataMap, ns, getPublishMessage()));
+    else
+        dispatcher->dispatchAsync(std::bind(&AsyncRedisStorage::modificationCommandCallback,
+                                            this,
+                                            std::placeholders::_1,
+                                            std::placeholders::_2,
+                                            modifyAck),
+                                  ns,
+                                  contentsBuilder->build("MSET", ns, dataMap));
+}
+
+void AsyncRedisStorage::modificationCommandCallback(const std::error_code& error,
+                                                    const Reply&,
+                                                    const ModifyAck& modifyAck )
+{
+    modifyAck(error);
+}
+
+void AsyncRedisStorage::conditionalCommandCallback(const std::error_code& error,
+                                                   const Reply& reply,
+                                                   const ModifyIfAck& modifyIfAck)
+{
+    auto type(reply.getType());
+    if (error ||
+        (type == Reply::Type::NIL) || // SETIE(PUB)
+        ((type == Reply::Type::INTEGER) && (reply.getInteger() != 1))) // SETNX(PUB) and DELIE(PUB)
+        modifyIfAck(error, false);
+    else
+        modifyIfAck(error, true);
+}
+
+void AsyncRedisStorage::setIfAsync(const Namespace& ns,
+                                   const Key& key,
+                                   const Data& oldData,
+                                   const Data& newData,
+                                   const ModifyIfAck& modifyIfAck)
+{
+    std::error_code ec;
+
+    if (!canOperationBePerformed(ns, boost::none, ec))
+    {
+        engine->postCallback(std::bind(modifyIfAck, ec, false));
+        return;
+    }
+
+    if (namespaceConfigurations->areNotificationsEnabled(ns))
+        dispatcher->dispatchAsync(std::bind(&AsyncRedisStorage::conditionalCommandCallback,
+                                            this,
+                                            std::placeholders::_1,
+                                            std::placeholders::_2,
+                                            modifyIfAck),
+                                  ns,
+                                  contentsBuilder->build("SETIEPUB", ns, key, newData, oldData, ns, getPublishMessage()));
+    else
+        dispatcher->dispatchAsync(std::bind(&AsyncRedisStorage::conditionalCommandCallback,
+                                            this,
+                                            std::placeholders::_1,
+                                            std::placeholders::_2,
+                                            modifyIfAck),
+                                  ns,
+                                  contentsBuilder->build("SETIE", ns, key, newData, oldData));
+}
+
+void AsyncRedisStorage::removeIfAsync(const Namespace& ns,
+                                      const Key& key,
+                                      const Data& data,
+                                      const ModifyIfAck& modifyIfAck)
+{
+    std::error_code ec;
+
+    if (!canOperationBePerformed(ns, boost::none, ec))
+    {
+        engine->postCallback(std::bind(modifyIfAck, ec, false));
+        return;
+    }
+
+    if (namespaceConfigurations->areNotificationsEnabled(ns))
+        dispatcher->dispatchAsync(std::bind(&AsyncRedisStorage::conditionalCommandCallback,
+                                            this,
+                                            std::placeholders::_1,
+                                            std::placeholders::_2,
+                                            modifyIfAck),
+                                  ns,
+                                  contentsBuilder->build("DELIEPUB", ns, key, data, ns, getPublishMessage()));
+    else
+        dispatcher->dispatchAsync(std::bind(&AsyncRedisStorage::conditionalCommandCallback,
+                                            this,
+                                            std::placeholders::_1,
+                                            std::placeholders::_2,
+                                            modifyIfAck),
+                                  ns,
+                                  contentsBuilder->build("DELIE", ns, key, data));
+}
+
+std::string AsyncRedisStorage::getPublishMessage() const
+{
+    if(publisherId)
+        return *publisherId;
+    else
+        return NO_PUBLISHER;
+}
+
+void AsyncRedisStorage::setIfNotExistsAsync(const Namespace& ns,
+                                            const Key& key,
+                                            const Data& data,
+                                            const ModifyIfAck& modifyIfAck)
+{
+    std::error_code ec;
+
+    if (!canOperationBePerformed(ns, boost::none, ec))
+    {
+        engine->postCallback(std::bind(modifyIfAck, ec, false));
+        return;
+    }
+
+    if (namespaceConfigurations->areNotificationsEnabled(ns))
+        dispatcher->dispatchAsync(std::bind(&AsyncRedisStorage::conditionalCommandCallback,
+                                            this,
+                                            std::placeholders::_1,
+                                            std::placeholders::_2,
+                                            modifyIfAck),
+                                  ns,
+                                  contentsBuilder->build("SETNXPUB", ns, key, data, ns ,getPublishMessage()));
+    else
+        dispatcher->dispatchAsync(std::bind(&AsyncRedisStorage::conditionalCommandCallback,
+                                            this,
+                                            std::placeholders::_1,
+                                            std::placeholders::_2,
+                                            modifyIfAck),
+                                  ns,
+                                  contentsBuilder->build("SETNX", ns, key, data));
+}
+
+void AsyncRedisStorage::getAsync(const Namespace& ns,
+                                 const Keys& keys,
+                                 const GetAck& getAck)
+{
+    std::error_code ec;
+
+    if (!canOperationBePerformed(ns, keys.empty(), ec))
+    {
+        engine->postCallback(std::bind(getAck, ec, DataMap()));
+        return;
+    }
+
+    dispatcher->dispatchAsync([getAck, keys](const std::error_code& error,
+                                                 const Reply& reply)
+                              {
+                                  if (error)
+                                      getAck(error, DataMap());
+                                  else
+                                      getAck(std::error_code(), buildDataMap(keys, *reply.getArray()));
+                              },
+                              ns,
+                              contentsBuilder->build("MGET", ns, keys));
+}
+
+void AsyncRedisStorage::removeAsync(const Namespace& ns,
+                                    const Keys& keys,
+                                    const ModifyAck& modifyAck)
+{
+    std::error_code ec;
+
+    if (!canOperationBePerformed(ns, keys.empty(), ec))
+    {
+        engine->postCallback(std::bind(modifyAck, ec));
+        return;
+    }
+
+    if (namespaceConfigurations->areNotificationsEnabled(ns))
+        dispatcher->dispatchAsync(std::bind(&AsyncRedisStorage::modificationCommandCallback,
+                                            this,
+                                            std::placeholders::_1,
+                                            std::placeholders::_2,
+                                            modifyAck),
+                                  ns,
+                                  contentsBuilder->build("DELPUB", ns, keys, ns, getPublishMessage()));
+    else
+        dispatcher->dispatchAsync(std::bind(&AsyncRedisStorage::modificationCommandCallback,
+                                            this,
+                                            std::placeholders::_1,
+                                            std::placeholders::_2,
+                                            modifyAck),
+                                  ns,
+                                  contentsBuilder->build("DEL", ns, keys));
+}
+
+void AsyncRedisStorage::findKeysAsync(const Namespace& ns,
+                                      const std::string& keyPrefix,
+                                      const FindKeysAck& findKeysAck)
+{
+    //TODO: update to more optimal solution than current KEYS-based one.
+    std::error_code ec;
+
+    if (!canOperationBePerformed(ns, boost::none, ec))
+    {
+        engine->postCallback(std::bind(findKeysAck, ec, Keys()));
+        return;
+    }
+
+    dispatcher->dispatchAsync([findKeysAck](const std::error_code& error, const Reply& reply)
+                              {
+                                  if (error)
+                                      findKeysAck(error, Keys());
+                                  else
+                                      findKeysAck(std::error_code(), getKeys(*reply.getArray()));
+                              },
+                              ns,
+                              contentsBuilder->build("KEYS", buildKeyPrefixSearchPattern(ns, keyPrefix)));
+}
+
+void AsyncRedisStorage::removeAllAsync(const Namespace& ns,
+                                       const ModifyAck& modifyAck)
+{
+    std::error_code ec;
+
+    if (!canOperationBePerformed(ns, boost::none, ec))
+    {
+        engine->postCallback(std::bind(modifyAck, ec));
+        return;
+    }
+
+    dispatcher->dispatchAsync([this, modifyAck, ns](const std::error_code& error, const Reply& reply)
+                              {
+                                  if (error)
+                                  {
+                                      modifyAck(error);
+                                      return;
+                                  }
+                                  const auto& array(*reply.getArray());
+                                  if (array.empty())
+                                      modifyAck(std::error_code());
+                                  else
+                                  {
+                                      removeAsync(ns, getKeys(array), modifyAck);
+                                  }
+                              },
+                              ns,
+                              contentsBuilder->build("KEYS", buildKeyPrefixSearchPattern(ns, "")));
+}
+
+std::string AsyncRedisStorage::buildKeyPrefixSearchPattern(const Namespace& ns, const std::string& keyPrefix) const
+{
+    std::string escapedKeyPrefix = keyPrefix;
+    escapeRedisSearchPatternCharacters(escapedKeyPrefix);
+    std::ostringstream oss;
+    oss << '{' << ns << '}' << SEPARATOR << escapedKeyPrefix << "*";
+    return oss.str();
+}
diff --git a/src/redis/contentsbuilder.cpp b/src/redis/contentsbuilder.cpp
new file mode 100644
index 0000000..6370be1
--- /dev/null
+++ b/src/redis/contentsbuilder.cpp
@@ -0,0 +1,208 @@
+/*
+   Copyright (c) 2018-2019 Nokia.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+#include "private/redis/contentsbuilder.hpp"
+#include "private/redis/contents.hpp"
+
+using namespace shareddatalayer;
+using namespace shareddatalayer::redis;
+
+ContentsBuilder::ContentsBuilder(const char nsKeySeparator):
+    nsKeySeparator(nsKeySeparator)
+{
+}
+
+ContentsBuilder::~ContentsBuilder()
+{
+}
+
+Contents ContentsBuilder::build(const std::string& string) const
+{
+    Contents contents;
+    addString(contents, string);
+    return contents;
+}
+
+Contents ContentsBuilder::build(const std::string& string,
+                                const std::string& string2) const
+{
+    Contents contents;
+    addString(contents, string);
+    addString(contents, string2);
+    return contents;
+}
+
+Contents ContentsBuilder::build(const std::string& string,
+                                const std::string& string2,
+                                const std::string& string3) const
+{
+    Contents contents;
+    addString(contents, string);
+    addString(contents, string2);
+    addString(contents, string3);
+    return contents;
+}
+
+Contents ContentsBuilder::build(const std::string& string,
+                                const AsyncConnection::Namespace& ns,
+                                const AsyncConnection::DataMap& dataMap) const
+{
+    Contents contents;
+    addString(contents, string);
+    addDataMap(contents, ns, dataMap);
+    return contents;
+}
+
+Contents ContentsBuilder::build(const std::string& string,
+                                const AsyncConnection::Namespace& ns,
+                                const AsyncConnection::DataMap& dataMap,
+                                const std::string& string2,
+                                const std::string& string3) const
+{
+    Contents contents;
+    addString(contents, string);
+    addDataMap(contents, ns, dataMap);
+    addString(contents, string2);
+    addString(contents, string3);
+    return contents;
+}
+
+Contents ContentsBuilder::build(const std::string& string,
+                                const AsyncConnection::Namespace& ns,
+                                const AsyncConnection::Key& key,
+                                const AsyncConnection::Data& data) const
+{
+    Contents contents;
+    addString(contents, string);
+    addKey(contents, ns, key);
+    addData(contents, data);
+    return contents;
+}
+
+Contents ContentsBuilder::build(const std::string& string,
+                                const AsyncConnection::Namespace& ns,
+                                const AsyncConnection::Key& key,
+                                const AsyncConnection::Data& data,
+                                const std::string& string2,
+                                const std::string& string3) const
+{
+    Contents contents;
+    addString(contents, string);
+    addKey(contents, ns, key);
+    addData(contents, data);
+    addString(contents, string2);
+    addString(contents, string3);
+    return contents;
+}
+
+Contents ContentsBuilder::build(const std::string& string,
+                                const AsyncConnection::Namespace& ns,
+                                const AsyncConnection::Key& key,
+                                const AsyncConnection::Data& data,
+                                const AsyncConnection::Data& data2) const
+{
+    Contents contents;
+    addString(contents, string);
+    addKey(contents, ns, key);
+    addData(contents, data);
+    addData(contents, data2);
+    return contents;
+}
+
+Contents ContentsBuilder::build(const std::string& string,
+                                const AsyncConnection::Namespace& ns,
+                                const AsyncConnection::Key& key,
+                                const AsyncConnection::Data& data,
+                                const AsyncConnection::Data& data2,
+                                const std::string& string2,
+                                const std::string& string3) const
+{
+    Contents contents;
+    addString(contents, string);
+    addKey(contents, ns, key);
+    addData(contents, data);
+    addData(contents, data2);
+    addString(contents, string2);
+    addString(contents, string3);
+    return contents;
+}
+
+Contents ContentsBuilder::build(const std::string& string,
+                                const AsyncConnection::Namespace& ns,
+                                const AsyncConnection::Keys& keys) const
+{
+    Contents contents;
+    addString(contents, string);
+    addKeys(contents, ns, keys);
+    return contents;
+}
+
+Contents ContentsBuilder::build(const std::string& string,
+                                const AsyncConnection::Namespace& ns,
+                                const AsyncConnection::Keys& keys,
+                                const std::string& string2,
+                                const std::string& string3) const
+{
+    Contents contents;
+    addString(contents, string);
+    addKeys(contents, ns, keys);
+    addString(contents, string2);
+    addString(contents, string3);
+    return contents;
+}
+
+void ContentsBuilder::addString(Contents& contents,
+                                const std::string& string) const
+{
+    contents.stack.push_back(string);
+    contents.sizes.push_back(string.size());
+}
+
+void ContentsBuilder::addDataMap(Contents& contents,
+                                 const AsyncConnection::Namespace& ns,
+                                 const AsyncConnection::DataMap& dataMap) const
+{
+    for (const auto& i : dataMap)
+    {
+        addKey(contents, ns, i.first);
+        addData(contents, i.second);
+    }
+}
+
+void ContentsBuilder::addKey(Contents& contents,
+                             const AsyncConnection::Namespace& ns,
+                             const AsyncConnection::Key& key) const
+{
+    auto content('{' + ns + '}' + nsKeySeparator + key);
+    contents.stack.push_back(content);
+    contents.sizes.push_back((content).size());
+}
+
+void ContentsBuilder::addData(Contents& contents,
+                              const AsyncConnection::Data& data) const
+{
+    contents.stack.push_back(std::string(reinterpret_cast<const char*>(data.data()),
+                                         static_cast<size_t>(data.size())));
+    contents.sizes.push_back(data.size());
+}
+
+void ContentsBuilder::addKeys(Contents& contents,
+                              const AsyncConnection::Namespace& ns,
+                              const AsyncConnection::Keys& keys) const
+{
+    for (const auto& i : keys)
+        addKey(contents, ns, i);
+}
diff --git a/src/redis/hiredisclusterepolladapter.cpp b/src/redis/hiredisclusterepolladapter.cpp
new file mode 100644
index 0000000..10d3a57
--- /dev/null
+++ b/src/redis/hiredisclusterepolladapter.cpp
@@ -0,0 +1,177 @@
+/*
+   Copyright (c) 2018-2019 Nokia.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+#include "private/redis/hiredisclusterepolladapter.hpp"
+#include <sys/epoll.h>
+#include "private/engine.hpp"
+#include "private/redis/hiredisclustersystem.hpp"
+
+using namespace shareddatalayer;
+using namespace shareddatalayer::redis;
+
+namespace
+{
+    int attachFunction(redisAsyncContext* ac, void* data)
+    {
+        auto instance(static_cast<HiredisClusterEpollAdapter*>(data));
+        instance->attach(ac);
+        return REDIS_OK;
+    }
+
+    void addReadWrap(void* data)
+    {
+        auto instance(static_cast<HiredisClusterEpollAdapter::Node*>(data));
+        instance->addRead();
+    }
+
+    void addWriteWrap(void* data)
+    {
+        auto instance(static_cast<HiredisClusterEpollAdapter::Node*>(data));
+        instance->addWrite();
+    }
+
+    void delReadWrap(void* data)
+    {
+        auto instance(static_cast<HiredisClusterEpollAdapter::Node*>(data));
+        instance->delRead();
+    }
+
+    void delWriteWrap(void* data)
+    {
+        auto instance(static_cast<HiredisClusterEpollAdapter::Node*>(data));
+        instance->delWrite();
+    }
+
+    void cleanupWrap(void* data)
+    {
+        auto instance(static_cast<HiredisClusterEpollAdapter::Node*>(data));
+        instance->cleanup();
+    }
+}
+
+HiredisClusterEpollAdapter::HiredisClusterEpollAdapter(Engine& engine):
+    HiredisClusterEpollAdapter(engine, HiredisClusterSystem::getInstance())
+{
+}
+
+HiredisClusterEpollAdapter::HiredisClusterEpollAdapter(Engine& engine, HiredisClusterSystem& hiredisClusterSystem):
+    engine(engine),
+    hiredisClusterSystem(hiredisClusterSystem)
+{
+}
+
+void HiredisClusterEpollAdapter::setup(redisClusterAsyncContext* acc)
+{
+    acc->adapter = this;
+    acc->attach_fn = attachFunction;
+}
+
+void HiredisClusterEpollAdapter::attach(redisAsyncContext* ac)
+{
+    detach(ac);
+    nodes.insert(std::make_pair(ac->c.fd,
+                                std::unique_ptr<Node>(new Node(engine,
+                                                               ac,
+                                                               hiredisClusterSystem))));
+}
+
+void HiredisClusterEpollAdapter::detach(const redisAsyncContext* ac)
+{
+    auto it = nodes.find(ac->c.fd);
+    if (it != nodes.end())
+        nodes.erase(it);
+}
+
+HiredisClusterEpollAdapter::Node::Node(Engine& engine,
+                                       redisAsyncContext* ac,
+                                       HiredisClusterSystem& hiredisClusterSystem):
+    engine(engine),
+    hiredisClusterSystem(hiredisClusterSystem),
+    ac(ac),
+    eventState(0),
+    reading(false),
+    writing(false)
+{
+    this->ac->ev.data = this;
+    this->ac->ev.addRead = addReadWrap;
+    this->ac->ev.addWrite = addWriteWrap;
+    this->ac->ev.delRead = delReadWrap;
+    this->ac->ev.delWrite = delWriteWrap;
+    this->ac->ev.cleanup = cleanupWrap;
+    engine.addMonitoredFD(ac->c.fd,
+                          eventState,
+                          std::bind(&HiredisClusterEpollAdapter::Node::eventHandler,
+                                    this,
+                                    std::placeholders::_1));
+    isMonitoring = true;
+}
+
+HiredisClusterEpollAdapter::Node::~Node()
+{
+    if (isMonitoring)
+        cleanup();
+}
+
+void HiredisClusterEpollAdapter::Node::eventHandler(unsigned int events)
+{
+    if (events & Engine::EVENT_IN)
+        if (reading && isMonitoring)
+            hiredisClusterSystem.redisAsyncHandleRead(ac);
+    if (events & Engine::EVENT_OUT)
+        if (writing && isMonitoring)
+            hiredisClusterSystem.redisAsyncHandleWrite(ac);
+}
+
+void HiredisClusterEpollAdapter::Node::addRead()
+{
+    if (reading)
+        return;
+    reading = true;
+    eventState |= Engine::EVENT_IN;
+    engine.modifyMonitoredFD(ac->c.fd, eventState);
+}
+
+void HiredisClusterEpollAdapter::Node::addWrite()
+{
+    if (writing)
+        return;
+    writing = true;
+    eventState |= Engine::EVENT_OUT;
+    engine.modifyMonitoredFD(ac->c.fd, eventState);
+}
+
+void HiredisClusterEpollAdapter::Node::delRead()
+{
+    reading = false;
+    eventState &= ~Engine::EVENT_IN;
+    engine.modifyMonitoredFD(ac->c.fd, eventState);
+}
+
+void HiredisClusterEpollAdapter::Node::delWrite()
+{
+    writing = false;
+    eventState &= ~Engine::EVENT_OUT;
+    engine.modifyMonitoredFD(ac->c.fd, eventState);
+}
+
+void HiredisClusterEpollAdapter::Node::cleanup()
+{
+    reading = false;
+    writing = false;
+    eventState = 0;
+    engine.deleteMonitoredFD(ac->c.fd);
+    isMonitoring = false;
+}
diff --git a/src/redis/hiredisclustersystem.cpp b/src/redis/hiredisclustersystem.cpp
new file mode 100644
index 0000000..7b3b25f
--- /dev/null
+++ b/src/redis/hiredisclustersystem.cpp
@@ -0,0 +1,76 @@
+/*
+   Copyright (c) 2018-2019 Nokia.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+#include "private/redis/hiredisclustersystem.hpp"
+
+using namespace shareddatalayer::redis;
+
+redisClusterAsyncContext* HiredisClusterSystem::redisClusterAsyncConnect(const char* addrs, int flags)
+{
+    return ::redisClusterAsyncConnect(addrs, flags);
+}
+
+int HiredisClusterSystem::redisClusterAsyncSetConnectCallback(redisClusterAsyncContext* acc,
+                                                              redisClusterInstanceConnectCallback* fn)
+{
+    return ::redisClusterAsyncSetConnectCallback(acc, fn);
+}
+
+int HiredisClusterSystem::redisClusterAsyncSetDisconnectCallback(redisClusterAsyncContext* acc,
+                                                                 redisClusterInstanceDisconnectCallback* fn)
+{
+    return ::redisClusterAsyncSetDisconnectCallback(acc, fn);
+}
+
+int HiredisClusterSystem::redisClusterAsyncCommandArgv(redisClusterAsyncContext* acc, redisClusterCallbackFn* fn,
+                                                       void* privdata, int argc, const char** argv,
+                                                       const size_t* argvlen)
+{
+    return ::redisClusterAsyncCommandArgv(acc, fn, privdata, argc, argv, argvlen);
+}
+
+int HiredisClusterSystem::redisClusterAsyncCommandArgvWithKey(redisClusterAsyncContext *acc, redisClusterCallbackFn *fn,
+                                                              void *privdata, const char *key, int keylen, int argc,
+                                                              const char **argv, const size_t *argvlen)
+{
+    return ::redisClusterAsyncCommandArgvWithKey(acc, fn, privdata, key, keylen, argc, argv, argvlen);
+}
+
+void HiredisClusterSystem::redisAsyncHandleRead(redisAsyncContext* ac)
+{
+    ::redisAsyncHandleRead(ac);
+}
+
+void HiredisClusterSystem::redisAsyncHandleWrite(redisAsyncContext* ac)
+{
+    ::redisAsyncHandleWrite(ac);
+}
+
+void HiredisClusterSystem::redisClusterAsyncDisconnect(redisClusterAsyncContext* acc)
+{
+    ::redisClusterAsyncDisconnect(acc);
+}
+
+void HiredisClusterSystem::redisClusterAsyncFree(redisClusterAsyncContext* acc)
+{
+    ::redisClusterAsyncFree(acc);
+}
+
+HiredisClusterSystem& HiredisClusterSystem::getInstance()
+{
+    static HiredisClusterSystem instance;
+    return instance;
+}
diff --git a/src/redis/hiredisepolladapter.cpp b/src/redis/hiredisepolladapter.cpp
new file mode 100644
index 0000000..11c2252
--- /dev/null
+++ b/src/redis/hiredisepolladapter.cpp
@@ -0,0 +1,150 @@
+/*
+   Copyright (c) 2018-2019 Nokia.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+#include "private/redis/hiredisepolladapter.hpp"
+#include <sys/epoll.h>
+#include "private/engine.hpp"
+#include "private/redis/hiredissystem.hpp"
+
+using namespace shareddatalayer;
+using namespace shareddatalayer::redis;
+
+
+namespace
+{
+    void addReadWrap(void* data)
+    {
+        auto instance(static_cast<HiredisEpollAdapter*>(data));
+        instance->addRead();
+    }
+
+    void delReadWrap(void* data)
+    {
+        auto instance(static_cast<HiredisEpollAdapter*>(data));
+        instance->delRead();
+    }
+
+    void addWriteWrap(void* data)
+    {
+        auto instance(static_cast<HiredisEpollAdapter*>(data));
+        instance->addWrite();
+    }
+
+    void delWriteWrap(void* data)
+    {
+        auto instance(static_cast<HiredisEpollAdapter*>(data));
+        instance->delWrite();
+    }
+
+    void cleanUpWrap(void* data)
+    {
+        auto instance(static_cast<HiredisEpollAdapter*>(data));
+        instance->cleanUp();
+    }
+}
+
+HiredisEpollAdapter::HiredisEpollAdapter(Engine& engine):
+    HiredisEpollAdapter(engine, HiredisSystem::getHiredisSystem())
+{
+}
+
+HiredisEpollAdapter::HiredisEpollAdapter(Engine& engine, HiredisSystem& hiredisSystem):
+    engine(engine),
+    hiredisSystem(hiredisSystem),
+    ac(nullptr),
+    eventState(0),
+    reading(false),
+    writing(false),
+    isMonitoring(false)
+{
+}
+
+HiredisEpollAdapter::~HiredisEpollAdapter()
+{
+    if (ac && isMonitoring)
+        cleanUp();
+}
+
+void HiredisEpollAdapter::attach(redisAsyncContext* ac)
+{
+    eventState = 0;
+    reading = false;
+    writing = false;
+    this->ac = ac;
+    this->ac->ev.data = this;
+    this->ac->ev.addRead = addReadWrap;
+    this->ac->ev.delRead = delReadWrap;
+    this->ac->ev.addWrite = addWriteWrap;
+    this->ac->ev.delWrite = delWriteWrap;
+    this->ac->ev.cleanup = cleanUpWrap;
+    engine.addMonitoredFD(ac->c.fd,
+                          eventState,
+                          std::bind(&HiredisEpollAdapter::eventHandler,
+                                    this,
+                                    std::placeholders::_1));
+    isMonitoring = true;
+}
+
+void HiredisEpollAdapter::eventHandler(unsigned int events)
+{
+    if (events & Engine::EVENT_IN)
+        if (reading)
+            hiredisSystem.redisAsyncHandleRead(ac);
+    if (events & Engine::EVENT_OUT)
+        if (writing)
+            hiredisSystem.redisAsyncHandleWrite(ac);
+}
+
+void HiredisEpollAdapter::addRead()
+{
+    if (reading)
+        return;
+    reading = true;
+    eventState |= Engine::EVENT_IN;
+    engine.modifyMonitoredFD(ac->c.fd, eventState);
+}
+
+void HiredisEpollAdapter::delRead()
+{
+    reading = false;
+    eventState &= ~Engine::EVENT_IN;
+    engine.modifyMonitoredFD(ac->c.fd, eventState);
+}
+
+void HiredisEpollAdapter::addWrite()
+{
+    if (writing)
+        return;
+    writing = true;
+    eventState |= Engine::EVENT_OUT;
+    engine.modifyMonitoredFD(ac->c.fd, eventState);
+}
+
+void HiredisEpollAdapter::delWrite()
+{
+    writing = false;
+    eventState &= ~Engine::EVENT_OUT;
+    engine.modifyMonitoredFD(ac->c.fd, eventState);
+}
+
+void HiredisEpollAdapter::cleanUp()
+{
+    reading = false;
+    writing = false;
+    eventState = 0;
+    engine.deleteMonitoredFD(ac->c.fd);
+    isMonitoring = false;
+}
diff --git a/src/redis/hiredissystem.cpp b/src/redis/hiredissystem.cpp
new file mode 100644
index 0000000..2d37920
--- /dev/null
+++ b/src/redis/hiredissystem.cpp
@@ -0,0 +1,90 @@
+/*
+   Copyright (c) 2018-2019 Nokia.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+#include "private/redis/hiredissystem.hpp"
+
+using namespace shareddatalayer::redis;
+
+redisContext* HiredisSystem::redisConnect(const char* ip, int port)
+{
+    return ::redisConnect(ip, port);
+}
+
+void* HiredisSystem::redisCommandArgv(redisContext* context, int argc, const char** argv, const size_t* argvlen)
+{
+    return ::redisCommandArgv(context, argc, argv, argvlen);
+}
+
+void HiredisSystem::freeReplyObject(void* reply)
+{
+    ::freeReplyObject(reply);
+}
+
+void HiredisSystem::redisFree(redisContext* context)
+{
+    ::redisFree(context);
+}
+
+redisAsyncContext* HiredisSystem::redisAsyncConnect(const char* ip, int port)
+{
+    return ::redisAsyncConnect(ip, port);
+}
+
+int HiredisSystem::redisAsyncSetConnectCallback(redisAsyncContext* ac, redisConnectCallback* fn)
+{
+    return ::redisAsyncSetConnectCallback(ac, fn);
+}
+
+int HiredisSystem::redisAsyncSetDisconnectCallback(redisAsyncContext* ac, redisDisconnectCallback* fn)
+{
+    return ::redisAsyncSetDisconnectCallback(ac, fn);
+}
+
+int HiredisSystem::redisAsyncCommandArgv(redisAsyncContext* ac,
+                                         redisCallbackFn* fn,
+                                         void* privdata,
+                                         int argc,
+                                         const char** argv,
+                                         const size_t* argvlen)
+{
+    return ::redisAsyncCommandArgv(ac, fn, privdata, argc, argv, argvlen);
+}
+
+void HiredisSystem::redisAsyncHandleRead(redisAsyncContext* ac)
+{
+    ::redisAsyncHandleRead(ac);
+}
+
+void HiredisSystem::redisAsyncHandleWrite(redisAsyncContext* ac)
+{
+    ::redisAsyncHandleWrite(ac);
+}
+
+void HiredisSystem::redisAsyncDisconnect(redisAsyncContext* ac)
+{
+    ::redisAsyncDisconnect(ac);
+}
+
+void HiredisSystem::redisAsyncFree(redisAsyncContext* ac)
+{
+    ::redisAsyncFree(ac);
+}
+
+HiredisSystem& HiredisSystem::getHiredisSystem() noexcept
+{
+    static HiredisSystem hiredisSystem;
+    return hiredisSystem;
+}
diff --git a/src/redis/redisgeneral.cpp b/src/redis/redisgeneral.cpp
new file mode 100644
index 0000000..eb837ae
--- /dev/null
+++ b/src/redis/redisgeneral.cpp
@@ -0,0 +1,194 @@
+/*
+   Copyright (c) 2018-2019 Nokia.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+#include "config.h"
+#include "private/createlogger.hpp"
+#include "private/error.hpp"
+#include "private/redis/redisgeneral.hpp"
+#include <arpa/inet.h>
+#include <cstring>
+#if HAVE_HIREDIS_VIP
+#include <hircluster.h>
+#endif
+#include <hiredis/hiredis.h>
+#include <sstream>
+
+using namespace shareddatalayer;
+using namespace shareddatalayer::redis;
+
+namespace
+{
+    bool equals(const std::string& s1, const char* s2, size_t s2Len)
+    {
+        if (s2 == nullptr)
+        {
+            logErrorOnce("redisGeneral: null pointer passed to equals function");
+            return false;
+        }
+
+        return ((s1.size() == s2Len) && (std::memcmp(s1.data(), s2, s2Len) == 0));
+    }
+
+    bool startsWith(const std::string& s1, const char* s2, size_t s2Len)
+    {
+        if (s2 == nullptr)
+        {
+            logErrorOnce("redisGeneral: null pointer passed to startsWith function");
+            return false;
+        }
+
+        return ((s1.size() <= s2Len) && (std::memcmp(s1.data(), s2, s1.size()) == 0));
+    }
+
+    AsyncRedisCommandDispatcherErrorCode mapRedisReplyErrorToSdlError(const redisReply* rr)
+    {
+        if (equals("LOADING Redis is loading the dataset in memory", rr->str, static_cast<size_t>(rr->len)))
+            return AsyncRedisCommandDispatcherErrorCode::DATASET_LOADING;
+
+        /* This error reply comes when some cluster node(s) is down and rest of the cluster
+         * nodes cannot operate due to that. This error reply typically comes from nodes
+         * which are working but cannot handle requests because other node(s) are down.
+         * Nodes which are actually down (under failover handling) typically return
+         * CLUSTER_ERROR_NOT_CONNECTED or CLUSTER_ERROR_CONNECTION_LOST.
+         */
+        if (startsWith("CLUSTERDOWN", rr->str, static_cast<size_t>(rr->len)))
+            return AsyncRedisCommandDispatcherErrorCode::NOT_CONNECTED;
+
+        if (startsWith("ERR Protocol error", rr->str, static_cast<size_t>(rr->len)))
+            return AsyncRedisCommandDispatcherErrorCode::PROTOCOL_ERROR;
+
+        std::ostringstream oss;
+        oss << "redis reply error: " << std::string(rr->str, static_cast<size_t>(rr->len));
+        logErrorOnce(oss.str());
+        return AsyncRedisCommandDispatcherErrorCode::UNKNOWN_ERROR;
+    }
+
+    AsyncRedisCommandDispatcherErrorCode mapRedisContextErrorToSdlError(int redisContextErr, const char* redisContextErrstr)
+    {
+        switch (redisContextErr)
+        {
+            /* From hiredis/read.h:
+             * When an error occurs, the err flag in a context is set to hold the type of
+             * error that occurred. REDIS_ERR_IO means there was an I/O error and you
+             * should use the "errno" variable to find out what is wrong.
+             * For other values, the "errstr" field will hold a description. */
+            case REDIS_ERR_IO:
+                if (errno == ECONNRESET)
+                    return AsyncRedisCommandDispatcherErrorCode::CONNECTION_LOST;
+                logErrorOnce("redis io error. Errno: " + std::to_string(errno));
+                return AsyncRedisCommandDispatcherErrorCode::IO_ERROR;
+            case REDIS_ERR_EOF:
+                return AsyncRedisCommandDispatcherErrorCode::CONNECTION_LOST;
+            case REDIS_ERR_PROTOCOL:
+                return AsyncRedisCommandDispatcherErrorCode::PROTOCOL_ERROR;
+            case REDIS_ERR_OOM:
+                return AsyncRedisCommandDispatcherErrorCode::OUT_OF_MEMORY;
+#if HAVE_HIREDIS_VIP
+            /* hiredis_vip returns CLUSTER_ERROR_NOT_CONNECTED when cluster node is disconnected
+             * but failover handling has not started yet (node_timeout not elapsed yet). In
+             * this situation hiredis_vip does not send request to redis (as it is clear that
+             * request cannot succeed), therefore we can map this error to NOT_CONNECTED error
+             * as it best descripes this situation.
+             */
+            case CLUSTER_ERROR_NOT_CONNECTED:
+                return AsyncRedisCommandDispatcherErrorCode::NOT_CONNECTED;
+             /* hiredis_vip returns CLUSTER_ERROR_CONNECTION_LOST when connection is lost while
+              * hiredis is waiting for reply from redis.
+              */
+            case CLUSTER_ERROR_CONNECTION_LOST:
+                return AsyncRedisCommandDispatcherErrorCode::CONNECTION_LOST;
+#endif
+            default:
+                std::ostringstream oss;
+                oss << "redis error: "
+                    << redisContextErrstr
+                    << " (" << redisContextErr << ")";
+                logErrorOnce(oss.str());
+                return AsyncRedisCommandDispatcherErrorCode::UNKNOWN_ERROR;
+        }
+    }
+}
+
+namespace shareddatalayer
+{
+    namespace redis
+    {
+        std::string formatToClusterSyntax(const DatabaseConfiguration::Addresses& addresses)
+        {
+            std::ostringstream oss;
+            for (auto i(addresses.begin()); i != addresses.end(); ++i)
+            {
+                oss << i->getHost() << ':' << ntohs(i->getPort());
+                if (i == --addresses.end())
+                    break;
+                else
+                    oss << ',';
+            }
+            return oss.str();
+        }
+
+        const std::set<std::string>& getRequiredRedisModuleCommands()
+        {
+            static const std::set<std::string> requiredRedisModuleCommands({"msetpub","setie","setiepub","setnxpub","delpub","delie","deliepub"});
+            return requiredRedisModuleCommands;
+        }
+
+        std::error_code getRedisError(int redisContextErr, const char* redisContextErrstr, const redisReply* rr)
+        {
+            if (rr != nullptr)
+            {
+                if (rr->type != REDIS_REPLY_ERROR)
+                    return std::error_code();
+
+                return std::error_code(mapRedisReplyErrorToSdlError(rr));
+            }
+
+            return std::error_code(mapRedisContextErrorToSdlError(redisContextErr, redisContextErrstr));
+        }
+
+        std::set<std::string> parseCommandListReply(const redis::Reply& reply)
+        {
+            std::set<std::string> availableCommands;
+            auto replyArray(reply.getArray());
+            for (const auto& j : *replyArray)
+            {
+                auto element = j->getArray();
+                auto command = element->front()->getString();
+                availableCommands.insert(command->str);
+            }
+            return availableCommands;
+        }
+
+        bool checkRedisModuleCommands(const std::set<std::string>& availableCommands)
+        {
+            std::set<std::string> missingCommands;
+
+            for (const auto& i : getRequiredRedisModuleCommands())
+            {
+                const auto it = availableCommands.find(i);
+                if (it == availableCommands.end())
+                    missingCommands.insert(i);
+            }
+            if (!missingCommands.empty())
+            {
+                logErrorOnce("Missing Redis module extension commands:");
+                for (const auto& i : missingCommands)
+                    logErrorOnce(i);
+            }
+            return missingCommands.empty();
+        }
+    }
+}
diff --git a/src/rejectedbybackend.cpp b/src/rejectedbybackend.cpp
new file mode 100644
index 0000000..8529086
--- /dev/null
+++ b/src/rejectedbybackend.cpp
@@ -0,0 +1,24 @@
+/*
+   Copyright (c) 2018-2019 Nokia.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+#include <sdl/rejectedbybackend.hpp>
+
+using namespace shareddatalayer;
+
+RejectedByBackend::RejectedByBackend(const std::string& error):
+    Exception(error)
+{
+}
diff --git a/src/rejectedbysdl.cpp b/src/rejectedbysdl.cpp
new file mode 100644
index 0000000..09a864c
--- /dev/null
+++ b/src/rejectedbysdl.cpp
@@ -0,0 +1,24 @@
+/*
+   Copyright (c) 2018-2019 Nokia.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+#include <sdl/rejectedbysdl.hpp>
+
+using namespace shareddatalayer;
+
+RejectedBySdl::RejectedBySdl(const std::string& error):
+    Exception(error)
+{
+}
diff --git a/src/syncstorage.cpp b/src/syncstorage.cpp
new file mode 100644
index 0000000..a1d7e54
--- /dev/null
+++ b/src/syncstorage.cpp
@@ -0,0 +1,26 @@
+/*
+   Copyright (c) 2018-2019 Nokia.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+#include "private/syncstorageimpl.hpp"
+#include <sdl/asyncstorage.hpp>
+#include <sdl/syncstorage.hpp>
+
+using namespace shareddatalayer;
+
+std::unique_ptr<SyncStorage> SyncStorage::create()
+{
+    return std::unique_ptr<SyncStorageImpl>(new SyncStorageImpl(AsyncStorage::create()));
+}
diff --git a/src/syncstorageimpl.cpp b/src/syncstorageimpl.cpp
new file mode 100644
index 0000000..b73029c
--- /dev/null
+++ b/src/syncstorageimpl.cpp
@@ -0,0 +1,238 @@
+/*
+   Copyright (c) 2018-2019 Nokia.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+#include <sstream>
+#include <sys/poll.h>
+#include <sdl/asyncstorage.hpp>
+#include <sdl/backenderror.hpp>
+#include <sdl/errorqueries.hpp>
+#include <sdl/invalidnamespace.hpp>
+#include <sdl/notconnected.hpp>
+#include <sdl/operationinterrupted.hpp>
+#include <sdl/rejectedbybackend.hpp>
+#include <sdl/rejectedbysdl.hpp>
+#include "private/redis/asyncredisstorage.hpp"
+#include "private/syncstorageimpl.hpp"
+#include "private/system.hpp"
+
+using namespace shareddatalayer;
+
+namespace
+{
+    void throwExceptionForErrorCode[[ noreturn ]](const std::error_code& ec)
+    {
+        if (ec == shareddatalayer::Error::BACKEND_FAILURE)
+            throw BackendError(ec.message());
+        else if (ec == shareddatalayer::Error::NOT_CONNECTED)
+            throw NotConnected(ec.message());
+        else if (ec == shareddatalayer::Error::OPERATION_INTERRUPTED)
+            throw OperationInterrupted(ec.message());
+        else if (ec == shareddatalayer::Error::REJECTED_BY_BACKEND)
+            throw RejectedByBackend(ec.message());
+        else if (ec == AsyncRedisStorage::ErrorCode::INVALID_NAMESPACE)
+            throw InvalidNamespace(ec.message());
+        else if (ec == shareddatalayer::Error::REJECTED_BY_SDL)
+            throw RejectedBySdl(ec.message());
+
+        std::ostringstream os;
+        os << "No corresponding SDL exception found for error code: " << ec.category().name() << " " << ec.value();
+        throw std::range_error(os.str());
+    }
+}
+
+SyncStorageImpl::SyncStorageImpl(std::unique_ptr<AsyncStorage> asyncStorage):
+    SyncStorageImpl(std::move(asyncStorage), System::getSystem())
+{
+}
+
+SyncStorageImpl::SyncStorageImpl(std::unique_ptr<AsyncStorage> pAsyncStorage,
+                                 System& system):
+    asyncStorage(std::move(pAsyncStorage)),
+    system(system),
+    pFd(asyncStorage->fd()),
+    localStatus(false),
+    synced(false)
+{
+}
+
+void SyncStorageImpl::modifyAck(const std::error_code& error)
+{
+    synced = true;
+    localError = error;
+}
+
+void SyncStorageImpl::modifyIfAck(const std::error_code& error, bool status)
+{
+    synced = true;
+    localError = error;
+    localStatus = status;
+}
+
+void SyncStorageImpl::getAck(const std::error_code& error, const DataMap& dataMap)
+{
+    synced = true;
+    localError = error;
+    localMap = dataMap;
+}
+
+void SyncStorageImpl::findKeysAck(const std::error_code& error, const Keys& keys)
+{
+    synced = true;
+    localError = error;
+    localKeys = keys;
+}
+
+void SyncStorageImpl::verifyBackendResponse()
+{
+    if(localError)
+        throwExceptionForErrorCode(localError);
+}
+
+void SyncStorageImpl::waitForCallback()
+{
+    struct pollfd events { pFd, POLLIN, 0 };
+    while(!synced)
+        if (system.poll(&events, 1, -1) > 0 && (events.revents & POLLIN))
+            asyncStorage->handleEvents();
+}
+
+void SyncStorageImpl::waitSdlToBeReady(const Namespace& ns)
+{
+    synced = false;
+    asyncStorage->waitReadyAsync(ns,
+                                 std::bind(&shareddatalayer::SyncStorageImpl::modifyAck,
+                                           this,
+                                           std::error_code()));
+    waitForCallback();
+    verifyBackendResponse();
+}
+
+void SyncStorageImpl::set(const Namespace& ns, const DataMap& dataMap)
+{
+    waitSdlToBeReady(ns);
+    synced = false;
+    asyncStorage->setAsync(ns,
+                           dataMap,
+                           std::bind(&shareddatalayer::SyncStorageImpl::modifyAck,
+                                     this,
+                                     std::placeholders::_1));
+    waitForCallback();
+    verifyBackendResponse();
+}
+
+bool SyncStorageImpl::setIf(const Namespace& ns, const Key& key, const Data& oldData, const Data& newData)
+{
+    waitSdlToBeReady(ns);
+    synced = false;
+    asyncStorage->setIfAsync(ns,
+                             key,
+                             oldData,
+                             newData,
+                             std::bind(&shareddatalayer::SyncStorageImpl::modifyIfAck,
+                                       this,
+                                       std::placeholders::_1,
+                                       std::placeholders::_2));
+    waitForCallback();
+    verifyBackendResponse();
+    return localStatus;
+}
+
+bool SyncStorageImpl::setIfNotExists(const Namespace& ns, const Key& key, const Data& data)
+{
+    waitSdlToBeReady(ns);
+    synced = false;
+    asyncStorage->setIfNotExistsAsync(ns,
+                                      key,
+                                      data,
+                                      std::bind(&shareddatalayer::SyncStorageImpl::modifyIfAck,
+                                                this,
+                                                std::placeholders::_1,
+                                                std::placeholders::_2));
+    waitForCallback();
+    verifyBackendResponse();
+    return localStatus;
+}
+
+SyncStorageImpl::DataMap SyncStorageImpl::get(const Namespace& ns, const Keys& keys)
+{
+    waitSdlToBeReady(ns);
+    synced = false;
+    asyncStorage->getAsync(ns,
+                           keys,
+                           std::bind(&shareddatalayer::SyncStorageImpl::getAck,
+                                     this,
+                                     std::placeholders::_1,
+                                     std::placeholders::_2));
+    waitForCallback();
+    verifyBackendResponse();
+    return localMap;
+}
+
+void SyncStorageImpl::remove(const Namespace& ns, const Keys& keys)
+{
+    waitSdlToBeReady(ns);
+    synced = false;
+    asyncStorage->removeAsync(ns,
+                              keys,
+                              std::bind(&shareddatalayer::SyncStorageImpl::modifyAck,
+                                        this,
+                                        std::placeholders::_1));
+    waitForCallback();
+    verifyBackendResponse();
+}
+
+bool SyncStorageImpl::removeIf(const Namespace& ns, const Key& key, const Data& data)
+{
+    waitSdlToBeReady(ns);
+    synced = false;
+    asyncStorage->removeIfAsync(ns,
+                                key,
+                                data,
+                                std::bind(&shareddatalayer::SyncStorageImpl::modifyIfAck,
+                                          this,
+                                          std::placeholders::_1,
+                                          std::placeholders::_2));
+    waitForCallback();
+    verifyBackendResponse();
+    return localStatus;
+}
+
+SyncStorageImpl::Keys SyncStorageImpl::findKeys(const Namespace& ns, const std::string& keyPrefix)
+{
+    waitSdlToBeReady(ns);
+    synced = false;
+    asyncStorage->findKeysAsync(ns,
+                                keyPrefix,
+                                std::bind(&shareddatalayer::SyncStorageImpl::findKeysAck,
+                                          this,
+                                          std::placeholders::_1,
+                                          std::placeholders::_2));
+    waitForCallback();
+    verifyBackendResponse();
+    return localKeys;
+}
+
+void SyncStorageImpl::removeAll(const Namespace& ns)
+{
+    waitSdlToBeReady(ns);
+    synced = false;
+    asyncStorage->removeAllAsync(ns,
+                                 std::bind(&shareddatalayer::SyncStorageImpl::modifyAck,
+                                           this,
+                                           std::placeholders::_1));
+    waitForCallback();
+    verifyBackendResponse();
+}
diff --git a/src/system.cpp b/src/system.cpp
new file mode 100644
index 0000000..e0852e9
--- /dev/null
+++ b/src/system.cpp
@@ -0,0 +1,129 @@
+/*
+   Copyright (c) 2018-2019 Nokia.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+#include "private/system.hpp"
+#include <system_error>
+#include <cerrno>
+#include <cstring>
+#include <sstream>
+#include <sys/epoll.h>
+#include <sys/timerfd.h>
+#include <sys/eventfd.h>
+#include "private/abort.hpp"
+#include "private/createlogger.hpp"
+
+using namespace shareddatalayer;
+
+int System::poll(struct pollfd *fds, nfds_t nfds, int timeout)
+{
+    const int ret(::poll(fds, nfds, timeout));
+    if (ret == -1 && errno != EINTR)
+        throw std::system_error(errno, std::system_category(), "poll");
+    return ret;
+}
+
+int System::epoll_create1(int flags)
+{
+    const int ret(::epoll_create1(flags));
+    if (ret == -1)
+        throw std::system_error(errno, std::system_category(), "epoll_create1");
+    return ret;
+}
+
+void System::epoll_ctl(int epfd, int op, int fd, epoll_event* event)
+{
+    const int ret(::epoll_ctl(epfd, op, fd, event));
+    if (ret == -1)
+        throw std::system_error(errno, std::system_category(), "epoll_ctl");
+}
+
+int System::epoll_wait(int epfd, epoll_event* events, int maxevents, int timeout)
+{
+    const int ret(::epoll_wait(epfd, events, maxevents, timeout));
+    if ((ret == -1) && (errno != EINTR))
+        throw std::system_error(errno, std::system_category(), "epoll_wait");
+    return ret;
+}
+
+int System::timerfd_create(int clockid, int flags)
+{
+    const int ret(::timerfd_create(clockid, flags));
+    if (ret == -1)
+        throw std::system_error(errno, std::system_category(), "timerfd_create");
+    return ret;
+}
+
+void System::timerfd_settime(int fd, int flags, const itimerspec* new_value, itimerspec* old_value)
+{
+    const int ret(::timerfd_settime(fd, flags, new_value, old_value));
+    if (ret == -1)
+        throw std::system_error(errno, std::system_category(), "timerfd_settime");
+}
+
+ssize_t System::read(int fd, void* buf, size_t count)
+{
+    const ssize_t ret(::read(fd, buf, count));
+    if ((ret == -1) && (errno != EINTR) && (errno != EAGAIN))
+        throw std::system_error(errno, std::system_category(), "read");
+    return ret;
+}
+
+int System::eventfd(unsigned int initval, int flags)
+{
+    const int ret(::eventfd(initval, flags));
+    if (ret == -1)
+        throw std::system_error(errno, std::system_category(), "eventfd");
+    return ret;
+}
+
+ssize_t System::write(int fd, const void* buf, size_t count)
+{
+    ssize_t ret;
+    do
+        ret = ::write(fd, buf, count);
+    while ((ret == -1) && (errno == EINTR));
+    if (ret == -1)
+        throw std::system_error(errno, std::system_category(), "write");
+    return ret;
+}
+
+std::chrono::steady_clock::duration System::time_since_epoch()
+{
+    return std::chrono::steady_clock::now().time_since_epoch();
+}
+
+void System::close(int fd)
+{
+    if (::close(fd) == -1)
+    {
+        int errno_saved = errno;
+        std::ostringstream msg;
+        msg << "close(" << fd << ") failed: " << strerror(errno_saved);
+        logErrorOnce(msg.str());
+        SHAREDDATALAYER_ABORT("close failed");
+    }
+}
+
+const char* System::getenv(const char* name)
+{
+    return ::getenv(name);
+}
+
+System& System::getSystem() noexcept
+{
+    static System system;
+    return system;
+}
diff --git a/src/systemlogger.cpp b/src/systemlogger.cpp
new file mode 100644
index 0000000..8b8336b
--- /dev/null
+++ b/src/systemlogger.cpp
@@ -0,0 +1,114 @@
+/*
+   Copyright (c) 2018-2019 Nokia.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+#include "private/systemlogger.hpp"
+#include <ostream>
+#include <sstream>
+#include <syslog.h>
+#include <boost/iostreams/stream.hpp>
+#include <boost/iostreams/concepts.hpp>
+
+using namespace shareddatalayer;
+
+namespace
+{
+    class Sink: public boost::iostreams::sink
+    {
+    public:
+        Sink(const std::string& prefix, int level): prefix(prefix), level(level) { }
+
+        ~Sink() { }
+
+        std::streamsize write(const char* s, std::streamsize n);
+
+    private:
+        const std::string prefix;
+        const int level;
+    };
+}
+
+std::streamsize Sink::write(const char* s, std::streamsize n)
+{
+    std::ostringstream os;
+    os << "%s: %." << n << 's';
+    syslog(level, os.str().c_str(), prefix.c_str(), s);
+    return n;
+}
+
+SystemLogger::SystemLogger(const std::string& prefix):
+    prefix(prefix)
+{
+}
+
+SystemLogger::~SystemLogger()
+{
+}
+
+std::ostream& SystemLogger::emerg()
+{
+    if (osEmerg == nullptr)
+        osEmerg.reset(new boost::iostreams::stream<Sink>(Sink(prefix, LOG_EMERG)));
+    return *osEmerg;
+}
+
+std::ostream& SystemLogger::alert()
+{
+    if (osAlert == nullptr)
+        osAlert.reset(new boost::iostreams::stream<Sink>(Sink(prefix, LOG_ALERT)));
+    return *osAlert;
+}
+
+std::ostream& SystemLogger::crit()
+{
+    if (osCrit == nullptr)
+        osCrit.reset(new boost::iostreams::stream<Sink>(Sink(prefix, LOG_CRIT)));
+    return *osCrit;
+}
+
+std::ostream& SystemLogger::error()
+{
+    if (osError == nullptr)
+        osError.reset(new boost::iostreams::stream<Sink>(Sink(prefix, LOG_ERR)));
+    return *osError;
+}
+
+std::ostream& SystemLogger::warning()
+{
+    if (osWarning == nullptr)
+        osWarning.reset(new boost::iostreams::stream<Sink>(Sink(prefix, LOG_WARNING)));
+    return *osWarning;
+}
+
+std::ostream& SystemLogger::notice()
+{
+    if (osNotice == nullptr)
+        osNotice.reset(new boost::iostreams::stream<Sink>(Sink(prefix, LOG_NOTICE)));
+    return *osNotice;
+}
+
+std::ostream& SystemLogger::info()
+{
+    if (osInfo == nullptr)
+        osInfo.reset(new boost::iostreams::stream<Sink>(Sink(prefix, LOG_INFO)));
+    return *osInfo;
+}
+
+std::ostream& SystemLogger::debug()
+{
+    if (osDebug == nullptr)
+        osDebug.reset(new boost::iostreams::stream<Sink>(Sink(prefix, LOG_DEBUG)));
+    return *osDebug;
+}
diff --git a/src/timer.cpp b/src/timer.cpp
new file mode 100644
index 0000000..7b4d41a
--- /dev/null
+++ b/src/timer.cpp
@@ -0,0 +1,51 @@
+/*
+   Copyright (c) 2018-2019 Nokia.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+#include "private/timer.hpp"
+#include "private/engine.hpp"
+#include "private/abort.hpp"
+
+using namespace shareddatalayer;
+
+Timer::Timer(Engine& engine):
+    engine(engine),
+    armed(false)
+{
+}
+
+Timer::~Timer()
+{
+    disarm();
+}
+
+void Timer::arm(const Duration& duration, const Callback& cb)
+{
+    if (!cb)
+        SHAREDDATALAYER_ABORT("Timer::arm: a null callback");
+
+    disarm();
+    engine.armTimer(*this, duration, [this, cb] () { armed = false; cb(); });
+    armed = true;
+}
+
+void Timer::disarm()
+{
+    if (!armed)
+        return;
+
+    engine.disarmTimer(*this);
+    armed = false;
+}
diff --git a/src/timerfd.cpp b/src/timerfd.cpp
new file mode 100644
index 0000000..1356c50
--- /dev/null
+++ b/src/timerfd.cpp
@@ -0,0 +1,126 @@
+/*
+   Copyright (c) 2018-2019 Nokia.
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+*/
+
+#include "private/timerfd.hpp"
+#include "private/engine.hpp"
+#include "private/system.hpp"
+
+using namespace shareddatalayer;
+
+TimerFD::TimerFD(Engine& engine):
+    TimerFD(System::getSystem(), engine)
+{
+}
+
+TimerFD::TimerFD(System& system, Engine& engine):
+    system(system),
+    fd(system, system.timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC))
+{
+    engine.addMonitoredFD(fd, Engine::EVENT_IN, std::bind(&TimerFD::handleEvents, this));
+}
+
+TimerFD::~TimerFD()
+{
+}
+
+void TimerFD::arm(Timer& timer, const Timer::Duration& duration, const Timer::Callback& cb)
+{
+    const auto absolute(toAbsolute(duration));
+    const auto i(queue.insert(std::make_pair(absolute, std::make_pair(&timer, cb))));
+    timer.iterator = i;
+    if (isFirst(i))
+        armTimerFD(absolute);
+}
+
+bool TimerFD::isFirst(Queue::iterator it) const
+{
+    return queue.begin() == it;
+}
+
+void TimerFD::disarm(const Timer& timer)
+{
+    const bool wasFirst(isFirst(timer.iterator));
+    queue.erase(timer.iterator);
+
+    if (queue.empty())
+        disarmTimerFD();
+    else if (wasFirst)
+        armTimerFD(nextTrigger());
+}
+
+Timer::Duration TimerFD::toAbsolute(const Timer::Duration& duration)
+{
+    return std::chrono::duration_cast<Timer::Duration>(system.time_since_epoch()) + duration;
+}
+
+void TimerFD::handleEvents()
+{
+    if (timerExpired())
+        handleExpiredTimers();
+}
+
+bool TimerFD::timerExpired() const
+{
+    uint64_t count;
+    return (system.read(fd, &count, sizeof(count)) == sizeof(count)) && (count > 0U);
+}
+
+void TimerFD::handleExpiredTimers()
+{
+    const auto now(system.time_since_epoch());
+    do
+    {
+        popAndExecuteFirstTimer();
+        if (queue.empty())
+        {
+            disarmTimerFD();
+            return;
+        }
+    }
+    while (queue.begin()->first <= now);
+    armTimerFD(nextTrigger());
+}
+
+void TimerFD::popAndExecuteFirstTimer()
+{
+    const auto i(queue.begin());
+    const auto cb(i->second.second);
+    queue.erase(i);
+    cb();
+}
+
+Timer::Duration TimerFD::nextTrigger() const
+{
+    return queue.begin()->first;
+}
+
+void TimerFD::disarmTimerFD()
+{
+    setTimeForTimerFD(0, 0);
+}
+
+void TimerFD::armTimerFD(const Timer::Duration& duration)
+{
+    static const long int NANOSECONDS_IN_ONE_SECOND(1E9);
+    setTimeForTimerFD(std::chrono::duration_cast<std::chrono::seconds>(duration).count(),
+                      std::chrono::duration_cast<std::chrono::nanoseconds>(duration).count() % NANOSECONDS_IN_ONE_SECOND);
+}
+
+void TimerFD::setTimeForTimerFD(time_t seconds, long int nanoseconds)
+{
+    const itimerspec ts{ { 0, 0 }, { seconds, nanoseconds } };
+    system.timerfd_settime(fd, TFD_TIMER_ABSTIME, &ts, nullptr);
+}
diff --git a/src/tools/collectsdlinfo.in b/src/tools/collectsdlinfo.in
new file mode 100644
index 0000000..583d8b9
--- /dev/null
+++ b/src/tools/collectsdlinfo.in
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+if test "${#}" != 1 ; then
+    echo "Usage: collectsdlinfo OUTPUTDIR" 1>&2
+    exit 1
+fi
+if test "${1}" = "-h" || test "${1}" = "--help" ; then
+    cat << EOF
+Usage: collectsdlinfo OUTPUTDIR
+
+collectsdlinfo finds SDL configuration files and collects debug info. 
+The results are saved into the given OUTPUTDIR directory.
+EOF
+    exit 0
+fi
+
+OUTPUTDIR="${1}"
+mkdir -p "${OUTPUTDIR}" || exit 1
+outputfile="${OUTPUTDIR}/shareddatalayer_configuration.txt"
+sdltool dump-configuration > "${outputfile}" 2>&1
+
+outputfile="${OUTPUTDIR}/shareddatalayer_write_read_latency.txt"
+sdltool test-get-set -- timeout 10 > "${outputfile}" 2>&1
+
+outputfile="${OUTPUTDIR}/shareddatalayer_backend_connectivity.txt"
+sdltool test-connectivity -- timeout 10 > "${outputfile}" 2>&1
