celix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pnol...@apache.org
Subject celix git commit: CELIX-426: Update C++ implementation for update C api.
Date Mon, 14 May 2018 20:30:19 GMT
Repository: celix
Updated Branches:
  refs/heads/feature/CELIX-426-cxx-api 8464f3d5c -> 4f4389256


CELIX-426: Update C++ implementation for update C api.


Project: http://git-wip-us.apache.org/repos/asf/celix/repo
Commit: http://git-wip-us.apache.org/repos/asf/celix/commit/4f438925
Tree: http://git-wip-us.apache.org/repos/asf/celix/tree/4f438925
Diff: http://git-wip-us.apache.org/repos/asf/celix/diff/4f438925

Branch: refs/heads/feature/CELIX-426-cxx-api
Commit: 4f43892563dba8fcf8279e33179d61b9ea6fc029
Parents: 8464f3d
Author: Pepijn Noltes <pepijnnoltes@gmail.com>
Authored: Mon May 14 22:29:47 2018 +0200
Committer: Pepijn Noltes <pepijnnoltes@gmail.com>
Committed: Mon May 14 22:29:47 2018 +0200

----------------------------------------------------------------------
 .../src/ConsumerBundleActivator.cc              |   4 +-
 .../src/ProviderBundleActivator.cc              |   2 +-
 framework/CMakeLists.txt                        |   4 +-
 framework/gtest/src/cxx_BundleContext_tests.cc  |  24 +-
 framework/include/celix/BundleContext.h         | 106 ++-
 framework/include/celix/Framework.h             |   6 +-
 framework/include/celix/dm/DependencyManager.h  |   2 +-
 .../include/celix/impl/BundleContextImpl.h      | 144 ++--
 framework/include/celix/impl/BundleImpl.h       |   1 +
 framework/include/celix/impl/FrameworkImpl.h    |  11 +-
 framework/include/celix_bundle.h                |  11 +-
 framework/include/celix_bundle_context.h        |   9 +-
 framework/include/framework.h                   |   2 -
 framework/private/mock/framework_mock.c         |   8 +-
 framework/src/BundleImpl.c                      | 765 ------------------
 framework/src/bundle.c                          | 766 +++++++++++++++++++
 framework/src/bundle_context.c                  |   4 +
 framework/src/framework.c                       |   5 +-
 framework/src/framework_private.h               |   9 +-
 19 files changed, 965 insertions(+), 918 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/4f438925/examples/celix-examples/services_example_cxx/src/ConsumerBundleActivator.cc
