You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@celix.apache.org by pn...@apache.org on 2019/01/07 20:12:00 UTC

[celix] 12/22: CELIX-438: Adds a assert and warning log for wrong useage of the use(Funcion)Service(s) calls and adds some unit tests for the C++ shell.

This is an automated email from the ASF dual-hosted git repository.

pnoltes pushed a commit to branch feature/cxx
in repository https://gitbox.apache.org/repos/asf/celix.git

commit cc671b6deb823fa06c79b1f88ac6a732eebab261
Author: Pepijn Noltes <pe...@gmail.com>
AuthorDate: Sun Jan 6 20:29:25 2019 +0100

    CELIX-438: Adds a assert and warning log for wrong useage of the use(Funcion)Service(s) calls and adds some unit tests for the C++ shell.
---
 CMakeLists.txt                                   |   2 +-
 bundles/shell/cxx_shell/CMakeLists.txt           |   6 +-
 bundles/shell/cxx_shell/gtest/CMakeLists.txt     |   7 +-
 bundles/shell/cxx_shell/gtest/src/Shell_tests.cc | 163 ++++++++++++++++++
 bundles/shell/cxx_shell/src/QueryCommand.cc      |   2 +-
 libs/CMakeLists.txt                              |   6 +-
 libs/framework_cxx/gtest/src/Framework_tests.cc  |   2 +-
 libs/framework_cxx/include/celix/BundleContext.h |  29 +++-
 libs/framework_cxx/include/celix/Framework.h     |   2 +
 libs/framework_cxx/src/Bundle.h                  |   6 +-
 libs/framework_cxx/src/BundleContext.cc          |   7 +-
 libs/framework_cxx/src/BundleController.h        |   2 +-
 libs/framework_cxx/src/Framework.cc              | 209 ++++++++++++-----------
 libs/registry/CMakeLists.txt                     |   5 +-
 libs/registry/gtest/CMakeLists.txt               |   3 +-
 libs/registry/gtest/src/Registry_tests.cc        |   2 +-
 libs/registry/gtest/src/Utils_tests.cc           |  56 ++++++
 libs/registry/include/celix/Constants.h          |   6 +-
 libs/registry/include/celix/ServiceRegistry.h    |  47 +++--
 libs/registry/include/celix/Utils.h              |  46 +++--
 libs/registry/src/ServiceRegistry.cc             |  44 +++--
 libs/registry/src/Utils.cc                       |  51 ++++++
 22 files changed, 518 insertions(+), 185 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 968e74c..f1807f7 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -56,7 +56,7 @@ option(ENABLE_TESTING "Enables unit testing" ON)
 if (ENABLE_TESTING)
 	enable_testing()
     include(cmake/celix_project/AddGTest.cmake)
-    include(cmake/celix_project/AddCppUTest.cmake)
+    #include(cmake/celix_project/AddCppUTest.cmake)
 endif ()
 include(cmake/celix_project/AddGLog.cmake)
 include(cmake/celix_project/AddLibzip.cmake)
diff --git a/bundles/shell/cxx_shell/CMakeLists.txt b/bundles/shell/cxx_shell/CMakeLists.txt
index c82d2ef..3dced30 100644
--- a/bundles/shell/cxx_shell/CMakeLists.txt
+++ b/bundles/shell/cxx_shell/CMakeLists.txt
@@ -56,6 +56,6 @@ else ()
 endif ()
 
 
-#if (ENABLE_TESTING)
-#    add_subdirectory(gtest)
-#endif ()
\ No newline at end of file
+if (ENABLE_TESTING)
+    add_subdirectory(gtest)
+endif ()
\ No newline at end of file
diff --git a/bundles/shell/cxx_shell/gtest/CMakeLists.txt b/bundles/shell/cxx_shell/gtest/CMakeLists.txt
index b4a7204..c95f364 100644
--- a/bundles/shell/cxx_shell/gtest/CMakeLists.txt
+++ b/bundles/shell/cxx_shell/gtest/CMakeLists.txt
@@ -17,9 +17,10 @@
 
 set(SOURCES
         src/main.cc
+        src/Shell_tests.cc
 )
 add_executable(celix_shell_cxx_tests ${SOURCES})
-target_link_libraries(celix_shell_cxx_tests PRIVATE gtest celix_framework_cxx celix_shell_cxx)
+target_link_libraries(celix_shell_cxx_tests PRIVATE gtest celix_framework_cxx celix_cxx_shell celix_cxx_shell_api glog::glog)
 
-add_test(NAME celix_shell_cxx_tests COMMAND celix_shell_cxx_tests)
-SETUP_TARGET_FOR_COVERAGE(celix_shell_cxx_tests_cov celix_shell_cxx_tests ${CMAKE_BINARY_DIR}/coverage/celix_shell_cxx_tests/celix_shell_cxx_tests)
\ No newline at end of file
+add_test(NAME celix_cxx_shell_tests COMMAND celix_cxx_shell_tests)
+SETUP_TARGET_FOR_COVERAGE(celix_cxx_shell_tests_cov celix_cxx_shell_tests ${CMAKE_BINARY_DIR}/coverage/celix_cxx_shell_tests/celix_cxx_shell_tests ..)
\ No newline at end of file
diff --git a/bundles/shell/cxx_shell/gtest/src/Shell_tests.cc b/bundles/shell/cxx_shell/gtest/src/Shell_tests.cc
new file mode 100644
index 0000000..b6bbd8b
--- /dev/null
+++ b/bundles/shell/cxx_shell/gtest/src/Shell_tests.cc
@@ -0,0 +1,163 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you 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 "gtest/gtest.h"
+
+#include "celix/api.h"
+#include "celix/IShellCommand.h"
+#include "celix/IShell.h"
+
+class ShellTest : public ::testing::Test {
+public:
+    ShellTest() {}
+    ~ShellTest(){}
+
+    celix::Framework& framework() { return fw; }
+private:
+    celix::Framework fw{};
+};
+
+
+
+
+TEST_F(ShellTest, AreCommandsAndShellRegistered) {
+
+    std::string filter = std::string{"("} + celix::IShellCommand::COMMAND_NAME + "=lb)";
+    long svcId = framework().context().findService<celix::IShellCommand>(filter);
+    EXPECT_TRUE(svcId > 0);
+
+    filter = std::string{"("} + celix::SHELL_COMMAND_FUNCTION_COMMAND_NAME + "=help)";
+    svcId = framework().context().findFunctionService<celix::ShellCommandFunction>(celix::SHELL_COMMAND_FUNCTION_SERVICE_FQN, filter);
+    EXPECT_TRUE(svcId > 0);
+
+    filter = std::string{"("} + celix::SHELL_COMMAND_FUNCTION_COMMAND_NAME + "=inspect)";
+    svcId = framework().context().findFunctionService<celix::ShellCommandFunction>(celix::SHELL_COMMAND_FUNCTION_SERVICE_FQN, filter);
+    EXPECT_TRUE(svcId > 0);
+
+    filter = std::string{"("} + celix::SHELL_COMMAND_FUNCTION_COMMAND_NAME + "=query)";
+    svcId = framework().context().findFunctionService<celix::ShellCommandFunction>(celix::SHELL_COMMAND_FUNCTION_SERVICE_FQN, filter);
+    EXPECT_TRUE(svcId > 0);
+
+    filter = std::string{"("} + celix::SHELL_COMMAND_FUNCTION_COMMAND_NAME + "=stop)";
+    svcId = framework().context().findFunctionService<celix::ShellCommandFunction>(celix::SHELL_COMMAND_FUNCTION_SERVICE_FQN, filter);
+    EXPECT_TRUE(svcId > 0);
+
+    filter = std::string{"("} + celix::SHELL_COMMAND_FUNCTION_COMMAND_NAME + "=start)";
+    svcId = framework().context().findFunctionService<celix::ShellCommandFunction>(celix::SHELL_COMMAND_FUNCTION_SERVICE_FQN, filter);
+    EXPECT_TRUE(svcId > 0);
+
+    filter = std::string{"("} + celix::SHELL_COMMAND_FUNCTION_COMMAND_NAME + "=version)";
+    svcId = framework().context().findFunctionService<celix::ShellCommandFunction>(celix::SHELL_COMMAND_FUNCTION_SERVICE_FQN, filter);
+    EXPECT_TRUE(svcId > 0);
+
+    svcId = framework().context().findService<celix::IShell>();
+    EXPECT_TRUE(svcId > 0);
+};
+
+TEST_F(ShellTest, LbCommandTest) {
+    std::stringstream ss{};
+    std::function<void(celix::IShellCommand&)> useLb = [&ss](celix::IShellCommand& cmd){
+        cmd.executeCommand("lb", {}, ss, ss);
+    };
+    std::string filter = std::string{"("} + celix::SHELL_COMMAND_FUNCTION_COMMAND_NAME + "=lb)";
+    bool called = framework().context().useService(useLb, filter);
+    EXPECT_TRUE(called);
+
+    ss.flush();
+    std::string output = ss.str();
+
+    size_t pos = output.find("1: Framework");
+    EXPECT_LE(pos, output.size());
+    pos = output.find("2: Shell");
+    EXPECT_LE(pos, output.size());
+
+}
+
+TEST_F(ShellTest, HelpCommandTest) {
+    std::string filter = std::string{"("} + celix::SHELL_COMMAND_FUNCTION_COMMAND_NAME + "=help)";
+    {
+        //call general help
+        std::stringstream ss{};
+        std::function<void(celix::ShellCommandFunction&)> useHelp = [&ss](celix::ShellCommandFunction& cmd){
+            cmd("help", {}, ss, ss);
+        };
+        bool called = framework().context().useFunctionService(celix::SHELL_COMMAND_FUNCTION_SERVICE_FQN, useHelp, filter);
+        EXPECT_TRUE(called);
+
+        ss.flush();
+        std::string output = ss.str();
+        size_t pos = output.find("help"); //Expect help as command
+        EXPECT_LE(pos, output.size());
+        pos = output.find("lb"); //Expect lb as command
+        EXPECT_LE(pos, output.size());
+        pos = output.find("inspect"); //Expect inspect as command
+        EXPECT_LE(pos, output.size());
+    }
+
+    {
+        //call help with arg
+        std::stringstream ss{};
+        std::vector<std::string> args{};
+        std::function<void(celix::ShellCommandFunction&)> useHelp = [&ss, &args](celix::ShellCommandFunction& cmd){
+            cmd("help", args, ss, ss);
+        };
+
+        args.emplace_back("lb");
+        bool called = framework().context().useFunctionService(celix::SHELL_COMMAND_FUNCTION_SERVICE_FQN, useHelp, filter);
+        EXPECT_TRUE(called);
+        ss.flush();
+        std::string output = ss.str();
+        size_t pos = output.find("list bundles.");
+        EXPECT_LE(pos, output.size());
+
+        args.clear();
+        args.emplace_back("unknown");
+        ss.clear();
+        called = framework().context().useFunctionService(celix::SHELL_COMMAND_FUNCTION_SERVICE_FQN, useHelp, filter);
+        EXPECT_TRUE(called);
+        ss.flush();
+        output = ss.str();
+        pos = output.find("not available");
+        EXPECT_LE(pos, output.size());
+    }
+}
+
+TEST_F(ShellTest, VersionCommandTest) {
+    //NOTE that this also test if the resources zip usage (extender pattern).
+
+    std::string filter = std::string{"("} + celix::SHELL_COMMAND_FUNCTION_COMMAND_NAME + "=version)";
+
+    //call general help
+    std::stringstream ss{};
+    std::function<void(celix::ShellCommandFunction &)> useHelp = [&ss](celix::ShellCommandFunction &cmd) {
+        cmd("version", {}, ss, ss);
+    };
+    bool called = framework().context().useFunctionService(celix::SHELL_COMMAND_FUNCTION_SERVICE_FQN, useHelp, filter);
+    EXPECT_TRUE(called);
+
+    ss.flush();
+    std::string output = ss.str();
+    size_t pos = output.find("3.0.0"); //Expect 3.0.0 as version
+    EXPECT_LE(pos, output.size());
+}
+
+
+//TODO rest of the commands
\ No newline at end of file
diff --git a/bundles/shell/cxx_shell/src/QueryCommand.cc b/bundles/shell/cxx_shell/src/QueryCommand.cc
index 225709c..67206bc 100644
--- a/bundles/shell/cxx_shell/src/QueryCommand.cc
+++ b/bundles/shell/cxx_shell/src/QueryCommand.cc
@@ -45,7 +45,7 @@ namespace {
                 svcName = cmdArgs[1];
                 filter = cmdArgs[2];
             } else {
-                lang = celix::CXX_LANG;
+                lang = celix::C_AND_CXX_LANG_REG;
                 svcName = cmdArgs[0];
                 filter = cmdArgs[1];
             }
diff --git a/libs/CMakeLists.txt b/libs/CMakeLists.txt
index 928932a..c811b70 100644
--- a/libs/CMakeLists.txt
+++ b/libs/CMakeLists.txt
@@ -17,9 +17,9 @@
 
 #utils, dfi and etcdlib are standalone
 #(e.g. no dependency on celix framework
-add_subdirectory(utils)
-add_subdirectory(dfi)
-add_subdirectory(etcdlib)
+#add_subdirectory(utils)
+#add_subdirectory(dfi)
+#add_subdirectory(etcdlib)
 
 #add_subdirectory(framework)
 