----------------------------------------------------------------------
diff --git a/examples/celix-examples/services_example_cxx/src/ConsumerBundleActivator.cc b/examples/celix-examples/services_example_cxx/src/ConsumerBundleActivator.cc
index 3371cad..f12e714 100644
--- a/examples/celix-examples/services_example_cxx/src/ConsumerBundleActivator.cc
+++ b/examples/celix-examples/services_example_cxx/src/ConsumerBundleActivator.cc
@@ -30,8 +30,8 @@ namespace {
     public:
         BundleActivator(celix::BundleContext &_ctx) : ctx{_ctx} {
             this->trackerId = ctx.trackServices<example::ICalc>(example::ICalc::NAME,
-                 [this](example::ICalc *, const celix::Properties &, const celix::Bundle&) {  this->trackCount += 1; },
-                 [this](example::ICalc *, const celix::Properties &, const celix::Bundle&) {  this->trackCount -= 1; });
+                 [this](example::ICalc *) {  this->trackCount += 1; },
+                 [this](example::ICalc *) {  this->trackCount -= 1; });
         }
 
         virtual ~BundleActivator() {

http://git-wip-us.apache.org/repos/asf/celix/blob/4f438925/examples/celix-examples/services_example_cxx/src/ProviderBundleActivator.cc
----------------------------------------------------------------------
diff --git a/examples/celix-examples/services_example_cxx/src/ProviderBundleActivator.cc b/examples/celix-examples/services_example_cxx/src/ProviderBundleActivator.cc
index ca8cf8d..c83b4af 100644
--- a/examples/celix-examples/services_example_cxx/src/ProviderBundleActivator.cc
+++ b/examples/celix-examples/services_example_cxx/src/ProviderBundleActivator.cc
@@ -48,7 +48,7 @@ namespace {
                     if (up) {
                         celix::Properties props{};
                         props[celix::Constants::SERVICE_RANKING] = std::to_string(std::rand());
-                        long svcId = ctx.registerService(example::ICalc::NAME, &calc, example::ICalc::VERSION, std::move(props));
+                        long svcId = ctx.registerService<example::ICalc>(&calc, example::ICalc::NAME, std::move(props));
                         svcIds.push_back(svcId);
                     } else {
                         long svcId = svcIds.back();

http://git-wip-us.apache.org/repos/asf/celix/blob/4f438925/framework/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/framework/CMakeLists.txt b/framework/CMakeLists.txt
index cdcd044..c32420f 100644
--- a/framework/CMakeLists.txt
+++ b/framework/CMakeLists.txt
@@ -24,7 +24,7 @@ if(WIN32)
 endif(WIN32)
 
 set(SOURCES
-        src/attribute.c src/BundleImpl.c src/bundle_archive.c src/bundle_cache.c
+        src/attribute.c src/bundle.c src/bundle_archive.c src/bundle_cache.c
         src/bundle_context.c src/bundle_revision.c src/capability.c src/celix_errorcodes.c
         src/filter.c src/framework.c src/manifest.c src/ioapi.c
         src/manifest_parser.c src/miniunz.c src/module.c
@@ -148,7 +148,7 @@ if (ENABLE_TESTING AND FRAMEWORK_TESTS)
         private/mock/bundle_revision_mock.c
         private/mock/resolver_mock.c
         private/mock/version_mock.c
-            src/BundleImpl.c
+            src/bundle.c
         src/celix_errorcodes.c
         private/mock/celix_log_mock.c)
     target_link_libraries(bundle_test ${CPPUTEST_LIBRARY} ${CPPUTEST_EXT_LIBRARY} Celix::utils pthread)

http://git-wip-us.apache.org/repos/asf/celix/blob/4f438925/framework/gtest/src/cxx_BundleContext_tests.cc
----------------------------------------------------------------------
diff --git a/framework/gtest/src/cxx_BundleContext_tests.cc b/framework/gtest/src/cxx_BundleContext_tests.cc
index a426d66..1777207 100644
--- a/framework/gtest/src/cxx_BundleContext_tests.cc
+++ b/framework/gtest/src/cxx_BundleContext_tests.cc
@@ -79,11 +79,11 @@ TEST_F(BundleContextTest, RegisterCServiceTest) {
 
     test_svc svc1{};
 
-    long svcId = ctx.registerCService("test service", &svc1);
+    long svcId = ctx.registerCService(&svc1, "test service");
     EXPECT_TRUE(svcId > 0);
     ctx.unregisterService(svcId);
 
-    long svcId2 = ctx.registerCService("test service", &svc1);
+    long svcId2 = ctx.registerCService(&svc1, "test service");
     EXPECT_TRUE(svcId2 > 0);
     EXPECT_NE(svcId, svcId2); //new registration new id
     ctx.unregisterService(svcId2);
@@ -98,11 +98,11 @@ TEST_F(BundleContextTest, RegisterServiceTest) {
 
     TestImpl svc1{};
 
-    long svcId = ctx.registerService<ITestSvc>(ITestSvc::NAME, &svc1);
+    long svcId = ctx.registerService<ITestSvc>(&svc1, ITestSvc::NAME);
     EXPECT_TRUE(svcId > 0);
     ctx.unregisterService(svcId);
 
-    long svcId2 = ctx.registerService<ITestSvc>(ITestSvc::NAME, &svc1);
+    long svcId2 = ctx.registerService<ITestSvc>(&svc1, ITestSvc::NAME);
     EXPECT_TRUE(svcId2 > 0);
     EXPECT_NE(svcId, svcId2); //new registration new id
     ctx.unregisterService(svcId2);
@@ -113,7 +113,7 @@ TEST_F(BundleContextTest, UseService) {
 
     TestImpl svc1{};
 
-    long svcId = ctx.registerService<ITestSvc>(ITestSvc::NAME, &svc1);
+    long svcId = ctx.registerService<ITestSvc>(&svc1, ITestSvc::NAME);
     EXPECT_TRUE(svcId > 0);
 
 
@@ -140,10 +140,10 @@ TEST_F(BundleContextTest, UseServices) {
 
     TestImpl svc{};
 
-    long svcId1 = ctx.registerService<ITestSvc>("test service", &svc);
+    long svcId1 = ctx.registerService<ITestSvc>(&svc, "test service");
     EXPECT_TRUE(svcId1 > 0);
 
-    long svcId2 = ctx.registerService<ITestSvc>("test service", &svc);
+    long svcId2 = ctx.registerService<ITestSvc>(&svc, "test service");
     EXPECT_TRUE(svcId2 > 0);
 
 
@@ -174,7 +174,7 @@ TEST_F(BundleContextTest, TrackService) {
     ITestSvc *svc4 = (ITestSvc*)0x400; //5 ranking
 
 
-    auto set = [&](ITestSvc *svc, const celix::Properties &, const celix::Bundle &) {
+    auto set = [&](ITestSvc *svc) {
         static int callCount = 0;
         callCount += 1;
         if (callCount == 1) {
@@ -191,8 +191,8 @@ TEST_F(BundleContextTest, TrackService) {
         count = callCount;
     };
 
-    long svcId1 = ctx.registerService("NA", svc1);
-    long svcId2 = ctx.registerService("NA", svc2);
+    long svcId1 = ctx.registerService(svc1, "NA");
+    long svcId2 = ctx.registerService(svc2, "NA");
 
     //starting tracker should lead to first set call
     long trackerId = ctx.trackService<ITestSvc>("NA", set);
@@ -201,12 +201,12 @@ TEST_F(BundleContextTest, TrackService) {
     //register svc3 should lead to second set call
     celix::Properties props3{};
     props3[OSGI_FRAMEWORK_SERVICE_RANKING] = "10";
-    long svcId3 = ctx.registerService("NA", svc3, "", std::move(props3));
+    long svcId3 = ctx.registerService(svc3, "NA", std::move(props3));
 
     //register svc4 should lead to no set (lower ranking)
     celix::Properties props4{};
     props4[OSGI_FRAMEWORK_SERVICE_RANKING] = "10";
-    long svcId4 = ctx.registerService("NA", svc4, "", props4);
+    long svcId4 = ctx.registerService(svc4, "NA", props4);
 
     //unregister svc3 should lead to set (new highest ranking)
     ctx.unregisterService(svcId3);

http://git-wip-us.apache.org/repos/asf/celix/blob/4f438925/framework/include/celix/BundleContext.h
----------------------------------------------------------------------
diff --git a/framework/include/celix/BundleContext.h b/framework/include/celix/BundleContext.h
index 9d9a274..1ff37a9 100644
--- a/framework/include/celix/BundleContext.h
+++ b/framework/include/celix/BundleContext.h
@@ -38,15 +38,40 @@ namespace celix {
     }
 
     template<typename I>
+    struct ServiceRegistrationOptions {
+        using type = I;
+
+        ServiceRegistrationOptions(I& _svc, const std::string& _serviceName) : svc{_svc}, serviceName{_serviceName} {};
+
+        I& svc;
+        const std::string serviceName;
+
+        celix::Properties properties{};
+        std::string serviceVersion{};
+        std::string serviceLanguage{celix::Constants::SERVICE_CXX_LANG};
+    };
+
+    template<typename I>
+    struct ServiceFilterOptions {
+        using type = I;
+
+        ServiceFilterOptions(const std::string &_serviceName) : serviceName{_serviceName} {};
+
+        std::string serviceName;
+
+        std::string versionRange{};
+        std::string filter{};
+        std::string lang{celix::Constants::SERVICE_CXX_LANG};
+    };
+
+
+    template<typename I>
     struct ServiceUseOptions {
-        /*
-         * Service filter info
-         */
-        const std::string &serviceName{}; //required
-        const std::string &versionRange{};
-        const std::string &filter{};
-        const std::string &lang{}; //default will be C++
+        using type = I;
+
+        ServiceUseOptions(const std::string &serviceName) : filter{ServiceFilterOptions<I>{serviceName}} {};
 
+        ServiceFilterOptions<I> filter;
 
         /*
          * Callbacks
@@ -58,13 +83,11 @@ namespace celix {
 
     template<typename I>
     struct ServiceTrackingOptions {
-        /*
-         * Service filter info
-         */
-        const std::string &serviceName{}; //required
-        const std::string &versionRange{};
-        const std::string &filter{};
-        const std::string &lang{}; //default will be C++
+        using type = I;
+
+        ServiceTrackingOptions(const std::string serviceName) : filter{ServiceFilterOptions<I>{serviceName}} {};
+
+        ServiceFilterOptions<I> filter;
 
         std::function<void(I* svc)> set{};
         std::function<void(I* svc)> add{};
@@ -105,20 +128,13 @@ namespace celix {
         virtual ~BundleContext(){};
 
         template<typename I>
-        long registerService(const std::string &serviceName, I *svc, const std::string &version = "", Properties props = {}) noexcept {
-            return this->registerServiceInternal(serviceName, svc, version, celix::Constants::SERVICE_CXX_LANG, std::move(props));
-        }
+        long registerService(I *svc, const std::string &serviceName, Properties props = {}) noexcept;
 
         template<typename I>
-        long registerCService(const std::string &serviceName, I *svc, const std::string &version = "", Properties props = {}) noexcept {
-            static_assert(std::is_pod<I>::value, "Service I must be a 'Plain Old Data' object");
-            return this->registerServiceInternal(serviceName, svc, version, celix::Constants::SERVICE_C_LANG, std::move(props));
-        }
+        long registerCService(I *svc, const std::string &serviceName, Properties props = {}) noexcept;
 
         template<typename I>
-        long registerServiceForLang(const std::string &serviceName, I *svc, const std::string &version = "", const std::string &lang = celix::Constants::SERVICE_C_LANG, Properties props = {}) noexcept {
-            return this->registerServiceInternal(serviceName, svc, version, lang, std::move(props));
-        }
+        long registerServiceWithOptions(const celix::ServiceRegistrationOptions<I>& opts) noexcept;
 
         //TODO register std::function ?
 
@@ -138,15 +154,7 @@ namespace celix {
         * @return the tracker id or < 0 if unsuccessful.
         */
         template<typename I>
-        long trackService(
-                const std::string &serviceName,
-                std::function<void(I *svc, const celix::Properties& props, const celix::Bundle &bnd)> set
-        ) noexcept {
-            return this->trackServiceInternal(serviceName, [set](void *voidSvc, const celix::Properties& props, const celix::Bundle &bnd) {
-                I* typedSvc = static_cast<I*>(voidSvc);
-                set(typedSvc, props, bnd);
-            });
-        }
+        long trackService(const std::string &serviceName, std::function<void(I *svc)> set) noexcept;
 
         /**
          * track services for the provided serviceName and/or filter.
@@ -158,25 +166,9 @@ namespace celix {
          * @return the tracker id or < 0 if unsuccessful.
          */
         template<typename I>
-        long trackServices(
-                const std::string &serviceName,
-                std::function<void(I *svc, const celix::Properties& props, const celix::Bundle &bnd)> add,
-                std::function<void(I *svc, const celix::Properties& props, const celix::Bundle &bnd)> remove
-        ) noexcept {
-            return this->trackServicesInternal(serviceName,
-                                               [add](void *voidSvc, const celix::Properties& props, const celix::Bundle &bnd) {
-                                                   I *typedSvc = static_cast<I *>(voidSvc);
-                                                   add(typedSvc, props, bnd);
-                                               },
-                                               [remove](void *voidSvc, const celix::Properties& props, const celix::Bundle &bnd) {
-                                                   I *typedSvc = static_cast<I *>(voidSvc);
-                                                   remove(typedSvc, props, bnd);
-                                               }
-            );
-        }
+        long trackServices(const std::string &serviceName, std::function<void(I *svc)> add, std::function<void(I *svc)> remove) noexcept;
 
-        //TODO make add / remove service refs??
-        //TODO add trackService(s)WithOptions
+        //TODO trackService(s)WithOptions
         //TODO add trackCService(s) variants
 
         /**
@@ -262,16 +254,10 @@ namespace celix {
 
         virtual bool useBundle(long bundleId, const std::function<void(const celix::Bundle &bnd)> &use) noexcept = 0;
     protected:
-        virtual long registerServiceInternal(const std::string &serviceName, void *svc, const std::string &version, const std::string &lang, celix::Properties props) noexcept = 0;
-
-        virtual long trackServiceInternal(const std::string &serviceName,
-                                         std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &bnd)> set) noexcept = 0;
+        virtual long registerServiceInternal(const celix_service_registration_options_t &opts) noexcept  = 0;
 
-        virtual long trackServicesInternal(
-                const std::string &serviceName,
-                std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &bnd)> add,
-                std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &bnd)> remove
-        ) noexcept = 0;
+        virtual long trackServiceInternal(const std::string &serviceName, std::function<void(void *svc)> set) noexcept = 0;
+        virtual long trackServicesInternal(const std::string &serviceName, std::function<void(void *svc)> add, std::function<void(void *svc)> remove) noexcept = 0;
 
         virtual bool useServiceInternal(const std::string &serviceName, const std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept = 0;
         virtual void useServicesInternal(const std::string &serviceName, const std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept = 0;

http://git-wip-us.apache.org/repos/asf/celix/blob/4f438925/framework/include/celix/Framework.h
----------------------------------------------------------------------
diff --git a/framework/include/celix/Framework.h b/framework/include/celix/Framework.h
index e8daa6a..790cfc0 100644
--- a/framework/include/celix/Framework.h
+++ b/framework/include/celix/Framework.h
@@ -17,9 +17,6 @@
  *under the License.
  */
 
-#ifndef CXX_CELIX_FRAMEWORK_H
-#define CXX_CELIX_FRAMEWORK_H
-
 #include <functional>
 
 #include "celix/Constants.h"
@@ -27,6 +24,9 @@
 #include "Bundle.h"
 #include "celix/BundleContext.h"
 
+#ifndef CXX_CELIX_FRAMEWORK_H
+#define CXX_CELIX_FRAMEWORK_H
+
 namespace celix {
 
     class Framework  {

http://git-wip-us.apache.org/repos/asf/celix/blob/4f438925/framework/include/celix/dm/DependencyManager.h
----------------------------------------------------------------------
diff --git a/framework/include/celix/dm/DependencyManager.h b/framework/include/celix/dm/DependencyManager.h
index 5a4dd99..538edb1 100644
--- a/framework/include/celix/dm/DependencyManager.h
+++ b/framework/include/celix/dm/DependencyManager.h
@@ -25,7 +25,7 @@
 #include "celix/dm/Component.h"
 #include "celix/dm/ServiceDependency.h"
 
-#include "bundle_context.h"
+#include "celix_bundle_context.h"
 #include "dm_dependency_manager.h"
 
 #include <vector>

http://git-wip-us.apache.org/repos/asf/celix/blob/4f438925/framework/include/celix/impl/BundleContextImpl.h
----------------------------------------------------------------------
diff --git a/framework/include/celix/impl/BundleContextImpl.h b/framework/include/celix/impl/BundleContextImpl.h
index cc2bc0e..42af304 100644
--- a/framework/include/celix/impl/BundleContextImpl.h
+++ b/framework/include/celix/impl/BundleContextImpl.h
@@ -166,36 +166,30 @@ namespace celix {
 
         protected:
 
-            long registerServiceInternal(const std::string &serviceName, void *svc, const std::string &version, const std::string &lang, Properties props = {}) noexcept override {
-                properties_t *c_props = properties_create();
-                for (auto &pair : props) {
-                    properties_set(c_props, pair.first.c_str(), pair.second.c_str());
-                }
-                return celix_bundleContext_registerServiceForLang(this->c_ctx, serviceName.c_str(), svc, version.c_str(), lang.c_str(), c_props);
+            long registerServiceInternal(const celix_service_registration_options_t &opts) noexcept override {
+                return celix_bundleContext_registerServiceWithOptions(this->c_ctx, &opts);
             }
 
-            long trackServiceInternal(const std::string &serviceName,
-                                      std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &bnd)> set) noexcept override  {
-                celix_service_tracking_options_t opts;
-                std::memset(&opts, 0, sizeof(opts));
+            long trackServiceInternal(const std::string &serviceName, std::function<void(void *svc)> set) noexcept override  {
+                celix_service_tracking_options_t opts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS;
 
-                auto c_set = [](void *handle, void *svc, const celix_properties_t *c_props, const celix_bundle_t *c_bnd) {
+                auto c_set = [](void *handle, void *svc) {
                     auto *entry = static_cast<TrackEntry*>(handle);
-                    celix::Properties props = createFromCProps(c_props);
-                    auto m_bnd = const_cast<celix_bundle_t *>(c_bnd);
-                    celix::impl::BundleImpl bnd{m_bnd};
-                    (entry->set)(svc, props, bnd);
+                    //celix::Properties props = createFromCProps(c_props);
+                    //auto m_bnd = const_cast<celix_bundle_t *>(c_bnd);
+                    //celix::impl::BundleImpl bnd{m_bnd};
+                    (entry->set)(svc);
                 };
                 const char *cname = serviceName.empty() ? nullptr : serviceName.c_str();
 
-                opts.serviceName = cname;
-                opts.lang = CELIX_FRAMEWORK_SERVICE_CXX_LANGUAGE;
+                opts.filter.serviceName = cname;
+                opts.filter.serviceLanguage = CELIX_FRAMEWORK_SERVICE_CXX_LANGUAGE;
 
                 auto te = std::unique_ptr<TrackEntry>{new TrackEntry{}};
                 te->set = std::move(set);
 
                 opts.callbackHandle = te.get();
-                opts.setWithOwner = c_set;
+                opts.set = c_set;
 
                 long id = celix_bundleContext_trackServicesWithOptions(this->c_ctx, &opts);
                 if (id >= 0) {
@@ -207,37 +201,37 @@ namespace celix {
 
             long trackServicesInternal(
                     const std::string &serviceName,
-                    std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &bnd)> add,
-                    std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &bnd)> remove
+                    std::function<void(void *svc)> add,
+                    std::function<void(void *svc)> remove
             ) noexcept override {
                 celix_service_tracking_options_t opts;
                 std::memset(&opts, 0, sizeof(opts));
 
-                auto c_add = [](void *handle, void *svc, const celix_properties_t *c_props, const celix_bundle_t *c_bnd) {
+                auto c_add = [](void *handle, void *svc) {
                     auto *entry = static_cast<TrackEntry*>(handle);
-                    celix::Properties props = createFromCProps(c_props);
-                    auto m_bnd = const_cast<celix_bundle_t *>(c_bnd);
-                    celix::impl::BundleImpl bnd{m_bnd};
-                    (entry->add)(svc, props, bnd);
+                    //celix::Properties props = createFromCProps(c_props);
+                    //auto m_bnd = const_cast<celix_bundle_t *>(c_bnd);
+                    //celix::impl::BundleImpl bnd{m_bnd};
+                    (entry->add)(svc);
                 };
-                auto c_remove = [](void *handle, void *svc, const celix_properties_t *c_props, const celix_bundle_t *c_bnd) {
+                auto c_remove = [](void *handle, void *svc) {
                     auto *entry = static_cast<TrackEntry*>(handle);
-                    celix::Properties props = createFromCProps(c_props);
-                    auto m_bnd = const_cast<celix_bundle_t *>(c_bnd);
-                    celix::impl::BundleImpl bnd{m_bnd};
-                    (entry->remove)(svc, props, bnd);
+                    //celix::Properties props = createFromCProps(c_props);
+                    //auto m_bnd = const_cast<celix_bundle_t *>(c_bnd);
+                    //celix::impl::BundleImpl bnd{m_bnd};
+                    (entry->remove)(svc);
                 };
 
-                opts.serviceName = serviceName.empty() ? nullptr : serviceName.c_str();
-                opts.lang = CELIX_FRAMEWORK_SERVICE_CXX_LANGUAGE;
+                opts.filter.serviceName = serviceName.empty() ? nullptr : serviceName.c_str();
+                opts.filter.serviceLanguage = CELIX_FRAMEWORK_SERVICE_CXX_LANGUAGE;
 
                 auto te = std::unique_ptr<TrackEntry>{new TrackEntry{}};
                 te->add = std::move(add);
                 te->remove = std::move(remove);
 
                 opts.callbackHandle = te.get();
-                opts.addWithOwner = c_add;
-                opts.removeWithOwner = c_remove;
+                opts.add = c_add;
+                opts.remove = c_remove;
 
                 long id = celix_bundleContext_trackServicesWithOptions(this->c_ctx, &opts);
                 if (id >= 0) {
@@ -261,10 +255,10 @@ namespace celix {
                 celix_service_use_options_t opts;
                 std::memset(&opts, 0, sizeof(opts));
 
-                opts.serviceName = serviceName.empty() ? nullptr : serviceName.c_str();;
-                opts.lang = celix::Constants::SERVICE_CXX_LANG;
+                opts.filter.serviceName = serviceName.empty() ? nullptr : serviceName.c_str();;
+                opts.filter.serviceLanguage = celix::Constants::SERVICE_CXX_LANG;
                 opts.callbackHandle = (void*)&use;
-                opts.use = c_use;
+                opts.useWithOwner = c_use;
 
                 return celix_bundleContext_useServiceWithOptions(this->c_ctx, &opts);
             }
@@ -283,10 +277,10 @@ namespace celix {
                 celix_service_use_options_t opts;
                 std::memset(&opts, 0, sizeof(opts));
 
-                opts.serviceName = serviceName.empty() ? nullptr : serviceName.c_str();;
-                opts.lang = celix::Constants::SERVICE_CXX_LANG;
+                opts.filter.serviceName = serviceName.empty() ? nullptr : serviceName.c_str();;
+                opts.filter.serviceLanguage = celix::Constants::SERVICE_CXX_LANG;
                 opts.callbackHandle = (void*)&use;
-                opts.use = c_use;
+                opts.useWithOwner = c_use;
 
                 celix_bundleContext_useServicesWithOptions(this->c_ctx, &opts);
             }
@@ -299,9 +293,17 @@ namespace celix {
             celix::dm::DependencyManager dm;
 
             struct TrackEntry {
-                std::function<void(void *, const celix::Properties &, const celix::Bundle &)> set{};
-                std::function<void(void *, const celix::Properties &, const celix::Bundle &)> add{};
-                std::function<void(void *, const celix::Properties &, const celix::Bundle &)> remove{};
+                std::function<void(void *)> set{};
+                std::function<void(void *, const celix::Properties &)> setWithProperties{};
+                std::function<void(void *, const celix::Properties &, const celix::Bundle &)> setWithOwner{};
+
+                std::function<void(void *)> add{};
+                std::function<void(void *, const celix::Properties &)> addWithProperties{};
+                std::function<void(void *, const celix::Properties &, const celix::Bundle &)> addWithOwner{};
+
+                std::function<void(void *)> remove{};
+                std::function<void(void *, const celix::Properties &)> removeWithProperties{};
+                std::function<void(void *, const celix::Properties &, const celix::Bundle &)> removeWithOwner{};
             };
 
             std::mutex mutex{};
@@ -310,4 +312,60 @@ namespace celix {
     }
 }
 
+
+template<typename I>
+long celix::BundleContext::registerService(I *svc, const std::string &serviceName, Properties props) noexcept {
+    celix::ServiceRegistrationOptions<I> opts{*svc, serviceName};
+    opts.properties = std::move(props);
+    return this->registerServiceWithOptions(opts);
+}
+
+template<typename I>
+long celix::BundleContext::registerCService(I *svc, const std::string &serviceName, Properties props) noexcept {
+    static_assert(std::is_pod<I>::value, "Service I must be a 'Plain Old Data' object");
+    celix::ServiceRegistrationOptions<I> opts{*svc, serviceName};
+    opts.properties = std::move(props);
+    opts.serviceLanguage = celix::Constants::SERVICE_C_LANG;
+    return this->registerServiceWithOptions(opts);
+}
+
+template<typename I>
+long celix::BundleContext::registerServiceWithOptions(const celix::ServiceRegistrationOptions<I>& opts) noexcept {
+    celix_properties_t *c_props = celix_properties_create();
+    for (auto &pair : opts.properties) {
+        celix_properties_set(c_props, pair.first.c_str(), pair.second.c_str());
+    }
+
+    celix_service_registration_options_t cOpts = CELIX_EMPTY_SERVICE_REGISTRATION_OPTIONS;
+    cOpts.svc = static_cast<void*>(&opts.svc);
+    cOpts.serviceName = opts.serviceName.c_str();
+    cOpts.serviceVersion = opts.serviceVersion.c_str();
+    cOpts.serviceLanguage = opts.serviceLanguage.c_str();
+    cOpts.properties = c_props;
+    return this->registerServiceInternal(cOpts);
+}
+
+template<typename I>
+long celix::BundleContext::trackService(const std::string &serviceName, std::function<void(I *svc)> set) noexcept {
+    return this->trackServiceInternal(serviceName, [set](void *voidSvc) {
+        I* typedSvc = static_cast<I*>(voidSvc);
+        set(typedSvc);
+    });
+}
+
+template<typename I>
+long celix::BundleContext::trackServices(const std::string &serviceName,
+        std::function<void(I *svc)> add, std::function<void(I *svc)> remove) noexcept {
+    auto voidAdd = [add](void *voidSvc) {
+        I *typedSvc = static_cast<I *>(voidSvc);
+        add(typedSvc);
+    };
+    auto voidRemove = [remove](void *voidSvc) {
+        I *typedSvc = static_cast<I *>(voidSvc);
+        remove(typedSvc);
+    };
+    return this->trackServicesInternal(serviceName, std::move(voidAdd), std::move(voidRemove));
+}
+
+
 #endif //CELIX_IMPL_BUNDLECONTEXTIMPL_H

http://git-wip-us.apache.org/repos/asf/celix/blob/4f438925/framework/include/celix/impl/BundleImpl.h
----------------------------------------------------------------------
diff --git a/framework/include/celix/impl/BundleImpl.h b/framework/include/celix/impl/BundleImpl.h
index 1f5c9c8..5fc6374 100644
--- a/framework/include/celix/impl/BundleImpl.h
+++ b/framework/include/celix/impl/BundleImpl.h
@@ -21,6 +21,7 @@
 #define CELIX_IMPL_BUNDLEIMPL_H
 
 #include "celix_bundle.h"
+#include "celix_bundle_context.h"
 
 namespace celix {
 

http://git-wip-us.apache.org/repos/asf/celix/blob/4f438925/framework/include/celix/impl/FrameworkImpl.h
----------------------------------------------------------------------
diff --git a/framework/include/celix/impl/FrameworkImpl.h b/framework/include/celix/impl/FrameworkImpl.h
index 0b7475e..7043ffa 100644
--- a/framework/include/celix/impl/FrameworkImpl.h
+++ b/framework/include/celix/impl/FrameworkImpl.h
@@ -17,8 +17,8 @@
  *under the License.
  */
 
-#ifndef CELIX_IMPL_FRAMEWORKIMPL_H
-#define CELIX_IMPL_FRAMEWORKIMPL_H
+#ifndef CXX_CELIX_IMPL_FRAMEWORKIMPL_H
+#define CXX_CELIX_IMPL_FRAMEWORKIMPL_H
 
 #include "celix_framework_factory.h"
 #include "framework.h"
@@ -81,8 +81,9 @@ namespace celix {
             }
             //TODO also in c virtual void breakWaitForStops() noexcept = 0;
 
-            virtual std::string getUUID() const noexcept override {
-                return std::string{framework_getUUID(this->c_fwm)};
+            std::string getUUID() const noexcept override {
+                //TODO return std::string{celix_framework_getUUID(this->c_fwm)};
+                return "TODO";
             }
 
             celix::BundleContext& getFrameworkContext() noexcept override {
@@ -123,4 +124,4 @@ namespace celix {
     }
 }
 
-#endif //CELIX_IMPL_FRAMEWORKIMPL_H
+#endif //CXX_CELIX_IMPL_FRAMEWORKIMPL_H

http://git-wip-us.apache.org/repos/asf/celix/blob/4f438925/framework/include/celix_bundle.h
----------------------------------------------------------------------
diff --git a/framework/include/celix_bundle.h b/framework/include/celix_bundle.h
index 9b38627..798a6f7 100644
--- a/framework/include/celix_bundle.h
+++ b/framework/include/celix_bundle.h
@@ -33,12 +33,13 @@ extern "C" {
      **********************************************************************************************************************
      **********************************************************************************************************************/
     
-    long celix_bundle_getId(const bundle_t *bnd);
-    
-    celix_bundle_state_e celix_bundle_getState(const bundle_t *bnd);
-    
-    
+    long celix_bundle_getId(const celix_bundle_t *bnd);
     
+    celix_bundle_state_e celix_bundle_getState(const celix_bundle_t *bnd);
+
+    char* celix_bundle_getEntry(const celix_bundle_t *bnd, const char* name);
+
+
 #ifdef __cplusplus
 }
 #endif

http://git-wip-us.apache.org/repos/asf/celix/blob/4f438925/framework/include/celix_bundle_context.h
----------------------------------------------------------------------
diff --git a/framework/include/celix_bundle_context.h b/framework/include/celix_bundle_context.h
index 1e8dff5..4c7af12 100644
--- a/framework/include/celix_bundle_context.h
+++ b/framework/include/celix_bundle_context.h
@@ -650,7 +650,7 @@ long celix_bundleContext_trackBundlesWithOptions(
  * @param use               The callback which will be called for the currently started bundles.
  *                          The bundle pointers are only guaranteed to be valid during the callback.
  */
-void celix_bundleContext_useBundle(
+bool celix_bundleContext_useBundle(
         celix_bundle_context_t *ctx,
         long bundleId,
         void *callbackHandle,
@@ -684,6 +684,13 @@ void celix_bundleContext_useBundles(
  */
 dm_dependency_manager_t* celix_bundleContext_getDependencyManager(celix_bundle_context_t *ctx);
 
+/**
+ * Gets the bundle for this bundle context
+ *
+ * @return the bundle or NULL if unsuccessful.
+ */
+ celix_bundle_t* celix_bundleContext_getBundle(celix_bundle_context_t *ctx);
+
 #ifdef __cplusplus
 }
 #endif

http://git-wip-us.apache.org/repos/asf/celix/blob/4f438925/framework/include/framework.h
----------------------------------------------------------------------
diff --git a/framework/include/framework.h b/framework/include/framework.h
index 0b718af..6f6827c 100644
--- a/framework/include/framework.h
+++ b/framework/include/framework.h
@@ -51,8 +51,6 @@ FRAMEWORK_EXPORT celix_status_t framework_stop(framework_t *framework);
 
 FRAMEWORK_EXPORT celix_status_t framework_destroy(framework_t *framework);
 
-FRAMEWORK_EXPORT const char* framework_getUUID(framework_t *framework);
-
 FRAMEWORK_EXPORT celix_status_t fw_init(framework_t *framework);
 
 FRAMEWORK_EXPORT celix_status_t framework_waitForStop(framework_t *framework);

http://git-wip-us.apache.org/repos/asf/celix/blob/4f438925/framework/private/mock/framework_mock.c
----------------------------------------------------------------------
diff --git a/framework/private/mock/framework_mock.c b/framework/private/mock/framework_mock.c
index 86a2791..9933dc0 100644
--- a/framework/private/mock/framework_mock.c
+++ b/framework/private/mock/framework_mock.c
@@ -16,13 +16,7 @@
  *specific language governing permissions and limitations
  *under the License.
  */
-/*
- * framework_mock.c
- *
- *  \date       Feb 7, 2013
- *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright  Apache License, Version 2.0
- */
+
 #include <CppUTestExt/MockSupport_c.h>
 #include "CppUTestExt/MockSupport_c.h"
 

http://git-wip-us.apache.org/repos/asf/celix/blob/4f438925/framework/src/BundleImpl.c
----------------------------------------------------------------------
diff --git a/framework/src/BundleImpl.c b/framework/src/BundleImpl.c
deleted file mode 100644
index 0fcba53..0000000
--- a/framework/src/BundleImpl.c
+++ /dev/null
@@ -1,765 +0,0 @@
-/**
- *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 <stdlib.h>
-#include <string.h>
-
-#include "framework_private.h"
-#include "bundle_private.h"
-#include "resolver.h"
-#include "utils.h"
-
-celix_status_t bundle_createModule(bundle_pt bundle, module_pt *module);
-celix_status_t bundle_closeRevisions(bundle_pt bundle);
-
-celix_status_t bundle_create(bundle_pt * bundle) {
-    celix_status_t status;
-    bundle_archive_pt archive = NULL;
-
-	*bundle = (bundle_pt) malloc(sizeof(**bundle));
-	if (*bundle == NULL) {
-		return CELIX_ENOMEM;
-	}
-	status = bundleArchive_createSystemBundleArchive(&archive);
-	if (status == CELIX_SUCCESS) {
-        module_pt module;
-
-        (*bundle)->archive = archive;
-        (*bundle)->activator = NULL;
-        (*bundle)->context = NULL;
-        (*bundle)->framework = NULL;
-        (*bundle)->state = OSGI_FRAMEWORK_BUNDLE_INSTALLED;
-        (*bundle)->modules = NULL;
-        arrayList_create(&(*bundle)->modules);
-        (*bundle)->handle = NULL;
-        (*bundle)->manifest = NULL;
-
-        module = module_createFrameworkModule((*bundle));
-        bundle_addModule(*bundle, module);
-
-        status = celixThreadMutex_create(&(*bundle)->lock, NULL);
-        if (status != CELIX_SUCCESS) {
-        	status = CELIX_ILLEGAL_STATE;
-        } else {
-			(*bundle)->lockCount = 0;
-			(*bundle)->lockThread = celix_thread_default;
-        }
-	}
-	framework_logIfError(logger, status, NULL, "Failed to create bundle");
-
-	return status;
-}
-
-celix_status_t bundle_createFromArchive(bundle_pt * bundle, framework_pt framework, bundle_archive_pt archive) {
-    module_pt module;
-	
-	celix_status_t status;
-
-	*bundle = (bundle_pt) malloc(sizeof(**bundle));
-	if (*bundle == NULL) {
-		return CELIX_ENOMEM;
-	}
-	(*bundle)->archive = archive;
-	(*bundle)->activator = NULL;
-	(*bundle)->context = NULL;
-	(*bundle)->handle = NULL;
-	(*bundle)->manifest = NULL;
-	(*bundle)->framework = framework;
-	(*bundle)->state = OSGI_FRAMEWORK_BUNDLE_INSTALLED;
-	(*bundle)->modules = NULL;
-	arrayList_create(&(*bundle)->modules);
-	
-	status = bundle_createModule(*bundle, &module);
-	if (status == CELIX_SUCCESS) {
-		bundle_addModule(*bundle, module);
-        status = celixThreadMutex_create(&(*bundle)->lock, NULL);
-        if (status != CELIX_SUCCESS) {
-			status = CELIX_ILLEGAL_STATE;
-		} else {
-			(*bundle)->lockCount = 0;
-			(*bundle)->lockThread = celix_thread_default;
-		}
-	} else {
-	    status = CELIX_FILE_IO_EXCEPTION;
-	}
-
-	framework_logIfError(logger, status, NULL, "Failed to create bundle");
-
-	return status;
-}
-
-celix_status_t bundle_destroy(bundle_pt bundle) {
-	array_list_iterator_pt iter = arrayListIterator_create(bundle->modules);
-	while (arrayListIterator_hasNext(iter)) {
-		module_pt module = arrayListIterator_next(iter);
-		module_destroy(module);
-	}
-	arrayListIterator_destroy(iter);
-	arrayList_destroy(bundle->modules);
-	celixThreadMutex_destroy(&bundle->lock);
-
-	free(bundle);
-
-	return CELIX_SUCCESS;
-}
-
-celix_status_t bundle_getArchive(bundle_pt bundle, bundle_archive_pt *archive) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	if (bundle != NULL && *archive == NULL) {
-		*archive = bundle->archive;
-	} else {
-		status = CELIX_ILLEGAL_ARGUMENT;
-	}
-
-	framework_logIfError(logger, status, NULL, "Failed to get bundle archive");
-
-	return status;
-}
-
-celix_status_t bundle_getCurrentModule(bundle_pt bundle, module_pt *module) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	if (bundle == NULL || arrayList_size(bundle->modules)==0 ) {
-		status = CELIX_ILLEGAL_ARGUMENT;
-	} else {
-		*module = arrayList_get(bundle->modules, arrayList_size(bundle->modules) - 1);
-	}
-
-	return status;
-}
-
-array_list_pt bundle_getModules(bundle_pt bundle) {
-    return bundle->modules;
-}
-
-void * bundle_getHandle(bundle_pt bundle) {
-	return bundle->handle;
-}
-
-void bundle_setHandle(bundle_pt bundle, void * handle) {
-	bundle->handle = handle;
-}
-
-activator_pt bundle_getActivator(bundle_pt bundle) {
-	return bundle->activator;
-}
-
-celix_status_t bundle_setActivator(bundle_pt bundle, activator_pt activator) {
-	bundle->activator = activator;
-	return CELIX_SUCCESS;
-}
-
-celix_status_t bundle_getContext(bundle_pt bundle, bundle_context_pt *context) {
-	*context = bundle->context;
-	return CELIX_SUCCESS;
-}
-
-celix_status_t bundle_setContext(bundle_pt bundle, bundle_context_pt context) {
-	bundle->context = context;
-	return CELIX_SUCCESS;
-}
-
-celix_status_t bundle_getEntry(bundle_pt bundle, const char* name, char** out) {
-	char *entry = celix_bundle_getEntry(bundle, name);
-	if (out != NULL ) {
-		*out = entry;
-	}
-	return CELIX_SUCCESS;
-}
-
-celix_status_t bundle_getState(bundle_pt bundle, bundle_state_e *state) {
-	if(bundle==NULL){
-		*state = OSGI_FRAMEWORK_BUNDLE_UNKNOWN;
-		return CELIX_BUNDLE_EXCEPTION;
-	}
-	*state = bundle->state;
-	return CELIX_SUCCESS;
-}
-
-celix_status_t bundle_setState(bundle_pt bundle, bundle_state_e state) {
-	bundle->state = state;
-	return CELIX_SUCCESS;
-}
-
-celix_status_t bundle_createModule(bundle_pt bundle, module_pt *module) {
-	celix_status_t status = CELIX_SUCCESS;
-	bundle_archive_pt archive = NULL;
-	bundle_revision_pt revision = NULL;
-	manifest_pt headerMap = NULL;
-
-	status = CELIX_DO_IF(status, bundle_getArchive(bundle, &archive));
-	status = CELIX_DO_IF(status, bundleArchive_getCurrentRevision(archive, &revision));
-	status = CELIX_DO_IF(status, bundleRevision_getManifest(revision, &headerMap));
-	if (status == CELIX_SUCCESS) {
-		long bundleId = 0;
-        status = bundleArchive_getId(bundle->archive, &bundleId);
-        if (status == CELIX_SUCCESS) {
-			int revision = 0;
-			char moduleId[512];
-
-			snprintf(moduleId, sizeof(moduleId), "%ld.%d", bundleId, revision);
-			*module = module_create(headerMap, moduleId, bundle);
-
-			if (*module != NULL) {
-				version_pt bundleVersion = module_getVersion(*module);
-				const char * symName = NULL;
-				status = module_getSymbolicName(*module, &symName);
-				if (status == CELIX_SUCCESS) {
-					array_list_pt bundles = framework_getBundles(bundle->framework);
-					unsigned int i;
-					for (i = 0; i < arrayList_size(bundles); i++) {
-						bundle_pt check = (bundle_pt) arrayList_get(bundles, i);
-
-						long id;
-						if (bundleArchive_getId(check->archive, &id) == CELIX_SUCCESS) {
-							if (id != bundleId) {
-								module_pt mod = NULL;
-								const char * sym = NULL;
-								version_pt version;
-								int cmp;
-								status = bundle_getCurrentModule(check, &mod);
-								status = module_getSymbolicName(mod, &sym);
-
-								version = module_getVersion(mod);
-								version_compareTo(bundleVersion, version, &cmp);
-								if ((symName != NULL) && (sym != NULL) && !strcmp(symName, sym) &&
-										!cmp) {
-									char *versionString = NULL;
-									version_toString(version, &versionString);
-									printf("Bundle symbolic name and version are not unique: %s:%s\n", sym, versionString);
-									free(versionString);
-									status = CELIX_BUNDLE_EXCEPTION;
-									break;
-								}
-							}
-						}
-					}
-					arrayList_destroy(bundles);
-				}
-			}
-        }
-	}
-
-	framework_logIfError(logger, status, NULL, "Failed to create module");
-
-	return status;
-}
-
-celix_status_t bundle_start(bundle_pt bundle) {
-	return bundle_startWithOptions(bundle, 0);
-}
-
-celix_status_t bundle_startWithOptions(bundle_pt bundle, int options) {
-	celix_status_t status = CELIX_SUCCESS;
-    if (bundle != NULL) {
-    	bool systemBundle = false;
-    	status = bundle_isSystemBundle(bundle, &systemBundle);
-    	if (status == CELIX_SUCCESS) {
-    		if (systemBundle) {
-    			framework_start(bundle->framework);
-    		} else {
-    			status = fw_startBundle(bundle->framework, bundle, options);
-    		}
-    	}
-    }
-
-	framework_logIfError(logger, status, NULL, "Failed to start bundle");
-
-    return status;
-}
-
-celix_status_t bundle_update(bundle_pt bundle, const char *inputFile) {
-	celix_status_t status = CELIX_SUCCESS;
-	if (bundle != NULL) {
-		bool systemBundle = false;
-		status = bundle_isSystemBundle(bundle, &systemBundle);
-		if (status == CELIX_SUCCESS) {
-			if (systemBundle) {
-				// #TODO: Support framework update
-				status = CELIX_BUNDLE_EXCEPTION;
-			} else {
-				status = framework_updateBundle(bundle->framework, bundle, inputFile);
-			}
-		}
-	}
-
-	framework_logIfError(logger, status, NULL, "Failed to update bundle");
-
-	return status;
-}
-
-celix_status_t bundle_stop(bundle_pt bundle) {
-	return bundle_stopWithOptions(bundle, 0);
-}
-
-celix_status_t bundle_stopWithOptions(bundle_pt bundle, int options) {
-	celix_status_t status = CELIX_SUCCESS;
-	if (bundle != NULL) {
-		bool systemBundle = false;
-		status = bundle_isSystemBundle(bundle, &systemBundle);
-		if (status == CELIX_SUCCESS) {
-			if (systemBundle) {
-				framework_stop(bundle->framework);
-			} else {
-				status = fw_stopBundle(bundle->framework, bundle, options);
-			}
-		}
-	}
-
-	framework_logIfError(logger, status, NULL, "Failed to stop bundle");
-
-	return status;
-}
-
-celix_status_t bundle_uninstall(bundle_pt bundle) {
-	celix_status_t status = CELIX_SUCCESS;
-	if (bundle != NULL) {
-		bool systemBundle = false;
-		status = bundle_isSystemBundle(bundle, &systemBundle);
-		if (status == CELIX_SUCCESS) {
-			if (systemBundle) {
-				status = CELIX_BUNDLE_EXCEPTION;
-			} else {
-				status = fw_uninstallBundle(bundle->framework, bundle);
-			}
-		}
-	}
-
-	framework_logIfError(logger, status, NULL, "Failed to uninstall bundle");
-
-	return status;
-}
-
-celix_status_t bundle_setPersistentStateInactive(bundle_pt bundle) {
-	celix_status_t status;
-	bool systemBundle;
-
-	status = bundle_isSystemBundle(bundle, &systemBundle);
-	if (status == CELIX_SUCCESS) {
-		if (!systemBundle) {
-			status = bundleArchive_setPersistentState(bundle->archive, OSGI_FRAMEWORK_BUNDLE_INSTALLED);
-		}
-	}
-
-	framework_logIfError(logger, status, NULL, "Failed to set persistent state to inactive");
-
-	return status;
-}
-
-celix_status_t bundle_setPersistentStateUninstalled(bundle_pt bundle) {
-	celix_status_t status;
-	bool systemBundle;
-
-	status = bundle_isSystemBundle(bundle, &systemBundle);
-	if (status == CELIX_SUCCESS) {
-		if (!systemBundle) {
-			status = bundleArchive_setPersistentState(bundle->archive, OSGI_FRAMEWORK_BUNDLE_UNINSTALLED);
-		}
-	}
-
-	framework_logIfError(logger, status, NULL, "Failed to set persistent state to uninstalled");
-
-    return status;
-}
-
-celix_status_t bundle_revise(bundle_pt bundle, const char * location, const char *inputFile) {
-	celix_status_t status;
-
-	bundle_archive_pt archive = NULL;
-	status = bundle_getArchive(bundle, &archive);
-	if (status == CELIX_SUCCESS) {
-		status = bundleArchive_revise(archive, location, inputFile);
-		if (status == CELIX_SUCCESS) {
-			module_pt module;
-			status = bundle_createModule(bundle, &module);
-			if (status == CELIX_SUCCESS) {
-				status = bundle_addModule(bundle, module);
-			} else {
-				bool rolledback;
-				status = bundleArchive_rollbackRevise(archive, &rolledback);
-				if (status == CELIX_SUCCESS) {
-					status = CELIX_BUNDLE_EXCEPTION;
-				}
-			}
-		}
-	}
-
-	framework_logIfError(logger, status, NULL, "Failed to revise bundle");
-
-	return status;
-}
-
-//bool bundle_rollbackRevise(bundle_pt bundle) {
-//	module_pt module = arrayList_remove(bundle->modules, arrayList_set(bundle->modules) - 1);
-//	return resolver_removeModule(module);
-//}
-
-celix_status_t bundle_addModule(bundle_pt bundle, module_pt module) {
-	arrayList_add(bundle->modules, module);
-	resolver_addModule(module);
-	return CELIX_SUCCESS;
-}
-
-celix_status_t bundle_isSystemBundle(bundle_pt bundle, bool *systemBundle) {
-	celix_status_t status;
-	long bundleId;
-	bundle_archive_pt archive = NULL;
-
-	status = bundle_getArchive(bundle, &archive);
-	if (status == CELIX_SUCCESS) {
-		status = bundleArchive_getId(archive, &bundleId);
-		if (status == CELIX_SUCCESS) {
-			*systemBundle = (bundleId == 0);
-		}
-	}
-
-	framework_logIfError(logger, status, NULL, "Failed to check if bundle is the systembundle");
-
-	return status;
-}
-
-celix_status_t bundle_isLockable(bundle_pt bundle, bool *lockable) {
-	celix_status_t status;
-
-	status = celixThreadMutex_lock(&bundle->lock);
-	if (status != CELIX_SUCCESS) {
-		status = CELIX_BUNDLE_EXCEPTION;
-	} else {
-		bool equals;
-		status = thread_equalsSelf(bundle->lockThread, &equals);
-		if (status == CELIX_SUCCESS) {
-			*lockable = (bundle->lockCount == 0) || (equals);
-		}
-
-		status = celixThreadMutex_unlock(&bundle->lock);
-		if (status != CELIX_SUCCESS) {
-			status = CELIX_BUNDLE_EXCEPTION;
-		}
-	}
-
-	framework_logIfError(logger, status, NULL, "Failed to check if bundle is lockable");
-
-	return status;
-}
-
-celix_status_t bundle_getLockingThread(bundle_pt bundle, celix_thread_t *thread) {
-	celix_status_t status;
-
-	status = celixThreadMutex_lock(&bundle->lock);
-	if (status != CELIX_SUCCESS) {
-		status = CELIX_BUNDLE_EXCEPTION;
-	} else {
-		*thread = bundle->lockThread;
-
-		status = celixThreadMutex_unlock(&bundle->lock);
-		if (status != CELIX_SUCCESS) {
-			status = CELIX_BUNDLE_EXCEPTION;
-		}
-	}
-
-	framework_logIfError(logger, status, NULL, "Failed to get locking thread");
-
-	return status;
-}
-
-celix_status_t bundle_lock(bundle_pt bundle, bool *locked) {
-	celix_status_t status;
-	bool equals;
-
-	celixThreadMutex_lock(&bundle->lock);
-
-	status = thread_equalsSelf(bundle->lockThread, &equals);
-	if (status == CELIX_SUCCESS) {
-		if ((bundle->lockCount > 0) && !equals) {
-			*locked = false;
-		} else {
-			bundle->lockCount++;
-			bundle->lockThread = celixThread_self();
-			*locked = true;
-		}
-	}
-
-	celixThreadMutex_unlock(&bundle->lock);
-
-	framework_logIfError(logger, status, NULL, "Failed to lock bundle");
-
-	return status;
-}
-
-celix_status_t bundle_unlock(bundle_pt bundle, bool *unlocked) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	bool equals;
-
-	celixThreadMutex_lock(&bundle->lock);
-
-	if (bundle->lockCount == 0) {
-		*unlocked = false;
-	} else {
-		status = thread_equalsSelf(bundle->lockThread, &equals);
-		if (status == CELIX_SUCCESS) {
-			if ((bundle->lockCount > 0) && !equals) {
-				*unlocked = false;
-			}
-			else{
-			   bundle->lockCount--;
-			   if (bundle->lockCount == 0) {
-			   	bundle->lockThread = celix_thread_default;
-			   }
-			   *unlocked = true;
-		   }
-	   }
-	}
-
-	celixThreadMutex_unlock(&bundle->lock);
-
-	framework_logIfError(logger, status, NULL, "Failed to unlock bundle");
-
-	return status;
-}
-
-celix_status_t bundle_close(bundle_pt bundle) {
-	bundle_archive_pt archive = NULL;
-	
-	celix_status_t status;
-
-    bundle_closeModules(bundle);
-    bundle_closeRevisions(bundle);
-    status = bundle_getArchive(bundle, &archive);
-    if (status == CELIX_SUCCESS) {
-		bundleArchive_close(archive);
-    }
-
-	framework_logIfError(logger, status, NULL, "Failed to close bundle");
-
-    return status;
-}
-
-celix_status_t bundle_closeAndDelete(bundle_pt bundle) {
-	celix_status_t status;
-
-	bundle_archive_pt archive = NULL;
-
-    bundle_closeModules(bundle);
-    bundle_closeRevisions(bundle);
-    status = bundle_getArchive(bundle, &archive);
-    if (status == CELIX_SUCCESS) {
-    	bundleArchive_closeAndDelete(archive);
-    }
-
-	framework_logIfError(logger, status, NULL, "Failed to close and delete bundle");
-
-    return status;
-}
-
-celix_status_t bundle_closeRevisions(bundle_pt bundle) {
-    celix_status_t status = CELIX_SUCCESS;
-
-    // TODO implement this
-    return status;
-}
-
-celix_status_t bundle_closeModules(bundle_pt bundle) {
-    celix_status_t status = CELIX_SUCCESS;
-
-    unsigned int i = 0;
-    for (i = 0; i < arrayList_size(bundle->modules); i++) {
-        module_pt module = (module_pt) arrayList_get(bundle->modules, i);
-        resolver_removeModule(module);
-        module_setWires(module, NULL);
-    }
-
-    return status;
-}
-
-celix_status_t bundle_refresh(bundle_pt bundle) {
-	celix_status_t status;
-	module_pt module;
-
-	status = bundle_closeModules(bundle);
-	if (status == CELIX_SUCCESS) {
-		arrayList_clear(bundle->modules);
-		status = bundle_createModule(bundle, &module);
-		if (status == CELIX_SUCCESS) {
-			status = bundle_addModule(bundle, module);
-			if (status == CELIX_SUCCESS) {
-				bundle->state = OSGI_FRAMEWORK_BUNDLE_INSTALLED;
-			}
-		}
-	}
-
-	framework_logIfError(logger, status, NULL, "Failed to refresh bundle");
-
-    return status;
-}
-
-celix_status_t bundle_getBundleId(bundle_t *bundle, long *bndId) {
-	celix_status_t status = CELIX_SUCCESS;
-	long id = celix_bundle_getId(bundle);
-	if (id >= 0) {
-		*bndId = id;
-	} else {
-		status = CELIX_BUNDLE_EXCEPTION;
-		*bndId = -1;
-	}
-	return status;
-}
-
-celix_status_t bundle_getRegisteredServices(bundle_pt bundle, array_list_pt *list) {
-	celix_status_t status;
-
-	status = fw_getBundleRegisteredServices(bundle->framework, bundle, list);
-
-	framework_logIfError(bundle->framework->logger, status, NULL, "Failed to get registered services");
-
-	return status;
-}
-
-celix_status_t bundle_getServicesInUse(bundle_pt bundle, array_list_pt *list) {
-	celix_status_t status;
-
-	status = fw_getBundleServicesInUse(bundle->framework, bundle, list);
-
-	framework_logIfError(logger, status, NULL, "Failed to get in use services");
-
-	return status;
-}
-
-celix_status_t bundle_setFramework(bundle_pt bundle, framework_pt framework) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	if (bundle != NULL && framework != NULL) {
-		bundle->framework = framework;
-	} else {
-		status = CELIX_ILLEGAL_ARGUMENT;
-	}
-
-	framework_logIfError(logger, status, NULL, "Failed to set framework");
-
-	return status;
-}
-
-celix_status_t bundle_getFramework(bundle_pt bundle, framework_pt *framework) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	if (bundle != NULL && *framework == NULL) {
-		*framework = bundle->framework;
-	} else {
-		status = CELIX_ILLEGAL_ARGUMENT;
-	}
-
-	framework_logIfError(logger, status, NULL, "Failed to get framework");
-
-	return status;
-}
-
-celix_status_t bundle_getBundleLocation(bundle_pt bundle, const char **location){
-	celix_status_t status;
-
-	bundle_archive_pt archive = NULL;
-
-	status = bundle_getArchive(bundle, &archive);
-	if (status != CELIX_SUCCESS){
-		printf("[ ERROR ]: Bundle - getBundleLocation (BundleArchive) \n");
-		return status;
-	}
-
-	status =  bundleArchive_getLocation(archive, location);
-	if (status != CELIX_SUCCESS){
-		printf("[ ERROR ]:  Bundle - getBundleLocation (BundleArchiveLocation) \n");
-		return status;
-	}
-
-	return CELIX_SUCCESS;
-}
-
-
-celix_status_t bundle_getBundleCache(bundle_pt bundle, const char **out) {
-    celix_status_t status;
-    
-    const char *cache = NULL;
-    bundle_archive_pt archive = NULL;
-    bundle_revision_pt rev = NULL;
-    
-    status = bundle_getArchive(bundle, &archive);
-    if (status != CELIX_SUCCESS){
-        printf("[ ERROR ]: Bundle - bundle_getBundleCache (BundleArchive) \n");
-        return status;
-    }
-    
-    status = bundleArchive_getCurrentRevision(archive, &rev);
-    if (status != CELIX_SUCCESS){
-        printf("[ ERROR ]:  Bundle - bundle_getBundleCache (BundleArchiveRevision) \n");
-        return status;
-    }
-    
-    status = bundleRevision_getRoot(rev, &cache);
-    if (status != CELIX_SUCCESS){
-        printf("[ ERROR ]:  Bundle - bundle_getBundleCache (BundleArchiveRevision) \n");
-        return status;
-    }
-    
-    if (out != NULL) {
-        *out = cache;
-    }
-    
-    return CELIX_SUCCESS;
-}
-
-
-
-
-/**********************************************************************************************************************
- **********************************************************************************************************************
- * Updated API
- **********************************************************************************************************************
- **********************************************************************************************************************/
-
-long celix_bundle_getId(const bundle_t* bnd) {
-	long bndId = -1;
-	bundle_archive_pt archive = NULL;
-	if (bnd != NULL) {
-		bundle_getArchive((bundle_t *) bnd, &archive);
-	}
-	if (archive != NULL) {
-		bundleArchive_getId(archive, &bndId);
-	}
-	if (bndId < 0) {
-		framework_logIfError(logger, CELIX_BUNDLE_EXCEPTION, NULL, "Failed to get bundle id");
-	}
-	return bndId;
-}
-
-celix_bundle_state_e celix_bundle_getState(const bundle_t *bnd) {
-	celix_bundle_state_e state = OSGI_FRAMEWORK_BUNDLE_UNKNOWN;
-	if (bnd != NULL) {
-		state = bnd->state;
-	}
-	return state;
-}
-
-char* celix_bundle_getEntry(const bundle_t *bnd, const char *relPath) {
-	char *entry = NULL;
-	if (bnd != NULL) {
-		framework_getBundleEntry(bnd->framework, (bundle_t*)bnd, relPath, &entry);
-	}
-	return entry;
-}
-

http://git-wip-us.apache.org/repos/asf/celix/blob/4f438925/framework/src/bundle.c
----------------------------------------------------------------------
diff --git a/framework/src/bundle.c b/framework/src/bundle.c
new file mode 100644
index 0000000..cbdf794
--- /dev/null
+++ b/framework/src/bundle.c
@@ -0,0 +1,766 @@
+/**
+ *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 <stdlib.h>
+#include <string.h>
+
+#include "framework_private.h"
+#include "bundle_private.h"
+#include "resolver.h"
+#include "utils.h"
+#include "celix_bundle.h"
+
+celix_status_t bundle_createModule(bundle_pt bundle, module_pt *module);
+celix_status_t bundle_closeRevisions(bundle_pt bundle);
+
+celix_status_t bundle_create(bundle_pt * bundle) {
+    celix_status_t status;
+    bundle_archive_pt archive = NULL;
+
+	*bundle = (bundle_pt) malloc(sizeof(**bundle));
+	if (*bundle == NULL) {
+		return CELIX_ENOMEM;
+	}
+	status = bundleArchive_createSystemBundleArchive(&archive);
+	if (status == CELIX_SUCCESS) {
+        module_pt module;
+
+        (*bundle)->archive = archive;
+        (*bundle)->activator = NULL;
+        (*bundle)->context = NULL;
+        (*bundle)->framework = NULL;
+        (*bundle)->state = OSGI_FRAMEWORK_BUNDLE_INSTALLED;
+        (*bundle)->modules = NULL;
+        arrayList_create(&(*bundle)->modules);
+        (*bundle)->handle = NULL;
+        (*bundle)->manifest = NULL;
+
+        module = module_createFrameworkModule((*bundle));
+        bundle_addModule(*bundle, module);
+
+        status = celixThreadMutex_create(&(*bundle)->lock, NULL);
+        if (status != CELIX_SUCCESS) {
+        	status = CELIX_ILLEGAL_STATE;
+        } else {
+			(*bundle)->lockCount = 0;
+			(*bundle)->lockThread = celix_thread_default;
+        }
+	}
+	framework_logIfError(logger, status, NULL, "Failed to create bundle");
+
+	return status;
+}
+
+celix_status_t bundle_createFromArchive(bundle_pt * bundle, framework_pt framework, bundle_archive_pt archive) {
+    module_pt module;
+	
+	celix_status_t status;
+
+	*bundle = (bundle_pt) malloc(sizeof(**bundle));
+	if (*bundle == NULL) {
+		return CELIX_ENOMEM;
+	}
+	(*bundle)->archive = archive;
+	(*bundle)->activator = NULL;
+	(*bundle)->context = NULL;
+	(*bundle)->handle = NULL;
+	(*bundle)->manifest = NULL;
+	(*bundle)->framework = framework;
+	(*bundle)->state = OSGI_FRAMEWORK_BUNDLE_INSTALLED;
+	(*bundle)->modules = NULL;
+	arrayList_create(&(*bundle)->modules);
+	
+	status = bundle_createModule(*bundle, &module);
+	if (status == CELIX_SUCCESS) {
+		bundle_addModule(*bundle, module);
+        status = celixThreadMutex_create(&(*bundle)->lock, NULL);
+        if (status != CELIX_SUCCESS) {
+			status = CELIX_ILLEGAL_STATE;
+		} else {
+			(*bundle)->lockCount = 0;
+			(*bundle)->lockThread = celix_thread_default;
+		}
+	} else {
+	    status = CELIX_FILE_IO_EXCEPTION;
+	}
+
+	framework_logIfError(logger, status, NULL, "Failed to create bundle");
+
+	return status;
+}
+
+celix_status_t bundle_destroy(bundle_pt bundle) {
+	array_list_iterator_pt iter = arrayListIterator_create(bundle->modules);
+	while (arrayListIterator_hasNext(iter)) {
+		module_pt module = arrayListIterator_next(iter);
+		module_destroy(module);
+	}
+	arrayListIterator_destroy(iter);
+	arrayList_destroy(bundle->modules);
+	celixThreadMutex_destroy(&bundle->lock);
+
+	free(bundle);
+
+	return CELIX_SUCCESS;
+}
+
+celix_status_t bundle_getArchive(bundle_pt bundle, bundle_archive_pt *archive) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	if (bundle != NULL && *archive == NULL) {
+		*archive = bundle->archive;
+	} else {
+		status = CELIX_ILLEGAL_ARGUMENT;
+	}
+
+	framework_logIfError(logger, status, NULL, "Failed to get bundle archive");
+
+	return status;
+}
+
+celix_status_t bundle_getCurrentModule(bundle_pt bundle, module_pt *module) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	if (bundle == NULL || arrayList_size(bundle->modules)==0 ) {
+		status = CELIX_ILLEGAL_ARGUMENT;
+	} else {
+		*module = arrayList_get(bundle->modules, arrayList_size(bundle->modules) - 1);
+	}
+
+	return status;
+}
+
+array_list_pt bundle_getModules(bundle_pt bundle) {
+    return bundle->modules;
+}
+
+void * bundle_getHandle(bundle_pt bundle) {
+	return bundle->handle;
+}
+
+void bundle_setHandle(bundle_pt bundle, void * handle) {
+	bundle->handle = handle;
+}
+
+activator_pt bundle_getActivator(bundle_pt bundle) {
+	return bundle->activator;
+}
+
+celix_status_t bundle_setActivator(bundle_pt bundle, activator_pt activator) {
+	bundle->activator = activator;
+	return CELIX_SUCCESS;
+}
+
+celix_status_t bundle_getContext(bundle_pt bundle, bundle_context_pt *context) {
+	*context = bundle->context;
+	return CELIX_SUCCESS;
+}
+
+celix_status_t bundle_setContext(bundle_pt bundle, bundle_context_pt context) {
+	bundle->context = context;
+	return CELIX_SUCCESS;
+}
+
+celix_status_t bundle_getEntry(bundle_pt bundle, const char* name, char** out) {
+	char *entry = celix_bundle_getEntry(bundle, name);
+	if (out != NULL ) {
+		*out = entry;
+	}
+	return CELIX_SUCCESS;
+}
+
+celix_status_t bundle_getState(bundle_pt bundle, bundle_state_e *state) {
+	if(bundle==NULL){
+		*state = OSGI_FRAMEWORK_BUNDLE_UNKNOWN;
+		return CELIX_BUNDLE_EXCEPTION;
+	}
+	*state = bundle->state;
+	return CELIX_SUCCESS;
+}
+
+celix_status_t bundle_setState(bundle_pt bundle, bundle_state_e state) {
+	bundle->state = state;
+	return CELIX_SUCCESS;
+}
+
+celix_status_t bundle_createModule(bundle_pt bundle, module_pt *module) {
+	celix_status_t status = CELIX_SUCCESS;
+	bundle_archive_pt archive = NULL;
+	bundle_revision_pt revision = NULL;
+	manifest_pt headerMap = NULL;
+
+	status = CELIX_DO_IF(status, bundle_getArchive(bundle, &archive));
+	status = CELIX_DO_IF(status, bundleArchive_getCurrentRevision(archive, &revision));
+	status = CELIX_DO_IF(status, bundleRevision_getManifest(revision, &headerMap));
+	if (status == CELIX_SUCCESS) {
+		long bundleId = 0;
+        status = bundleArchive_getId(bundle->archive, &bundleId);
+        if (status == CELIX_SUCCESS) {
+			int revision = 0;
+			char moduleId[512];
+
+			snprintf(moduleId, sizeof(moduleId), "%ld.%d", bundleId, revision);
+			*module = module_create(headerMap, moduleId, bundle);
+
+			if (*module != NULL) {
+				version_pt bundleVersion = module_getVersion(*module);
+				const char * symName = NULL;
+				status = module_getSymbolicName(*module, &symName);
+				if (status == CELIX_SUCCESS) {
+					array_list_pt bundles = framework_getBundles(bundle->framework);
+					unsigned int i;
+					for (i = 0; i < arrayList_size(bundles); i++) {
+						bundle_pt check = (bundle_pt) arrayList_get(bundles, i);
+
+						long id;
+						if (bundleArchive_getId(check->archive, &id) == CELIX_SUCCESS) {
+							if (id != bundleId) {
+								module_pt mod = NULL;
+								const char * sym = NULL;
+								version_pt version;
+								int cmp;
+								status = bundle_getCurrentModule(check, &mod);
+								status = module_getSymbolicName(mod, &sym);
+
+								version = module_getVersion(mod);
+								version_compareTo(bundleVersion, version, &cmp);
+								if ((symName != NULL) && (sym != NULL) && !strcmp(symName, sym) &&
+										!cmp) {
+									char *versionString = NULL;
+									version_toString(version, &versionString);
+									printf("Bundle symbolic name and version are not unique: %s:%s\n", sym, versionString);
+									free(versionString);
+									status = CELIX_BUNDLE_EXCEPTION;
+									break;
+								}
+							}
+						}
+					}
+					arrayList_destroy(bundles);
+				}
+			}
+        }
+	}
+
+	framework_logIfError(logger, status, NULL, "Failed to create module");
+
+	return status;
+}
+
+celix_status_t bundle_start(bundle_pt bundle) {
+	return bundle_startWithOptions(bundle, 0);
+}
+
+celix_status_t bundle_startWithOptions(bundle_pt bundle, int options) {
+	celix_status_t status = CELIX_SUCCESS;
+    if (bundle != NULL) {
+    	bool systemBundle = false;
+    	status = bundle_isSystemBundle(bundle, &systemBundle);
+    	if (status == CELIX_SUCCESS) {
+    		if (systemBundle) {
+    			framework_start(bundle->framework);
+    		} else {
+    			status = fw_startBundle(bundle->framework, bundle, options);
+    		}
+    	}
+    }
+
+	framework_logIfError(logger, status, NULL, "Failed to start bundle");
+
+    return status;
+}
+
+celix_status_t bundle_update(bundle_pt bundle, const char *inputFile) {
+	celix_status_t status = CELIX_SUCCESS;
+	if (bundle != NULL) {
+		bool systemBundle = false;
+		status = bundle_isSystemBundle(bundle, &systemBundle);
+		if (status == CELIX_SUCCESS) {
+			if (systemBundle) {
+				// #TODO: Support framework update
+				status = CELIX_BUNDLE_EXCEPTION;
+			} else {
+				status = framework_updateBundle(bundle->framework, bundle, inputFile);
+			}
+		}
+	}
+
+	framework_logIfError(logger, status, NULL, "Failed to update bundle");
+
+	return status;
+}
+
+celix_status_t bundle_stop(bundle_pt bundle) {
+	return bundle_stopWithOptions(bundle, 0);
+}
+
+celix_status_t bundle_stopWithOptions(bundle_pt bundle, int options) {
+	celix_status_t status = CELIX_SUCCESS;
+	if (bundle != NULL) {
+		bool systemBundle = false;
+		status = bundle_isSystemBundle(bundle, &systemBundle);
+		if (status == CELIX_SUCCESS) {
+			if (systemBundle) {
+				framework_stop(bundle->framework);
+			} else {
+				status = fw_stopBundle(bundle->framework, bundle, options);
+			}
+		}
+	}
+
+	framework_logIfError(logger, status, NULL, "Failed to stop bundle");
+
+	return status;
+}
+
+celix_status_t bundle_uninstall(bundle_pt bundle) {
+	celix_status_t status = CELIX_SUCCESS;
+	if (bundle != NULL) {
+		bool systemBundle = false;
+		status = bundle_isSystemBundle(bundle, &systemBundle);
+		if (status == CELIX_SUCCESS) {
+			if (systemBundle) {
+				status = CELIX_BUNDLE_EXCEPTION;
+			} else {
+				status = fw_uninstallBundle(bundle->framework, bundle);
+			}
+		}
+	}
+
+	framework_logIfError(logger, status, NULL, "Failed to uninstall bundle");
+
+	return status;
+}
+
+celix_status_t bundle_setPersistentStateInactive(bundle_pt bundle) {
+	celix_status_t status;
+	bool systemBundle;
+
+	status = bundle_isSystemBundle(bundle, &systemBundle);
+	if (status == CELIX_SUCCESS) {
+		if (!systemBundle) {
+			status = bundleArchive_setPersistentState(bundle->archive, OSGI_FRAMEWORK_BUNDLE_INSTALLED);
+		}
+	}
+
+	framework_logIfError(logger, status, NULL, "Failed to set persistent state to inactive");
+
+	return status;
+}
+
+celix_status_t bundle_setPersistentStateUninstalled(bundle_pt bundle) {
+	celix_status_t status;
+	bool systemBundle;
+
+	status = bundle_isSystemBundle(bundle, &systemBundle);
+	if (status == CELIX_SUCCESS) {
+		if (!systemBundle) {
+			status = bundleArchive_setPersistentState(bundle->archive, OSGI_FRAMEWORK_BUNDLE_UNINSTALLED);
+		}
+	}
+
+	framework_logIfError(logger, status, NULL, "Failed to set persistent state to uninstalled");
+
+    return status;
+}
+
+celix_status_t bundle_revise(bundle_pt bundle, const char * location, const char *inputFile) {
+	celix_status_t status;
+
+	bundle_archive_pt archive = NULL;
+	status = bundle_getArchive(bundle, &archive);
+	if (status == CELIX_SUCCESS) {
+		status = bundleArchive_revise(archive, location, inputFile);
+		if (status == CELIX_SUCCESS) {
+			module_pt module;
+			status = bundle_createModule(bundle, &module);
+			if (status == CELIX_SUCCESS) {
+				status = bundle_addModule(bundle, module);
+			} else {
+				bool rolledback;
+				status = bundleArchive_rollbackRevise(archive, &rolledback);
+				if (status == CELIX_SUCCESS) {
+					status = CELIX_BUNDLE_EXCEPTION;
+				}
+			}
+		}
+	}
+
+	framework_logIfError(logger, status, NULL, "Failed to revise bundle");
+
+	return status;
+}
+
+//bool bundle_rollbackRevise(bundle_pt bundle) {
+//	module_pt module = arrayList_remove(bundle->modules, arrayList_set(bundle->modules) - 1);
+//	return resolver_removeModule(module);
+//}
+
+celix_status_t bundle_addModule(bundle_pt bundle, module_pt module) {
+	arrayList_add(bundle->modules, module);
+	resolver_addModule(module);
+	return CELIX_SUCCESS;
+}
+
+celix_status_t bundle_isSystemBundle(bundle_pt bundle, bool *systemBundle) {
+	celix_status_t status;
+	long bundleId;
+	bundle_archive_pt archive = NULL;
+
+	status = bundle_getArchive(bundle, &archive);
+	if (status == CELIX_SUCCESS) {
+		status = bundleArchive_getId(archive, &bundleId);
+		if (status == CELIX_SUCCESS) {
+			*systemBundle = (bundleId == 0);
+		}
+	}
+
+	framework_logIfError(logger, status, NULL, "Failed to check if bundle is the systembundle");
+
+	return status;
+}
+
+celix_status_t bundle_isLockable(bundle_pt bundle, bool *lockable) {
+	celix_status_t status;
+
+	status = celixThreadMutex_lock(&bundle->lock);
+	if (status != CELIX_SUCCESS) {
+		status = CELIX_BUNDLE_EXCEPTION;
+	} else {
+		bool equals;
+		status = thread_equalsSelf(bundle->lockThread, &equals);
+		if (status == CELIX_SUCCESS) {
+			*lockable = (bundle->lockCount == 0) || (equals);
+		}
+
+		status = celixThreadMutex_unlock(&bundle->lock);
+		if (status != CELIX_SUCCESS) {
+			status = CELIX_BUNDLE_EXCEPTION;
+		}
+	}
+
+	framework_logIfError(logger, status, NULL, "Failed to check if bundle is lockable");
+
+	return status;
+}
+
+celix_status_t bundle_getLockingThread(bundle_pt bundle, celix_thread_t *thread) {
+	celix_status_t status;
+
+	status = celixThreadMutex_lock(&bundle->lock);
+	if (status != CELIX_SUCCESS) {
+		status = CELIX_BUNDLE_EXCEPTION;
+	} else {
+		*thread = bundle->lockThread;
+
+		status = celixThreadMutex_unlock(&bundle->lock);
+		if (status != CELIX_SUCCESS) {
+			status = CELIX_BUNDLE_EXCEPTION;
+		}
+	}
+
+	framework_logIfError(logger, status, NULL, "Failed to get locking thread");
+
+	return status;
+}
+
+celix_status_t bundle_lock(bundle_pt bundle, bool *locked) {
+	celix_status_t status;
+	bool equals;
+
+	celixThreadMutex_lock(&bundle->lock);
+
+	status = thread_equalsSelf(bundle->lockThread, &equals);
+	if (status == CELIX_SUCCESS) {
+		if ((bundle->lockCount > 0) && !equals) {
+			*locked = false;
+		} else {
+			bundle->lockCount++;
+			bundle->lockThread = celixThread_self();
+			*locked = true;
+		}
+	}
+
+	celixThreadMutex_unlock(&bundle->lock);
+
+	framework_logIfError(logger, status, NULL, "Failed to lock bundle");
+
+	return status;
+}
+
+celix_status_t bundle_unlock(bundle_pt bundle, bool *unlocked) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	bool equals;
+
+	celixThreadMutex_lock(&bundle->lock);
+
+	if (bundle->lockCount == 0) {
+		*unlocked = false;
+	} else {
+		status = thread_equalsSelf(bundle->lockThread, &equals);
+		if (status == CELIX_SUCCESS) {
+			if ((bundle->lockCount > 0) && !equals) {
+				*unlocked = false;
+			}
+			else{
+			   bundle->lockCount--;
+			   if (bundle->lockCount == 0) {
+			   	bundle->lockThread = celix_thread_default;
+			   }
+			   *unlocked = true;
+		   }
+	   }
+	}
+
+	celixThreadMutex_unlock(&bundle->lock);
+
+	framework_logIfError(logger, status, NULL, "Failed to unlock bundle");
+
+	return status;
+}
+
+celix_status_t bundle_close(bundle_pt bundle) {
+	bundle_archive_pt archive = NULL;
+	
+	celix_status_t status;
+
+    bundle_closeModules(bundle);
+    bundle_closeRevisions(bundle);
+    status = bundle_getArchive(bundle, &archive);
+    if (status == CELIX_SUCCESS) {
+		bundleArchive_close(archive);
+    }
+
+	framework_logIfError(logger, status, NULL, "Failed to close bundle");
+
+    return status;
+}
+
+celix_status_t bundle_closeAndDelete(bundle_pt bundle) {
+	celix_status_t status;
+
+	bundle_archive_pt archive = NULL;
+
+    bundle_closeModules(bundle);
+    bundle_closeRevisions(bundle);
+    status = bundle_getArchive(bundle, &archive);
+    if (status == CELIX_SUCCESS) {
+    	bundleArchive_closeAndDelete(archive);
+    }
+
+	framework_logIfError(logger, status, NULL, "Failed to close and delete bundle");
+
+    return status;
+}
+
+celix_status_t bundle_closeRevisions(bundle_pt bundle) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    // TODO implement this
+    return status;
+}
+
+celix_status_t bundle_closeModules(bundle_pt bundle) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    unsigned int i = 0;
+    for (i = 0; i < arrayList_size(bundle->modules); i++) {
+        module_pt module = (module_pt) arrayList_get(bundle->modules, i);
+        resolver_removeModule(module);
+        module_setWires(module, NULL);
+    }
+
+    return status;
+}
+
+celix_status_t bundle_refresh(bundle_pt bundle) {
+	celix_status_t status;
+	module_pt module;
+
+	status = bundle_closeModules(bundle);
+	if (status == CELIX_SUCCESS) {
+		arrayList_clear(bundle->modules);
+		status = bundle_createModule(bundle, &module);
+		if (status == CELIX_SUCCESS) {
+			status = bundle_addModule(bundle, module);
+			if (status == CELIX_SUCCESS) {
+				bundle->state = OSGI_FRAMEWORK_BUNDLE_INSTALLED;
+			}
+		}
+	}
+
+	framework_logIfError(logger, status, NULL, "Failed to refresh bundle");
+
+    return status;
+}
+
+celix_status_t bundle_getBundleId(bundle_t *bundle, long *bndId) {
+	celix_status_t status = CELIX_SUCCESS;
+	long id = celix_bundle_getId(bundle);
+	if (id >= 0) {
+		*bndId = id;
+	} else {
+		status = CELIX_BUNDLE_EXCEPTION;
+		*bndId = -1;
+	}
+	return status;
+}
+
+celix_status_t bundle_getRegisteredServices(bundle_pt bundle, array_list_pt *list) {
+	celix_status_t status;
+
+	status = fw_getBundleRegisteredServices(bundle->framework, bundle, list);
+
+	framework_logIfError(bundle->framework->logger, status, NULL, "Failed to get registered services");
+
+	return status;
+}
+
+celix_status_t bundle_getServicesInUse(bundle_pt bundle, array_list_pt *list) {
+	celix_status_t status;
+
+	status = fw_getBundleServicesInUse(bundle->framework, bundle, list);
+
+	framework_logIfError(logger, status, NULL, "Failed to get in use services");
+
+	return status;
+}
+
+celix_status_t bundle_setFramework(bundle_pt bundle, framework_pt framework) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	if (bundle != NULL && framework != NULL) {
+		bundle->framework = framework;
+	} else {
+		status = CELIX_ILLEGAL_ARGUMENT;
+	}
+
+	framework_logIfError(logger, status, NULL, "Failed to set framework");
+
+	return status;
+}
+
+celix_status_t bundle_getFramework(bundle_pt bundle, framework_pt *framework) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	if (bundle != NULL && *framework == NULL) {
+		*framework = bundle->framework;
+	} else {
+		status = CELIX_ILLEGAL_ARGUMENT;
+	}
+
+	framework_logIfError(logger, status, NULL, "Failed to get framework");
+
+	return status;
+}
+
+celix_status_t bundle_getBundleLocation(bundle_pt bundle, const char **location){
+	celix_status_t status;
+
+	bundle_archive_pt archive = NULL;
+
+	status = bundle_getArchive(bundle, &archive);
+	if (status != CELIX_SUCCESS){
+		printf("[ ERROR ]: Bundle - getBundleLocation (BundleArchive) \n");
+		return status;
+	}
+
+	status =  bundleArchive_getLocation(archive, location);
+	if (status != CELIX_SUCCESS){
+		printf("[ ERROR ]:  Bundle - getBundleLocation (BundleArchiveLocation) \n");
+		return status;
+	}
+
+	return CELIX_SUCCESS;
+}
+
+
+celix_status_t bundle_getBundleCache(bundle_pt bundle, const char **out) {
+    celix_status_t status;
+    
+    const char *cache = NULL;
+    bundle_archive_pt archive = NULL;
+    bundle_revision_pt rev = NULL;
+    
+    status = bundle_getArchive(bundle, &archive);
+    if (status != CELIX_SUCCESS){
+        printf("[ ERROR ]: Bundle - bundle_getBundleCache (BundleArchive) \n");
+        return status;
+    }
+    
+    status = bundleArchive_getCurrentRevision(archive, &rev);
+    if (status != CELIX_SUCCESS){
+        printf("[ ERROR ]:  Bundle - bundle_getBundleCache (BundleArchiveRevision) \n");
+        return status;
+    }
+    
+    status = bundleRevision_getRoot(rev, &cache);
+    if (status != CELIX_SUCCESS){
+        printf("[ ERROR ]:  Bundle - bundle_getBundleCache (BundleArchiveRevision) \n");
+        return status;
+    }
+    
+    if (out != NULL) {
+        *out = cache;
+    }
+    
+    return CELIX_SUCCESS;
+}
+
+
+
+
+/**********************************************************************************************************************
+ **********************************************************************************************************************
+ * Updated API
+ **********************************************************************************************************************
+ **********************************************************************************************************************/
+
+long celix_bundle_getId(const bundle_t* bnd) {
+	long bndId = -1;
+	bundle_archive_pt archive = NULL;
+	if (bnd != NULL) {
+		bundle_getArchive((bundle_t *) bnd, &archive);
+	}
+	if (archive != NULL) {
+		bundleArchive_getId(archive, &bndId);
+	}
+	if (bndId < 0) {
+		framework_logIfError(logger, CELIX_BUNDLE_EXCEPTION, NULL, "Failed to get bundle id");
+	}
+	return bndId;
+}
+
+celix_bundle_state_e celix_bundle_getState(const bundle_t *bnd) {
+	celix_bundle_state_e state = OSGI_FRAMEWORK_BUNDLE_UNKNOWN;
+	if (bnd != NULL) {
+		state = bnd->state;
+	}
+	return state;
+}
+
+char* celix_bundle_getEntry(const bundle_t *bnd, const char *relPath) {
+	char *entry = NULL;
+	if (bnd != NULL) {
+		framework_getBundleEntry(bnd->framework, (bundle_t*)bnd, relPath, &entry);
+	}
+	return entry;
+}
+

http://git-wip-us.apache.org/repos/asf/celix/blob/4f438925/framework/src/bundle_context.c
----------------------------------------------------------------------
diff --git a/framework/src/bundle_context.c b/framework/src/bundle_context.c
index b7afe82..1173e4a 100644
--- a/framework/src/bundle_context.c
+++ b/framework/src/bundle_context.c
@@ -867,4 +867,8 @@ celix_array_list_t* celix_bundleContext_findServicesWithOptions(celix_bundle_con
     useOpts.useWithProperties = bundleContext_retrieveSvcIds;
     celix_bundleContext_useServicesWithOptions(ctx, &useOpts);
     return list;
+}
+
+celix_bundle_t* celix_bundleContext_getBundle(celix_bundle_context_t *ctx) {
+    return ctx->bundle;
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/4f438925/framework/src/framework.c
----------------------------------------------------------------------
diff --git a/framework/src/framework.c b/framework/src/framework.c
index c87eaf4..12e5030 100644
--- a/framework/src/framework.c
+++ b/framework/src/framework.c
@@ -2772,16 +2772,19 @@ void celix_framework_useBundles(framework_t *fw, void *callbackHandle, void(*use
     }
 }
 
-void celix_framework_useBundle(framework_t *fw, long bundleId, void *callbackHandle, void(*use)(void *handle, const bundle_t *bnd)) {
+bool celix_framework_useBundle(framework_t *fw, long bundleId, void *callbackHandle, void(*use)(void *handle, const bundle_t *bnd)) {
+    bool called = false;
     if (bundleId >= 0) {
         //TODO get bundle lock without throwing errors framework_acquireBundleLock() -> a more simple lock ??
         bundle_t *bnd = framework_getBundleById(fw, bundleId);
         celix_bundle_state_e bndState = celix_bundle_getState(bnd);
         if (bndState == OSGI_FRAMEWORK_BUNDLE_ACTIVE) {
             use(callbackHandle, bnd);
+            called = true;
         }
         //TODO unlock
     }
+    return called;
 }
 
 service_registration_t* celix_framework_registerServiceFactory(framework_t *fw , const celix_bundle_t *bnd, const char* serviceName, celix_service_factory_t *factory, celix_properties_t *properties) {

http://git-wip-us.apache.org/repos/asf/celix/blob/4f438925/framework/src/framework_private.h
----------------------------------------------------------------------
diff --git a/framework/src/framework_private.h b/framework/src/framework_private.h
index a04bbaa..e02e272 100644
--- a/framework/src/framework_private.h
+++ b/framework/src/framework_private.h
@@ -16,13 +16,6 @@
  *specific language governing permissions and limitations
  *under the License.
  */
-/*
- * framework_private.h
- *
- *  \date       May 22, 2013
- *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright  Apache License, Version 2.0
- */
 
 
 #ifndef FRAMEWORK_PRIVATE_H_
@@ -156,7 +149,7 @@ FRAMEWORK_EXPORT bundle_pt framework_getBundleById(framework_pt framework, long
  **********************************************************************************************************************/
 
 void celix_framework_useBundles(framework_t *fw, void *callbackHandle, void(*use)(void *handle, const bundle_t *bnd));
-void celix_framework_useBundle(framework_t *fw, long bundleId, void *callbackHandle, void(*use)(void *handle, const bundle_t *bnd));
+bool celix_framework_useBundle(framework_t *fw, long bundleId, void *callbackHandle, void(*use)(void *handle, const bundle_t *bnd));
 service_registration_t* celix_framework_registerServiceFactory(framework_t *fw , const celix_bundle_t *bnd, const char* serviceName, celix_service_factory_t *factory, celix_properties_t *properties);
 
 #endif /* FRAMEWORK_PRIVATE_H_ */


Mime
View raw message