diff --git a/libs/framework_cxx/gtest/src/Framework_tests.cc b/libs/framework_cxx/gtest/src/Framework_tests.cc
index 88580f3..ab14713 100644
--- a/libs/framework_cxx/gtest/src/Framework_tests.cc
+++ b/libs/framework_cxx/gtest/src/Framework_tests.cc
@@ -40,7 +40,7 @@ TEST_F(FrameworkTest, CreateDestroy) {
     EXPECT_EQ(0, framework().listBundles(false).size());
 
     bool isFramework = false;
-    framework().useBundle(0L, [&](const celix::IBundle &bnd) {
+    framework().useBundle(celix::FRAMEWORK_BUNDLE_ID, [&](const celix::IBundle &bnd) {
        isFramework = bnd.isFrameworkBundle();
     });
     EXPECT_TRUE(isFramework);
diff --git a/libs/framework_cxx/include/celix/BundleContext.h b/libs/framework_cxx/include/celix/BundleContext.h
index 296b5c0..21a879e 100644
--- a/libs/framework_cxx/include/celix/BundleContext.h
+++ b/libs/framework_cxx/include/celix/BundleContext.h
@@ -53,7 +53,7 @@ namespace celix {
             return registry().registerFunctionService(std::move(functionName), std::forward<F>(function), std::move(props), bundle());
         }
 
-        //TODO register C services
+        //TODO reg svc fatories
 
         bool useBundle(long bndId, std::function<void(const celix::IBundle &bnd)> use) const {
             return bundle()->framework().useBundle(bndId, std::move(use));
@@ -163,7 +163,25 @@ namespace celix {
             return registry().useFunctionServices<F>(functionName, std::move(use), filter, bundle());
         }
 
-        //TODO use C services
+        template<typename I>
+        long findService(const std::string &filter = "") {
+            return registry().findService<I>(filter);
+        }
+
+        template<typename F>
+        long findFunctionService(const std::string &functionName, const std::string &filter = "") {
+            return registry().findFunctionService<F>(functionName, filter);
+        }
+
+        template<typename I>
+        std::vector<long> findServices(const std::string &filter = "") {
+            return registry().findServices<I>(filter);
+        }
+
+        template<typename F>
+        std::vector<long> findFunctionServices(const std::string &functionName, const std::string &filter = "") {
+            return registry().findFunctionServices<F>(functionName, filter);
+        }
 
         template<typename I>
         celix::ServiceTracker trackServices(celix::ServiceTrackerOptions<I> options = {}) {
@@ -175,15 +193,8 @@ namespace celix {
             return registry().trackFunctionServices<F>(functionName, std::move(options), bundle());
         }
 
-        //TODO track C Services
-
-        //TODO track trackers
-
-        //TODO track c trackers
-
 
         celix::ServiceRegistry& registry() const;
-        celix::ServiceRegistry& cRegistry() const;
     private:
 
         class Impl;
diff --git a/libs/framework_cxx/include/celix/Framework.h b/libs/framework_cxx/include/celix/Framework.h
index 89e9a3b..22d6aef 100644
--- a/libs/framework_cxx/include/celix/Framework.h
+++ b/libs/framework_cxx/include/celix/Framework.h
@@ -89,6 +89,8 @@ namespace celix {
         std::string cacheDir() const;
         std::string uuid() const;
 
+        celix::BundleContext& context() const;
+
         //TODO trackBundles
 
         //long bundleIdForName(const std::string &bndName) const;
diff --git a/libs/framework_cxx/src/Bundle.h b/libs/framework_cxx/src/Bundle.h
index ce5e456..1adb2c7 100644
--- a/libs/framework_cxx/src/Bundle.h
+++ b/libs/framework_cxx/src/Bundle.h
@@ -29,9 +29,9 @@
 namespace celix {
     class Bundle : public celix::IBundle {
     public:
-        Bundle(long _bndId, celix::Framework *_fw, celix::Properties _manifest) :
+        Bundle(long _bndId, const std::string &cacheDir, celix::Framework *_fw, celix::Properties _manifest) :
                 bndId{_bndId}, fw{_fw}, bndManifest{std::move(_manifest)},
-                bundleCache{framework().cacheDir() + "/bundle" + std::to_string(_bndId)},
+                bundleCache{cacheDir + "/bundle" + std::to_string(_bndId)},
                 bndState{BundleState::INSTALLED} {
             bndState.store(BundleState::INSTALLED, std::memory_order_release);
         }
@@ -48,7 +48,7 @@ namespace celix {
         const std::string &cacheRoot() const noexcept override;
 
         //bundle part
-        bool isFrameworkBundle() const noexcept override { return false; }
+        bool isFrameworkBundle() const noexcept override { return bndId == 1 /*note 1 is the framework bundle id*/; }
 
         void *handle() const noexcept override { return nullptr; } //TODO
 
diff --git a/libs/framework_cxx/src/BundleContext.cc b/libs/framework_cxx/src/BundleContext.cc
index 5b9b192..045f2e3 100644
--- a/libs/framework_cxx/src/BundleContext.cc
+++ b/libs/framework_cxx/src/BundleContext.cc
@@ -26,15 +26,13 @@ namespace celix {
     public:
         Impl(std::shared_ptr<celix::IBundle> _bnd) :
             bnd{std::move(_bnd)},
-            reg{&bnd->framework().registry(celix::CXX_LANG)},
-            cReg(&bnd->framework().registry(celix::C_LANG)){}
+            reg{&bnd->framework().registry(celix::C_AND_CXX_LANG_REG)} {}
 
         Impl(const Impl&) = delete;
         Impl& operator=(const Impl&) = delete;
 
         const std::shared_ptr<celix::IBundle> bnd;
         celix::ServiceRegistry * const reg; //TODO make weak_ptr
-        celix::ServiceRegistry * const cReg; //TODO make weak_ptr
 
     };
 }
@@ -52,7 +50,4 @@ celix::ServiceRegistry& celix::BundleContext::registry() const {
     return *pimpl->reg;
 }
 
-celix::ServiceRegistry& celix::BundleContext::cRegistry() const {
-    return *pimpl->cReg;
-}
 
diff --git a/libs/framework_cxx/src/BundleController.h b/libs/framework_cxx/src/BundleController.h
index 1228066..01a821c 100644
--- a/libs/framework_cxx/src/BundleController.h
+++ b/libs/framework_cxx/src/BundleController.h
@@ -247,7 +247,7 @@ namespace celix {
         const uint8_t *resourcesZip;
         const size_t resourcesZipLen;
 
-        mutable std::mutex mutex{};
+        mutable std::mutex mutex{}; //protects act and lock access to the bundle for state transitions
         std::unique_ptr<celix::IBundleActivator> act{nullptr};
     };
 }
diff --git a/libs/framework_cxx/src/Framework.cc b/libs/framework_cxx/src/Framework.cc
index 0740e5b..1b3ab87 100644
--- a/libs/framework_cxx/src/Framework.cc
+++ b/libs/framework_cxx/src/Framework.cc
@@ -62,28 +62,67 @@ static struct {
 static void registerFramework(celix::Framework *fw);
 static void unregisterFramework(celix::Framework *fw);
 
-class celix::Framework::Impl : public IBundle {
-public:
-    Impl(celix::Framework *_fw, celix::Properties _config) : fw{_fw}, config{std::move(_config)}, bndManifest{createManifest()}, cwd{cwdString()}, fwUUID{uuidString()}{
-        startFramework();
+namespace {
+    //some utils function
+
+    celix::Properties createFwManifest() {
+        celix::Properties m{};
+        m[celix::MANIFEST_BUNDLE_SYMBOLIC_NAME] = "framework";
+        m[celix::MANIFEST_BUNDLE_NAME] = "Framework";
+        m[celix::MANIFEST_BUNDLE_GROUP] = "Celix";
+        m[celix::MANIFEST_BUNDLE_VERSION] = "3.0.0";
+        return m;
+    }
+
+    std::string genUUIDString() {
+        char uuidStr[37];
+        uuid_t uuid;
+        uuid_generate(uuid);
+        uuid_unparse(uuid, uuidStr);
+        return std::string{uuidStr};
+    }
+
+    std::string createCwdString() {
+        char workdir[PATH_MAX];
+        if (getcwd(workdir, sizeof(workdir)) != NULL) {
+            return std::string{workdir};
+        } else {
+            return std::string{};
+        }
     }
 
+    std::string genFwCacheDir(const celix::Properties &/*fwConfig*/) {
+        //TODO make configeruable
+        return createCwdString() + "/.cache";
+    }
+}
+
+class celix::Framework::Impl {
+public:
+    Impl(celix::Framework *_fw, celix::Properties _config) :
+            fw{_fw},
+            config{std::move(_config)},
+            bndManifest{createFwManifest()},
+            cwd{createCwdString()},
+            fwUUID{genUUIDString()},
+            fwCacheDir{genFwCacheDir(config)} {}
+
     Impl(const Impl&) = delete;
     Impl& operator=(const Impl&) = delete;
 
-    ~Impl() {
-        stopFramework();
-        waitForShutdown();
-    }
+    ~Impl() {}
 
     std::vector<long> listBundles(bool includeFrameworkBundle) const {
         std::vector<long> result{};
-        if (includeFrameworkBundle) {
-            result.push_back(0L); //framework bundle id
-        }
         std::lock_guard<std::mutex> lock{bundles.mutex};
         for (auto &entry : bundles.entries) {
-            result.push_back(entry.first);
+            if (entry.second->bundle()->id() == FRAMEWORK_BUNDLE_ID) {
+                if (includeFrameworkBundle) {
+                    result.push_back(entry.first);
+                }
+            } else {
+                result.push_back(entry.first);
+            }
         }
         std::sort(result.begin(), result.end());//ensure that the bundles are order by bndId -> i.e. time of install
         return result;
@@ -118,7 +157,7 @@ public:
 
             std::lock_guard<std::mutex> lck{bundles.mutex};
             bndId = bundles.nextBundleId++;
-            auto bnd = std::shared_ptr<celix::Bundle>{new celix::Bundle{bndId, this->fw, std::move(manifest)}};
+            auto bnd = std::shared_ptr<celix::Bundle>{new celix::Bundle{bndId, this->cacheDir(), this->fw, std::move(manifest)}};
             auto ctx = std::shared_ptr<celix::BundleContext>{new celix::BundleContext{bnd}};
             bndController = std::shared_ptr<celix::BundleController>{new celix::BundleController{std::move(actFactory), bnd, ctx, resourcesZip, resourcesZipLen}};
             bundles.entries.emplace(std::piecewise_construct,
@@ -141,16 +180,15 @@ public:
     }
 
     bool startBundle(long bndId) {
-        if (bndId == this->fwBndId) {
-            //TODO
-            return false;
+        if (bndId == FRAMEWORK_BUNDLE_ID) {
+            return startFramework();
         } else {
             return transitionBundleTo(bndId, BundleState::ACTIVE);
         }
     }
 
     bool stopBundle(long bndId) {
-        if (bndId == this->fwBndId) {
+        if (bndId == FRAMEWORK_BUNDLE_ID) {
             return stopFramework();
         } else {
             return transitionBundleTo(bndId, BundleState::INSTALLED);
@@ -201,26 +239,20 @@ public:
 
     bool useBundle(long bndId, std::function<void(const celix::IBundle &bnd)> use) const {
         bool called = false;
-        if (bndId == 0) {
-            //framework bundle
-            use(*this);
-            called = true;
-        } else {
-            std::shared_ptr<celix::BundleController> match = nullptr;
-            {
-                std::lock_guard<std::mutex> lck{bundles.mutex};
-                auto it = bundles.entries.find(bndId);
-                if (it != bundles.entries.end()) {
-                    match = it->second;
-                    //TODO increase usage
-                }
-            }
-            if (match) {
-                use(*match->bundle());
-                called = true;
-                //TODO decrease usage -> use shared ptr instead
+        std::shared_ptr<celix::BundleController> match = nullptr;
+        {
+            std::lock_guard<std::mutex> lck{bundles.mutex};
+            auto it = bundles.entries.find(bndId);
+            if (it != bundles.entries.end()) {
+                match = it->second;
+                //TODO increase usage
             }
         }
+        if (match) {
+            use(*match->bundle());
+            called = true;
+            //TODO decrease usage -> use shared ptr instead
+        }
         return called;
     }
 
@@ -229,13 +261,16 @@ public:
         {
             std::lock_guard<std::mutex> lck{bundles.mutex};
             for (const auto &it : bundles.entries) {
-                useBundles[it.first] = it.second;
+                if (it.second->bundle()->id() == FRAMEWORK_BUNDLE_ID) {
+                    if (includeFramework) {
+                        useBundles[it.first] = it.second;
+                    }
+                } else {
+                    useBundles[it.first] = it.second;
+                }
             }
         }
 
-        if (includeFramework) {
-            use(*this);
-        }
         for (const auto &cntr : useBundles) {
             use(*cntr.second->bundle());
         }
@@ -257,51 +292,45 @@ public:
         }
     }
 
-    //resource bundle part
-    long id() const noexcept override { return 1L /*note registry empty bundle is id 0, framework is id 1*/; }
-    bool hasCacheEntry(const std::string &) const noexcept override { return false; }
-    bool isCacheEntryDir(const std::string &) const noexcept override { return false; }
-    bool isCacheEntryFile(const std::string &) const noexcept override { return false; }
-
-    //virtual bool storeResource(const std::string &path, std::ostream content) noexcept = 0;
-    //virtual std::istream open(const std::string &path) const noexcept = 0;
-    //virtual std::fstream open(const std::string &path) noexcept = 0;
-    std::string absPathForCacheEntry(const std::string &) const noexcept override { return {}; }
-    const std::string& cacheRoot() const noexcept override { //TODO
-        return cwd;
-    }
-
-    //bundle stuff
-    bool isFrameworkBundle() const noexcept override { return true; }
-    void* handle() const noexcept override { return nullptr; }
-    celix::BundleState state() const noexcept override { return BundleState::ACTIVE ; }
-    const std::string& name() const noexcept override { return bndManifest.at(celix::MANIFEST_BUNDLE_NAME); }
-    const std::string& symbolicName() const noexcept override { return bndManifest.at(celix::MANIFEST_BUNDLE_SYMBOLIC_NAME); }
-    const std::string& group() const noexcept override { return bndManifest.at(celix::MANIFEST_BUNDLE_GROUP); }
-    const std::string& version() const noexcept override { return bndManifest.at(celix::MANIFEST_BUNDLE_VERSION); }
-    const celix::Properties& manifest() const noexcept  override { return bndManifest;}
-    bool isValid() const noexcept override { return true; }
-    celix::Framework& framework() const noexcept override { return *fw; }
 
     std::string cacheDir() const {
-        return cwd + "/.cache"; //TODO make configurable
+        return fwCacheDir;
     }
 
-    std::vector<std::string> readCacheDir(const std::string &) const noexcept override { return {}; } //TODO
-
     std::string uuid() const {
         return fwUUID;
     }
 
+    celix::BundleContext& frameworkContext() const {
+        std::lock_guard<std::mutex> lck(bundles.mutex);
+        return *bundles.entries.at(celix::FRAMEWORK_BUNDLE_ID)->context();
+    }
+
     bool startFramework() {
         //TODO create cache dir using a process id (and  lock file?).
         //Maybe also move to /var/cache or /tmp and when framework stop delete all framework caches of not running processes
-        std::cout << "Celix Framework Started";
+
+        {
+            //Adding framework bundle to the bundles.
+            auto bnd = std::shared_ptr<celix::Bundle>{new celix::Bundle{FRAMEWORK_BUNDLE_ID, this->fwCacheDir, this->fw, bndManifest}};
+            bnd->setState(BundleState::ACTIVE);
+            auto ctx = std::shared_ptr<celix::BundleContext>{new celix::BundleContext{bnd}};
+            class EmptyActivator : public IBundleActivator {};
+            std::function<celix::IBundleActivator*(std::shared_ptr<celix::BundleContext>)> fac = [](std::shared_ptr<celix::BundleContext>) {
+                return new EmptyActivator{};
+            };
+            auto ctr = std::shared_ptr<celix::BundleController>{new celix::BundleController{std::move(fac), std::move(bnd), std::move(ctx), nullptr, 0}};
+            std::lock_guard<std::mutex> lck{bundles.mutex};
+            bundles.entries[FRAMEWORK_BUNDLE_ID] = std::move(ctr);
+        }
+
+        //TODO update state
+
+        std::cout << "Celix Framework Started\n";
         return true;
     }
 
     bool stopFramework() {
-        //TODO create cache dir
         std::lock_guard<std::mutex> lck{shutdown.mutex};
         if (!shutdown.shutdownStarted) {
             shutdown.future = std::async(std::launch::async, [this]{
@@ -317,7 +346,12 @@ public:
             shutdown.shutdownStarted = true;
             shutdown.cv.notify_all();
         }
-        std::cout << "Celix Framework Stopped";
+
+        //TODO update bundle state
+
+        //TODO clean cache dir
+
+        std::cout << "Celix Framework Stopped\n";
         return true;
     }
 
@@ -329,38 +363,13 @@ public:
         return true;
     }
 private:
-    celix::Properties createManifest() {
-        celix::Properties m{};
-        m[celix::MANIFEST_BUNDLE_SYMBOLIC_NAME] = "framework";
-        m[celix::MANIFEST_BUNDLE_NAME] = "Framework";
-        m[MANIFEST_BUNDLE_GROUP] = "Celix";
-        m[celix::MANIFEST_BUNDLE_VERSION] = "3.0.0";
-        return m;
-    }
 
-    std::string uuidString() {
-        char uuidStr[37];
-        uuid_t uuid;
-        uuid_generate(uuid);
-        uuid_unparse(uuid, uuidStr);
-        return std::string{uuidStr};
-    }
-
-    std::string cwdString() {
-        char workdir[PATH_MAX];
-        if (getcwd(workdir, sizeof(workdir)) != NULL) {
-            return std::string{workdir};
-        } else {
-            return std::string{};
-        }
-    }
-
-    const long fwBndId = 1L;
     celix::Framework * const fw;
     const celix::Properties config;
     const celix::Properties bndManifest;
     const std::string cwd;
     const std::string fwUUID;
+    const std::string fwCacheDir;
 
 
     struct {
@@ -374,7 +383,7 @@ private:
 
     struct {
         std::unordered_map<long, std::shared_ptr<celix::BundleController>> entries{};
-        long nextBundleId = 2;
+        long nextBundleId = FRAMEWORK_BUNDLE_ID + 1;
         mutable std::mutex mutex{};
     } bundles{};
 
@@ -389,11 +398,14 @@ private:
  **********************************************************************************************************************/
 
 celix::Framework::Framework(celix::Properties config) : pimpl{std::unique_ptr<Impl>{new Impl{this, std::move(config)}}} {
+    pimpl->startFramework();
     registerFramework(this);
 }
 
 celix::Framework::~Framework() {
     unregisterFramework(this);
+    pimpl->stopFramework();
+    pimpl->waitForShutdown();
 }
 
 celix::Framework::Framework(Framework &&rhs) = default;
@@ -435,6 +447,9 @@ std::string celix::Framework::uuid() const {
     return pimpl->uuid();
 }
 
+celix::BundleContext& celix::Framework::context() const {
+    return pimpl->frameworkContext();
+}
 
 /***********************************************************************************************************************
  * Celix 'global' functions
diff --git a/libs/registry/CMakeLists.txt b/libs/registry/CMakeLists.txt
index 5880f52..a7de533 100644
--- a/libs/registry/CMakeLists.txt
+++ b/libs/registry/CMakeLists.txt
@@ -16,10 +16,11 @@
 # under the License.
 
 add_library(celix_registry STATIC
-        src/ServiceRegistry.cc
+        src/Utils.cc
         src/Filter.cc
         src/Properties.cc
-)
+        src/ServiceRegistry.cc)
+
 target_include_directories(celix_registry PRIVATE src)
 target_include_directories(celix_registry PUBLIC include)
 target_link_libraries(celix_registry PRIVATE glog::glog)
diff --git a/libs/registry/gtest/CMakeLists.txt b/libs/registry/gtest/CMakeLists.txt
index b534c50..88a8b87 100644
--- a/libs/registry/gtest/CMakeLists.txt
+++ b/libs/registry/gtest/CMakeLists.txt
@@ -17,8 +17,9 @@
 
 set(SOURCES
         src/main.cc
-        src/Registry_tests.cc
+        src/Utils_tests.cc
         src/Filter_tests.cc
+        src/Registry_tests.cc
         src/ServiceTracking_tests.cc
         src/RegistryConcurrency_tests.cc
 )
diff --git a/libs/registry/gtest/src/Registry_tests.cc b/libs/registry/gtest/src/Registry_tests.cc
index d8fad0e..49941ea 100644
--- a/libs/registry/gtest/src/Registry_tests.cc
+++ b/libs/registry/gtest/src/Registry_tests.cc
@@ -180,7 +180,7 @@ TEST_F(RegistryTest, UseServices) {
         EXPECT_EQ(&svc, &intf1);
         long id = celix::getProperty(props, celix::SERVICE_ID, 0);
         EXPECT_EQ(svcId1, id);
-        EXPECT_EQ(0, bnd.id()); //not nullptr -> use empty bundle (bndId 0)
+        EXPECT_EQ(LONG_MAX, bnd.id()); //not nullptr -> use empty bundle (bndId 0)
     });
     EXPECT_TRUE(called);
 }
diff --git a/libs/registry/gtest/src/Utils_tests.cc b/libs/registry/gtest/src/Utils_tests.cc
new file mode 100644
index 0000000..3994109
--- /dev/null
+++ b/libs/registry/gtest/src/Utils_tests.cc
@@ -0,0 +1,56 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you 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 "gtest/gtest.h"
+
+#include "celix/Utils.h"
+
+class UtilsTest : public ::testing::Test {
+public:
+    UtilsTest() {}
+    ~UtilsTest(){}
+};
+
+class MarkerInterface;
+
+namespace example {
+    class MarkerInterface;
+}
+
+class SvcWithFqn {
+    static constexpr const char * const FQN = "SvcWithFqn[Version 1]";
+};
+
+TEST_F(UtilsTest, svcName) {
+    std::string name = celix::serviceName<MarkerInterface>();
+    EXPECT_EQ("MarkerInterface", name);
+
+    name = celix::serviceName<example::MarkerInterface>();
+    EXPECT_EQ("example::MarkerInterface", name);
+
+    name = celix::serviceName<SvcWithFqn>();
+    //TODO EXPECT_EQ("SvcWithFqn[Version 1]", name);
+
+    name = celix::functionServiceName<std::function<void()>>("do");
+    EXPECT_EQ("do[std::function<void()>]", name);
+
+
+    name = celix::functionServiceName<std::function<std::vector<std::vector<long>>(long, int, std::vector<double>)>>("collect");
+    //TODO EXPECT_EQ("collect[std::function<std::vector<std::vector<long>>(long, int, std::vector<double>)>]", name);
+}
\ No newline at end of file
diff --git a/libs/registry/include/celix/Constants.h b/libs/registry/include/celix/Constants.h
index 517a372..96f6326 100644
--- a/libs/registry/include/celix/Constants.h
+++ b/libs/registry/include/celix/Constants.h
@@ -31,14 +31,14 @@ namespace celix {
 
     static constexpr const char *const FRAMEWORK_UUID = "framework.uuid";
 
-    static constexpr const char *const CXX_LANG = "C++";
-    static constexpr const char *const C_LANG = "C";
-
+    static constexpr const char *const C_AND_CXX_LANG_REG = "C/C++";
 
     static constexpr const char *const MANIFEST_BUNDLE_SYMBOLIC_NAME = "Bundle-SymbolicName";
     static constexpr const char *const MANIFEST_BUNDLE_NAME = "Bundle-Name";
     static constexpr const char *const MANIFEST_BUNDLE_VERSION = "Bundle-Version";
     static constexpr const char *const MANIFEST_BUNDLE_GROUP = "Bundle-Group";
+
+    static constexpr long FRAMEWORK_BUNDLE_ID = 1L;
 }
 
 #endif //CXX_CELIX_CONSTANTS_H
diff --git a/libs/registry/include/celix/ServiceRegistry.h b/libs/registry/include/celix/ServiceRegistry.h
index 76b277d..c9a9a8e 100644
--- a/libs/registry/include/celix/ServiceRegistry.h
+++ b/libs/registry/include/celix/ServiceRegistry.h
@@ -145,10 +145,29 @@ namespace celix {
         }
 
         template<typename F>
-        celix::ServiceRegistration registerFunctionService(const std::string &functionName, F&& func, celix::Properties props = {}, std::shared_ptr<const celix::IResourceBundle> owner = {});
+        celix::ServiceRegistration registerFunctionService(
+                const std::string &functionName,
+                F&& func, celix::Properties props = {},
+                std::shared_ptr<const celix::IResourceBundle> owner = {});
 
         template<typename I>
-        celix::ServiceRegistration registerServiceFactory(std::shared_ptr<celix::IServiceFactory<I>> factory, celix::Properties props = {}, std::shared_ptr<const celix::IResourceBundle> owner = {});
+        celix::ServiceRegistration registerServiceFactory(
+                std::shared_ptr<celix::IServiceFactory<I>> factory,
+                celix::Properties props = {},
+                std::shared_ptr<const celix::IResourceBundle> owner = {}) {
+            auto svcName = celix::serviceName<I>();
+            return registerServiceFactory(svcName, std::move(factory), std::move(props), std::move(owner));
+        }
+
+        template<typename F>
+        celix::ServiceRegistration registerFunctionServiceFactory(
+                const std::string &functionName,
+                std::shared_ptr<celix::IServiceFactory<F>> factory,
+                celix::Properties props = {},
+                std::shared_ptr<const celix::IResourceBundle> owner = {}) {
+            auto svcName = celix::functionServiceName<F>(functionName);
+            return registerServiceFactory(svcName, std::move(factory), std::move(props), std::move(owner));
+        }
 
         template<typename I>
         //NOTE C++17 typename std::enable_if<!std::is_callable<I>::value, long>::type
@@ -160,7 +179,7 @@ namespace celix {
         template<typename I>
         //NOTE C++17 typename std::enable_if<std::is_callable<I>::value, long>::type
         long findFunctionService(const std::string &functionName, const std::string &filter = "") const {
-            auto services = findFunctionService<I>(functionName, filter);
+            auto services = findFunctionServices<I>(functionName, filter);
             return services.size() > 0 ? services[0] : -1L;
         }
 
@@ -190,8 +209,6 @@ namespace celix {
             return trackServices<F>(svcName, std::move(options), std::move(requester));
         }
 
-        //TODO trackTrackers
-
         template<typename I>
         int useServices(std::function<void(I& svc)> use, const std::string &filter = "", std::shared_ptr<const celix::IResourceBundle> requester = {}) const {
             auto svcName = celix::serviceName<I>();
@@ -338,8 +355,18 @@ namespace celix {
         std::unique_ptr<celix::ServiceRegistry::Impl> pimpl;
 
         //register services
-        celix::ServiceRegistration registerService(std::string svcName, std::shared_ptr<void> svc, celix::Properties props, std::shared_ptr<const celix::IResourceBundle> owner);
-        celix::ServiceRegistration registerServiceFactory(std::string svcName, std::shared_ptr<celix::IServiceFactory<void>> factory, celix::Properties props, std::shared_ptr<const celix::IResourceBundle> owner);
+        celix::ServiceRegistration registerService(
+                std::string svcName,
+                std::shared_ptr<void> svc,
+                celix::Properties props,
+                std::shared_ptr<const celix::IResourceBundle> owner);
+
+        template<typename I>
+        celix::ServiceRegistration registerServiceFactory(
+                std::string svcName,
+                std::shared_ptr<celix::IServiceFactory<I>> factory,
+                celix::Properties props,
+                std::shared_ptr<const celix::IResourceBundle> owner);
 
         //use Services
         template<typename I>
@@ -351,6 +378,8 @@ namespace celix {
                 const std::string &filter,
                 std::shared_ptr<const celix::IResourceBundle> requester) const;
 
+        celix::ServiceRegistration registerServiceFactory(std::string svcName, std::shared_ptr<celix::IServiceFactory<void>> factory, celix::Properties props, std::shared_ptr<const celix::IResourceBundle> owner);
+
         template<typename I>
         bool useService(
                 const std::string &svcName,
@@ -394,9 +423,7 @@ inline celix::ServiceRegistration celix::ServiceRegistry::registerFunctionServic
 }
 
 template<typename I>
-inline celix::ServiceRegistration celix::ServiceRegistry::registerServiceFactory(std::shared_ptr<celix::IServiceFactory<I>> factory, celix::Properties props, std::shared_ptr<const celix::IResourceBundle> owner) {
-    std::string svcName = celix::serviceName<I>();
-
+inline celix::ServiceRegistration celix::ServiceRegistry::registerServiceFactory(std::string svcName, std::shared_ptr<celix::IServiceFactory<I>> factory, celix::Properties props, std::shared_ptr<const celix::IResourceBundle> owner) {
     class VoidServiceFactory : public celix::IServiceFactory<void> {
     public:
         VoidServiceFactory(std::shared_ptr<celix::IServiceFactory<I>> _factory) : factory{std::move(_factory)} {}
diff --git a/libs/registry/include/celix/Utils.h b/libs/registry/include/celix/Utils.h
index 5640636..09d674d 100644
--- a/libs/registry/include/celix/Utils.h
+++ b/libs/registry/include/celix/Utils.h
@@ -24,29 +24,20 @@
 #include <string>
 #include <iostream>
 
+namespace celix {
+namespace impl {
+    void assertIsNotFunctionService(const std::string &svcName);
+    std::string typeNameFromPrettyFunction(const std::string &templateName, const std::string &pretty);
+}
+}
+
 namespace {
 
     template<typename INTERFACE_TYPENAME>
     std::string typeName() {
-        std::string result;
-
-        const char *templateStr = "INTERFACE_TYPENAME = ";
-        const size_t templateStrLen = strlen(templateStr);
-
-        result = __PRETTY_FUNCTION__; //USING pretty function to retrieve the filled in template argument without using typeid()
-        size_t bpos = result.find(templateStr) + templateStrLen; //find begin pos after INTERFACE_TYPENAME = entry
-        size_t epos = bpos;
-        while (isalnum(result[epos]) || result[epos] == '_' || result[epos] == ':' || result[epos] == ' ' || result[epos] == '*' || result[epos] == '&' || result[epos] == '<' || result[epos] == '>') {
-            epos += 1;
-        }
-        size_t len = epos - bpos;
-        result = result.substr(bpos, len);
-
-        if (result.empty()) {
-            std::cerr << "Cannot infer type name in function call '" << __PRETTY_FUNCTION__ << "'\n'";
-        }
-
-        return result;
+        static const std::string templateStr = "INTERFACE_TYPENAME = ";
+        std::string pretty = __PRETTY_FUNCTION__;
+        return celix::impl::typeNameFromPrettyFunction(templateStr, __PRETTY_FUNCTION__);
     }
 
     template<typename Arg>
@@ -60,13 +51,13 @@ namespace {
     }
 
     template<typename R>
-    std::string functionName(const std::string &funcName) {
-        return funcName + " [std::function<" + typeName<R>() + "()>]";
+    std::string functionName() {
+        return "std::function<" + typeName<R>() + "()>";
     }
 
     template<typename R, typename Arg1, typename... Args>
-    std::string functionName(const std::string &funcName) {
-        return funcName + " [std::function<" + typeName<R>() + "("  + argName<Arg1, Args...>() + ")>]";
+    std::string functionName() {
+        return "std::function<" + typeName<R>() + "("  + argName<Arg1, Args...>() + ")>";
     }
 };
 
@@ -85,9 +76,13 @@ namespace celix {
     template<typename I>
     //NOTE C++17 typename std::enable_if<!std::is_callable<I>::value, std::string>::type
     std::string serviceName() {
-        return typeName<I>();
+        std::string svcName = typeName<I>();
+        celix::impl::assertIsNotFunctionService(svcName);
+        return svcName;
     }
 
+    //TODO resolve FQN for Function Service.
+
     /**
     * Returns the service name for a std::function I.
     * Note that for a std::function the additional function name is needed to get a fully qualified service name;
@@ -95,7 +90,8 @@ namespace celix {
     template<typename F>
     //NOTE C++17 typename std::enable_if<std::is_callable<I>::value, std::string>::type
     std::string functionServiceName(const std::string &fName) {
-        return functionName<decltype(&F::operator())>(fName);
+        std::string func = functionName<decltype(&F::operator())>();
+        return fName + "[" + func + "]";
     }
 }
 
diff --git a/libs/registry/src/ServiceRegistry.cc b/libs/registry/src/ServiceRegistry.cc
index 58d5778..6ed83f7 100644
--- a/libs/registry/src/ServiceRegistry.cc
+++ b/libs/registry/src/ServiceRegistry.cc
@@ -40,7 +40,11 @@ namespace {
     public:
         ~EmptyBundle() override = default;
 
-        long id() const noexcept override { return 0; }
+        long id() const noexcept override {
+            //TODO not sure what todo. 1 is reserved for the framework and I would like to keep <= 0 as invalid, so
+            //that default initialized long are not a valid bundle / svc id.
+            return LONG_MAX;
+        }
 
         const std::string& cacheRoot() const noexcept override {
             static std::string empty{};
@@ -94,7 +98,11 @@ namespace {
 
         void decrUsage() const {
             std::lock_guard<std::mutex> lck{mutex};
-            usage -= 1;
+            if (usage == 0) {
+                LOG(ERROR) << "Usage count decrease below 0!" << std::endl;
+            } else {
+                usage -= 1;
+            }
             cond.notify_all();
         }
 
@@ -298,7 +306,11 @@ namespace {
 
         void decrUsage() const {
             std::lock_guard<std::mutex> lck{mutex};
-            usage -= 1;
+            if (usage == 0) {
+                LOG(ERROR) << "Usage count decrease below 0!" << std::endl;
+            } else {
+                usage -= 1;
+            }
             cond.notify_all();
         }
 
@@ -516,8 +528,8 @@ public:
 
 
 celix::ServiceRegistry::ServiceRegistry(std::string name) : pimpl{new ServiceRegistry::Impl{std::move(name)}} {}
-celix::ServiceRegistry::ServiceRegistry(celix::ServiceRegistry &&rhs) = default;
-celix::ServiceRegistry& celix::ServiceRegistry::operator=(celix::ServiceRegistry &&rhs) = default;
+celix::ServiceRegistry::ServiceRegistry(celix::ServiceRegistry &&) = default;
+celix::ServiceRegistry& celix::ServiceRegistry::operator=(celix::ServiceRegistry &&) = default;
 celix::ServiceRegistry::~ServiceRegistry() {
     if (pimpl) {
         //TODO
@@ -637,6 +649,7 @@ int celix::ServiceRegistry::useAnyServices(const std::string &svcName,
                                                               const celix::IResourceBundle &bnd)> use,
                                            const std::string &f,
                                            std::shared_ptr<const celix::IResourceBundle> requester) const {
+
     celix::Filter filter = f;
     if (!filter.valid()) {
         LOG(WARNING) << "Invalid filter (" << f << ") provided. Cannot find services" << std::endl;
@@ -664,18 +677,19 @@ int celix::ServiceRegistry::useAnyServices(const std::string &svcName,
             entry->decrUsage();
         }};
         use(svc, entry->props, *entry->owner);
-        entry->decrUsage();
     }
 
     return (int)matches.size();
 }
 
 //TODO move to Impl
-bool celix::ServiceRegistry::useAnyService(const std::string &svcName,
-                                           std::function<void(std::shared_ptr<void> svc, const celix::Properties &props,
-                                                              const celix::IResourceBundle &bnd)> use,
-                                           const std::string &f,
-                                           std::shared_ptr<const celix::IResourceBundle> requester) const {
+bool celix::ServiceRegistry::useAnyService(
+        const std::string &svcName,
+        std::function<void(std::shared_ptr<void> svc, const celix::Properties &props,
+                const celix::IResourceBundle &bnd)> use,
+                const std::string &f,
+                std::shared_ptr<const celix::IResourceBundle> requester) const {
+
     celix::Filter filter = f;
     if (!filter.valid()) {
         LOG(WARNING) << "Invalid filter (" << f << ") provided. Cannot find services" << std::endl;
@@ -720,8 +734,8 @@ std::vector<std::string> celix::ServiceRegistry::listAllRegisteredServiceNames()
 celix::ServiceRegistration::ServiceRegistration() : pimpl{nullptr} {}
 
 celix::ServiceRegistration::ServiceRegistration(celix::ServiceRegistration::Impl *impl) : pimpl{impl} {}
-celix::ServiceRegistration::ServiceRegistration(celix::ServiceRegistration &&rhs) noexcept = default;
-celix::ServiceRegistration& celix::ServiceRegistration::operator=(celix::ServiceRegistration &&rhs) noexcept = default;
+celix::ServiceRegistration::ServiceRegistration(celix::ServiceRegistration &&) noexcept = default;
+celix::ServiceRegistration& celix::ServiceRegistration::operator=(celix::ServiceRegistration &&) noexcept = default;
 celix::ServiceRegistration::~ServiceRegistration() { unregister(); }
 
 long celix::ServiceRegistration::serviceId() const { return pimpl ? pimpl->entry->svcId : -1L; }
@@ -774,8 +788,8 @@ void celix::ServiceTracker::stop() {
     }
 }
 
-celix::ServiceTracker::ServiceTracker(celix::ServiceTracker &&rhs) noexcept = default;
-celix::ServiceTracker& celix::ServiceTracker::operator=(celix::ServiceTracker &&rhs) noexcept = default;
+celix::ServiceTracker::ServiceTracker(celix::ServiceTracker &&) noexcept = default;
+celix::ServiceTracker& celix::ServiceTracker::operator=(celix::ServiceTracker &&) noexcept = default;
 
 int celix::ServiceTracker::trackCount() const { return pimpl ? pimpl->entry->count() : 0; }
 const std::string& celix::ServiceTracker::serviceName() const { return pimpl? pimpl->entry->svcName : emptyString; }
diff --git a/libs/registry/src/Utils.cc b/libs/registry/src/Utils.cc
new file mode 100644
index 0000000..27feccb
--- /dev/null
+++ b/libs/registry/src/Utils.cc
@@ -0,0 +1,51 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you 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 "celix/Utils.h"
+
+#include <string>
+
+#include <glog/logging.h>
+
+void celix::impl::assertIsNotFunctionService(const std::string &svcName) {
+    size_t pos = svcName.find("::function"); //note could be std::fuction or st::__1::function, etc?
+    if (pos <= svcName.size()) {
+        //match
+        LOG(WARNING) << "Unexpected std::function as template argument. For function use the find/use/trackFunctionService instead of find/use/trackService!" << std::endl;
+        assert(false);
+    }
+}
+
+std::string celix::impl::typeNameFromPrettyFunction(const std::string &templateName, const std::string &prettyFunction) {
+    std::string result = prettyFunction; //USING pretty function to retrieve the filled in template argument without using typeid()
+    size_t bpos = result.find(templateName) + templateName.size(); //find begin pos after INTERFACE_TYPENAME = entry
+    size_t epos = bpos;
+    while (isalnum(result[epos]) || result[epos] == '_' || result[epos] == ':' || result[epos] == '*' || result[epos] == '&' || result[epos] == '<' || result[epos] == '>') {
+    epos += 1;
+    }
+    size_t len = epos - bpos;
+    result = result.substr(bpos, len);
+
+    if (result.empty()) {
+        LOG(WARNING) << "Cannot infer type name in function call '" << prettyFunction << "'\n'";
+    }
+
+    return result;
+}
+