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 2018/05/14 19:17:52 UTC

[01/12] celix git commit: CELIX-446: Renames services example to best practice and create a new services example for C.

Repository: celix
Updated Branches:
  refs/heads/feature/CELIX-426-cxx-api e3339ca42 -> 8464f3d5c


http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/framework/src/bundle_context.c
----------------------------------------------------------------------
diff --git a/framework/src/bundle_context.c b/framework/src/bundle_context.c
index b75b692..5a9bbd1 100644
--- a/framework/src/bundle_context.c
+++ b/framework/src/bundle_context.c
@@ -676,7 +676,7 @@ bool celix_bundleContext_useServiceWithId(
         long serviceId,
         const char *serviceName,
         void *callbackHandle,
-        void (*use)(void *handle, void *svc, const properties_t *props, const bundle_t *owner)) {
+        void (*use)(void *handle, void *svc)) {
     celix_service_use_options_t opts;
     memset(&opts, 0, sizeof(opts));
 
@@ -694,7 +694,7 @@ bool celix_bundleContext_useService(
         bundle_context_t *ctx,
         const char* serviceName,
         void *callbackHandle,
-        void (*use)(void *handle, void *svc, const properties_t *props, const bundle_t *owner)) {
+        void (*use)(void *handle, void *svc)) {
     celix_service_use_options_t opts;
     memset(&opts, 0, sizeof(opts));
     opts.serviceName = serviceName;
@@ -708,7 +708,7 @@ void celix_bundleContext_useServices(
         bundle_context_t *ctx,
         const char* serviceName,
         void *callbackHandle,
-        void (*use)(void *handle, void *svc, const properties_t *props, const bundle_t *owner)) {
+        void (*use)(void *handle, void *svc)) {
     celix_service_use_options_t opts;
     memset(&opts, 0, sizeof(opts));
     opts.serviceName = serviceName;
@@ -717,6 +717,7 @@ void celix_bundleContext_useServices(
     celix_bundleContext_useServicesWithOptions(ctx, &opts);
 }
 
+
 bool celix_bundleContext_useServiceWithOptions(
         celix_bundle_context_t *ctx,
         const celix_service_use_options_t *opts) {
@@ -732,7 +733,16 @@ bool celix_bundleContext_useServiceWithOptions(
 
         service_tracker_t *trk = celix_serviceTracker_createWithOptions(ctx, &trkOpts);
         if (trk != NULL) {
-            called = celix_serviceTracker_useHighestRankingService(trk, opts->serviceName, opts->callbackHandle, opts->use);
+            if (opts->use != NULL) {
+
+            }
+            if (opts->useWithProperties != NULL) {
+
+            }
+            if (opts->useWithOwner != NULL) {
+
+            }
+            called = celix_serviceTracker_useHighestRankingService(trk, opts->serviceName, opts->callbackHandle, opts->use, opts->useWithProperties, opts->useWithOwner);
             celix_serviceTracker_destroy(trk);
         }
     }
@@ -755,7 +765,7 @@ void celix_bundleContext_useServicesWithOptions(
 
         service_tracker_t *trk = celix_serviceTracker_createWithOptions(ctx, &trkOpts);
         if (trk != NULL) {
-            celix_serviceTracker_useServices(trk, opts->serviceName, opts->callbackHandle, opts->use);
+            celix_serviceTracker_useServices(trk, opts->serviceName, opts->callbackHandle, opts->use, opts->useWithProperties, opts->useWithOwner);
             celix_serviceTracker_destroy(trk);
         }
     }

http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/framework/src/service_tracker.c
----------------------------------------------------------------------
diff --git a/framework/src/service_tracker.c b/framework/src/service_tracker.c
index 194d9ac..c92efa3 100644
--- a/framework/src/service_tracker.c
+++ b/framework/src/service_tracker.c
@@ -332,7 +332,7 @@ static celix_status_t serviceTracker_track(service_tracker_pt tracker, service_r
             celixThreadRwlock_unlock(&tracker->lock);
 
             serviceTracker_invokeAddService(tracker, tracked);
-            celix_serviceTracker_useHighestRankingService(tracker, tracked->serviceName, tracker, serviceTracker_checkAndInvokeSetService);
+            celix_serviceTracker_useHighestRankingService(tracker, tracked->serviceName, tracker, NULL, NULL, serviceTracker_checkAndInvokeSetService);
             tracked_decreaseUse(tracked);
         }
     }
@@ -482,7 +482,7 @@ static celix_status_t serviceTracker_untrack(service_tracker_pt tracker, service
     if (size == 0) {
         serviceTracker_checkAndInvokeSetService(tracker, NULL, NULL, NULL);
     } else {
-        celix_serviceTracker_useHighestRankingService(tracker, serviceName, tracker, serviceTracker_checkAndInvokeSetService);
+        celix_serviceTracker_useHighestRankingService(tracker, serviceName, tracker, NULL, NULL, serviceTracker_checkAndInvokeSetService);
     }
 
     framework_logIfError(logger, status, NULL, "Cannot untrack reference");
@@ -645,7 +645,9 @@ bool celix_serviceTracker_useHighestRankingService(
         celix_service_tracker_t *tracker,
         const char *serviceName /*sanity*/,
         void *callbackHandle,
-        void (*use)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *owner)) {
+        void (*use)(void *handle, void *svc),
+        void (*useWithProperties)(void *handle, void *svc, const celix_properties_t *props),
+        void (*useWithOwner)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *owner)) {
     bool called = false;
     celix_tracked_entry_t *tracked = NULL;
     celix_tracked_entry_t *highest = NULL;
@@ -673,7 +675,15 @@ bool celix_serviceTracker_useHighestRankingService(
 
     if (highest != NULL) {
         //got service, call, decrease use count an signal useCond after.
-        use(callbackHandle, highest->service, highest->properties, highest->serviceOwner);
+        if (use != NULL) {
+            use(callbackHandle, highest->service);
+        }
+        if (useWithProperties != NULL) {
+            useWithProperties(callbackHandle, highest->service, highest->properties);
+        }
+        if (useWithOwner != NULL) {
+            useWithOwner(callbackHandle, highest->service, highest->properties, highest->serviceOwner);
+        }
         called = true;
         tracked_decreaseUse(highest);
     }
@@ -685,7 +695,9 @@ void celix_serviceTracker_useServices(
         service_tracker_t *tracker,
         const char* serviceName /*sanity*/,
         void *callbackHandle,
-        void (*use)(void *handle, void *svc, const properties_t *props, const bundle_t *owner)) {
+        void (*use)(void *handle, void *svc),
+        void (*useWithProperties)(void *handle, void *svc, const celix_properties_t *props),
+        void (*useWithOwner)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *owner)) {
     int i;
 
     //first lock tracker, get tracked entries and increase use count
@@ -704,7 +716,15 @@ void celix_serviceTracker_useServices(
     for (i = 0; i < size; i++) {
         celix_tracked_entry_t *entry = entries[i];
         //got service, call, decrease use count an signal useCond after.
-        use(callbackHandle, entry->service, entry->properties, entry->serviceOwner);
+        if (use != NULL) {
+            use(callbackHandle, entry->service);
+        }
+        if (useWithProperties != NULL) {
+            useWithProperties(callbackHandle, entry->service, entry->properties);
+        }
+        if (useWithOwner != NULL) {
+            useWithOwner(callbackHandle, entry->service, entry->properties, entry->serviceOwner);
+        }
 
         tracked_decreaseUse(entry);
     }

http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/framework/tst/bundle_context_services_test.cpp
----------------------------------------------------------------------
diff --git a/framework/tst/bundle_context_services_test.cpp b/framework/tst/bundle_context_services_test.cpp
index 7cbe057..790cbd2 100644
--- a/framework/tst/bundle_context_services_test.cpp
+++ b/framework/tst/bundle_context_services_test.cpp
@@ -98,10 +98,8 @@ TEST(CelixBundleContextServicesTests, registerMultipleAndUseServices) {
     long svcId3 = celix_bundleContext_registerService(ctx, calcName, &svc, NULL, NULL);
     CHECK(svcId3 >= 0);
 
-    auto use = [](void *handle, void *svc, const properties_t *props, const bundle_t *bnd) {
+    auto use = [](void *handle, void *svc) {
         CHECK(svc != NULL);
-        CHECK(props != NULL);
-        CHECK(bnd != NULL);
         int *total =  static_cast<int*>(handle);
         struct calc *calc = static_cast<struct calc*>(svc);
         int tmp = calc->calc(1);
@@ -142,10 +140,8 @@ TEST(CelixBundleContextServicesTests, registerAndUseService) {
     CHECK(svcId >= 0);
 
     int result = 0;
-    bool called = celix_bundleContext_useServiceWithId(ctx, svcId, calcName, &result, [](void *handle, void *svc, const properties_t *props, const bundle_t *bnd) {
+    bool called = celix_bundleContext_useServiceWithId(ctx, svcId, calcName, &result, [](void *handle, void *svc) {
         CHECK(svc != NULL);
-        CHECK(props != NULL);
-        CHECK(bnd != NULL);
         int *result =  static_cast<int*>(handle);
         struct calc *calc = static_cast<struct calc*>(svc);
         int tmp = calc->calc(2);
@@ -156,7 +152,7 @@ TEST(CelixBundleContextServicesTests, registerAndUseService) {
 
     result = 0;
     long nonExistingSvcId = 101;
-    called = celix_bundleContext_useServiceWithId(ctx, nonExistingSvcId, calcName, &result, [](void *handle, void *svc, const properties_t *, const bundle_t *) {
+    called = celix_bundleContext_useServiceWithId(ctx, nonExistingSvcId, calcName, &result, [](void *handle, void *svc) {
         int *result =  static_cast<int*>(handle);
         struct calc *calc = static_cast<struct calc*>(svc);
         int tmp = calc->calc(2);
@@ -192,10 +188,8 @@ TEST(CelixBundleContextServicesTests, registerAndUseWithForcedRaceCondition) {
     };
     struct sync callInfo{};
 
-    auto use = [](void *handle, void *svc, const properties_t *props, const bundle_t *bnd) {
+    auto use = [](void *handle, void *svc) {
         CHECK(svc != NULL);
-        CHECK(props != NULL);
-        CHECK(bnd != NULL);
 
         struct sync *h = static_cast<struct sync*>(handle);
 


[09/12] celix git commit: CELIX-446: Adds celix_bundleContext_registerServiceWithOptions api, refactors previous registerService api.

Posted by pn...@apache.org.
CELIX-446: Adds celix_bundleContext_registerServiceWithOptions api, refactors previous registerService api.


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

Branch: refs/heads/feature/CELIX-426-cxx-api
Commit: 3391d88d09956a5df09eece9b8ad37009bb30484
Parents: 3ba41ca
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Sun May 13 12:47:04 2018 +0200
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Sun May 13 12:47:04 2018 +0200

----------------------------------------------------------------------
 .../src/dynamic_provider_example.c              |   2 +-
 .../src/simple_provider_example.c               |   2 +-
 framework/include/bundle_context.h              | 117 ++++++++++++-------
 framework/private/mock/bundle_context_mock.c    |  29 +----
 framework/src/bundle_context.c                  |  64 +++++-----
 framework/tst/bundle_context_services_test.cpp  |  50 ++++----
 shell/src/activator.c                           |  12 +-
 7 files changed, 143 insertions(+), 133 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/3391d88d/examples/celix-examples/services_example_c/src/dynamic_provider_example.c
----------------------------------------------------------------------
diff --git a/examples/celix-examples/services_example_c/src/dynamic_provider_example.c b/examples/celix-examples/services_example_c/src/dynamic_provider_example.c
index 4127c4b..7a7d9d9 100644
--- a/examples/celix-examples/services_example_c/src/dynamic_provider_example.c
+++ b/examples/celix-examples/services_example_c/src/dynamic_provider_example.c
@@ -65,7 +65,7 @@ void * run(void *handle) {
         if (up) {
             properties_t *props = properties_create();
             celix_properties_setLong(props, OSGI_FRAMEWORK_SERVICE_RANKING, rand());
-            data->svcIds[i++] = celix_bundleContext_registerService(data->ctx, EXAMPLE_CALC_NAME, &data->svc, NULL, props);
+            data->svcIds[i++] = celix_bundleContext_registerService(data->ctx, &data->svc, EXAMPLE_CALC_NAME, props);
         } else { //down
             celix_bundleContext_unregisterService(data->ctx, data->svcIds[i]);
             data->svcIds[--i] = -1L;

http://git-wip-us.apache.org/repos/asf/celix/blob/3391d88d/examples/celix-examples/services_example_c/src/simple_provider_example.c
----------------------------------------------------------------------
diff --git a/examples/celix-examples/services_example_c/src/simple_provider_example.c b/examples/celix-examples/services_example_c/src/simple_provider_example.c
index 765a49e..3358903 100644
--- a/examples/celix-examples/services_example_c/src/simple_provider_example.c
+++ b/examples/celix-examples/services_example_c/src/simple_provider_example.c
@@ -54,7 +54,7 @@ celix_status_t bundleActivator_create(celix_bundle_context_t *ctx, void **out) {
 
 celix_status_t bundleActivator_start(void * handle, celix_bundle_context_t *ctx) {
     activator_data_t *data = handle;
-    data->svcId = celix_bundleContext_registerService(data->ctx, EXAMPLE_CALC_NAME, &data->svc, EXAMPLE_CALC_VERSION, NULL);
+    data->svcId = celix_bundleContext_registerService(data->ctx, &data->svc, EXAMPLE_CALC_NAME, NULL);
     printf("Registered calc service with service id %li\n", data->svcId);
 	return CELIX_SUCCESS;
 }

http://git-wip-us.apache.org/repos/asf/celix/blob/3391d88d/framework/include/bundle_context.h
----------------------------------------------------------------------
diff --git a/framework/include/bundle_context.h b/framework/include/bundle_context.h
index 5daaff9..93840b7 100644
--- a/framework/include/bundle_context.h
+++ b/framework/include/bundle_context.h
@@ -196,34 +196,83 @@ bundleContext_getPropertyWithDefault(bundle_context_pt context, const char *name
  */
 dm_dependency_manager_t* celix_bundleContext_getDependencyManager(celix_bundle_context_t *ctx);
 
+
+typedef struct celix_service_registration_options {
+    /**
+     * The service pointer. The actual pointer to the service. For C this is normally a pointer to a struct
+     * with function pointers, but theoretically this can be a pointer to anything (e.g. a pointer to a single function,
+     * or a pointer to a C++ interface implementation, or just a pointer to a data structure).
+     *
+     * The bundle is responsible to keep the service pointer valid as long as it is registered in the Celix framework.
+     */
+    void *svc;
+
+    /**
+     * The service factory pointer.
+     * Note if the factory service is set, the svc field will not be used.
+     *
+     * The service factory will be called for every bundle requesting/de-requesting a service. This gives the provider the
+     * option to create bundle specific service instances.
+     *
+     * When a service is requested for a bundle the getService of the factory service will be called. This function must
+     * return a valid pointer to a service conform the registered service name or NULL.
+     * When a service in no longer needed for a bundle (e.g. ending the useService(s) calls when a service tacker is stopped)
+     * the ungetService function of the service factory will be called.
+     *
+     * The bundle is responsible to keep the service factory pointer valid as long as it is registered in the Celix framework.
+     */
+    celix_service_factory_t *factory;
+
+    /**
+     * The required service name. This is used to identify the service. A fully qualified name with a namespace is
+     * advisable to prevent name collision. (e.g. EXAMPLE_PRESURE_SENSOR).
+     */
+    const char *serviceName;
+
+    /**
+     * The optional service properties. These contain meta information about the service in the
+     * form of string key/values. (e.g. the location of a pressure sensor: location=left-tire).
+     *
+     * When a service is registered the Celix framework will take ownership of the provided properties.
+     * If a registration fails, the properties will be destroyed (freed) by the Celix framework.
+     */
+     celix_properties_t *properties;
+
+     /**
+      * The optional service language. If this is NULL, CELIX_FRAMEWORK_SERVICE_LANGUAGE_C is used.
+      */
+      const char *serviceLanguage;
+
+      /**
+       * The optional service version (in the form of <MAJOR>.<MINOR>.<MICRO>.<QUALIFIER>).
+       * If present consumer of the service can specific which service version range of
+       * a specific service they are interested in. Note that it is the responsibility of the users to ensure that
+       * service in those version range are compatible (binary of source). It is advisable to use semantic versioning
+       * for this.
+       */
+      const char *serviceVersion;
+} celix_service_registration_options_t;
+
+#define CELIX_EMPTY_SERVICE_REGISTRATION_OPTIONS { .svc = NULL, \
+    .serviceName = NULL, \
+    .properties = NULL, \
+    .serviceLanguage = NULL, \
+    .serviceVersion = NULL }
+
 /**
  * Register a C lang service to the framework.
  *
  * @param ctx The bundle context
- * @param serviceName the service name, cannot be NULL
  * @param svc the service object. Normally a pointer to a service struct (e.g. a struct with function pointers)
- * @param serviceVersion The optional service version.
+ * @param serviceName the service name, cannot be NULL
  * @param properties The meta properties associated with the service. The service registration will take ownership of the properties (e.g. no destroy needed)
  * @return The serviceId, which should be >= 0. If < 0 then the registration was unsuccessful.
  */
-long celix_bundleContext_registerService(celix_bundle_context_t *ctx, const char *serviceName, void *svc, const char *serviceVersion, celix_properties_t *properties);
-
-/**
-* Register a service for the specified language to the framework.
-*
-* @param ctx The bundle context
-* @param serviceName the service name, cannot be NULL
-* @param svc Pointer to the service. Normally a pointer to a service struct (e.g. a struct with function pointers)
-* @param serviceVersion The optional service version.
-* @param lang The service language. Will be set to CELIX_FRAMEWORK_SERVICE_LANGUAGE_C if NULL is provided.
-* @param properties The meta properties associated with the service. The service registration will take ownership of the properties
-* @return The serviceId, which should >= 0. If < 0 then the registration was unsuccessful.
-*/
-long celix_bundleContext_registerServiceForLang(celix_bundle_context_t *ctx, const char *serviceName, void *svc, const char *serviceVersion, const char* lang, celix_properties_t *properties);
+long celix_bundleContext_registerService(celix_bundle_context_t *ctx, void *svc, const char *serviceName, celix_properties_t *properties);
 
 /**
  * Register a service factory in the framework (for the C language).
- * THe service factory will be called for every bundle requesting/de-requesting a service. This gives the provider the
+ * The service factory will be called for every bundle requesting/de-requesting a service. This gives the provider the
  * option to create bundle specific service instances.
  *
  * When a service is requested for a bundle the getService of the factory service will be called. This function must
@@ -232,33 +281,22 @@ long celix_bundleContext_registerServiceForLang(celix_bundle_context_t *ctx, con
  * the ungetService function of the service factory will be called.
  *
  * @param ctx The bundle context
- * @param serviceName The required service name of the services this factory will produce.
  * @param factory The pointer to the factory service.
- * @param serviceVersion The optional service version.
+ * @param serviceName The required service name of the services this factory will produce.
  * @param properties The optional service factory properties. For a service consumer this will be seen as the service properties.
  * @return The service id of the service factory or < 0 if the registration was unsuccessful.
  */
-long celix_bundleContext_registerServiceFactory(celix_bundle_context_t *ctx, const char *serviceName, celix_service_factory_t *factory, const char *serviceVersion, celix_properties_t *properties);
+long celix_bundleContext_registerServiceFactory(celix_bundle_context_t *ctx, celix_service_factory_t *factory, const char *serviceName, celix_properties_t *props);
 
 /**
- * Register a service factory in the framework.
- * THe service factory will be called for every bundle requesting/de-requesting a service. This gives the provider the
- * option to create bundle specific service instances.
- *
- * When a service is requested for a bundle the getService of the factory service will be called. This function must
- * return a valid pointer to a service conform the registered service name or NULL.
- * When a service in no longer needed for a bundle (e.g. ending the useService(s) calls when a service tacker is stopped)
- * the ungetService function of the service factory will be called.
- *
- * @param ctx The bundle context
- * @param serviceName The required service name of the services this factory will produce.
- * @param factory The pointer to the factory service.
- * @param serviceVersion The optional service version.
- * @param lang The d service language. Will be set to CELIX_FRAMEWORK_SERVICE_LANGUAGE_C if NULL is provided.
- * @param properties The optional service factory properties. For a service consumer this will be seen as the service properties.
- * @return The service id of the service factory or < 0 if the registration was unsuccessful.
- */
-long celix_bundleContext_registerServiceFactorForLang(celix_bundle_context_t *ctx, const char *serviceName, celix_service_factory_t *factory, const char *serviceVersion, const char *lang, celix_properties_t *properties);
+* Register a service Celix to the framework using the provded registration options.
+*
+* @param ctx The bundle context
+* @param opts The pointer to the registration options. The options are only in the during registration call.
+* @return The serviceId, which should >= 0. If < 0 then the registration was unsuccessful.
+*/
+long celix_bundleContext_registerServiceWithOptions(celix_bundle_context_t *ctx, const celix_service_registration_options_t *opts);
+
 
 /**
  * Unregister the service or service factory with service id.
@@ -565,8 +603,6 @@ bool celix_bundleContext_uninstallBundle(celix_bundle_context_t *ctx, long bundl
  * requested bundle tracker ootions.
  */
 typedef struct celix_bundle_tracker_options {
-    //TODO options to track framework & own bundle
-
     /**
      * Handle used in the tracker callbacks.
      */
@@ -612,7 +648,6 @@ long celix_bundleContext_trackBundlesWithOptions(
         const celix_bundle_tracker_options_t *opts
 );
 
-//TODO except framework & own bundle
 /**
  * track bundles
  * The add bundle callback will also be called for already installed bundles.

http://git-wip-us.apache.org/repos/asf/celix/blob/3391d88d/framework/private/mock/bundle_context_mock.c
----------------------------------------------------------------------
diff --git a/framework/private/mock/bundle_context_mock.c b/framework/private/mock/bundle_context_mock.c
index b763b5a..9d3fe85 100644
--- a/framework/private/mock/bundle_context_mock.c
+++ b/framework/private/mock/bundle_context_mock.c
@@ -194,24 +194,19 @@ celix_status_t bundleContext_getProperty(bundle_context_pt context, const char *
 	return mock_c()->returnValue().value.intValue;
 }
 
-long celix_bundleContext_registerService(bundle_context_t *ctx, const char *serviceName, void *svc, const char *serviceVersion, properties_t *properties) {
+long celix_bundleContext_registerService(bundle_context_t *ctx, void *svc, const char *serviceName, properties_t *properties) {
 	mock_c()->actualCall("celix_bundleContext_registerCService")
 			->withPointerParameters("ctx", ctx)
 			->withStringParameters("serviceName", serviceName)
 			->withPointerParameters("svc", svc)
-			->withPointerParameters("properties", properties)
-			->withStringParameters("serviceName", serviceVersion);
+			->withPointerParameters("properties", properties);
 	return mock_c()->returnValue().value.longIntValue;
 }
 
-long celix_bundleContext_registerServiceForLang(bundle_context_t *ctx, const char *serviceName, void *svc, const char *serviceVersion, const char* lang, properties_t *properties) {
-	mock_c()->actualCall("celix_bundleContext_registerServiceForLang")
+long celix_bundleContext_registerServiceWithOptions(celix_bundle_context_t *ctx, const celix_service_registration_options_t *opts) {
+	mock_c()->actualCall("celix_bundleContext_registerServiceWithOptions")
 			->withPointerParameters("ctx", ctx)
-			->withStringParameters("serviceName", serviceName)
-			->withConstPointerParameters("svc", svc)
-			->withPointerParameters("properties", properties)
-			->withStringParameters("serviceName", serviceVersion)
-			->withStringParameters("lang", lang);
+			->withConstPointerParameters("opts", opts);
 	return mock_c()->returnValue().value.longIntValue;
 }
 
@@ -327,23 +322,11 @@ void celix_bundleContext_useServicesWithOptions(
 			->withConstPointerParameters("opts", opts);
 }
 
-long celix_bundleContext_registerServiceFactory(celix_bundle_context_t *ctx, const char *serviceName, celix_service_factory_t *factory, const char *serviceVersion, celix_properties_t *props) {
+long celix_bundleContext_registerServiceFactory(celix_bundle_context_t *ctx, celix_service_factory_t *factory, const char *serviceName, celix_properties_t *props) {
 	mock_c()->actualCall("celix_bundleContext_registerServiceFactory")
 			->withPointerParameters("ctx", ctx)
 			->withStringParameters("serviceName", serviceName)
 			->withPointerParameters("factory", factory)
-			->withStringParameters("serviceVersion", serviceVersion)
-			->withPointerParameters("props", props);
-	return mock_c()->returnValue().value.longIntValue;
-}
-
-long celix_bundleContext_registerServiceFactorForLang(celix_bundle_context_t *ctx, const char *serviceName, celix_service_factory_t *factory, const char *serviceVersion, const char *lang, celix_properties_t *props) {
-	mock_c()->actualCall("celix_bundleContext_registerServiceFactorForLang")
-			->withPointerParameters("ctx", ctx)
-			->withStringParameters("serviceName", serviceName)
-			->withPointerParameters("factory", factory)
-			->withStringParameters("serviceVersion", serviceVersion)
-			->withStringParameters("lang", lang)
 			->withPointerParameters("props", props);
 	return mock_c()->returnValue().value.longIntValue;
 }

http://git-wip-us.apache.org/repos/asf/celix/blob/3391d88d/framework/src/bundle_context.c
----------------------------------------------------------------------
diff --git a/framework/src/bundle_context.c b/framework/src/bundle_context.c
index ffb1704..f79d101 100644
--- a/framework/src/bundle_context.c
+++ b/framework/src/bundle_context.c
@@ -425,29 +425,47 @@ celix_status_t bundleContext_getPropertyWithDefault(bundle_context_pt context, c
  **********************************************************************************************************************/
 
 
-long celix_bundleContext_registerService(bundle_context_t *ctx, const char *serviceName, void *svc, const char *serviceVersion, properties_t *properties) {
-    return celix_bundleContext_registerServiceForLang(ctx, serviceName, svc, serviceVersion, NULL, properties);
+long celix_bundleContext_registerService(bundle_context_t *ctx, void *svc, const char *serviceName, celix_properties_t *properties) {
+    celix_service_registration_options_t opts = CELIX_EMPTY_SERVICE_REGISTRATION_OPTIONS;
+    opts.svc = svc;
+    opts.serviceName = serviceName;
+    opts.properties = properties;
+    return celix_bundleContext_registerServiceWithOptions(ctx, &opts);
 }
 
 
-long celix_bundleContext_registerServiceForLang(bundle_context_t *ctx, const char *serviceName, void *svc, const char *serviceVersion, const char* lang, properties_t *properties) {
+long celix_bundleContext_registerServiceFactory(celix_bundle_context_t *ctx, celix_service_factory_t *factory, const char *serviceName, celix_properties_t *props) {
+    celix_service_registration_options_t opts = CELIX_EMPTY_SERVICE_REGISTRATION_OPTIONS;
+    opts.factory = factory;
+    opts.serviceName = serviceName;
+    opts.properties = props;
+    return celix_bundleContext_registerServiceWithOptions(ctx, &opts);
+}
+
+long celix_bundleContext_registerServiceWithOptions(bundle_context_t *ctx, const celix_service_registration_options_t *opts) {
     long svcId = -1;
     service_registration_t *reg = NULL;
-    if (properties == NULL) {
-        properties = properties_create();
+    celix_properties_t *props = opts->properties;
+    if (props == NULL) {
+        props = celix_properties_create();
     }
-    if (serviceVersion != NULL) {
-        properties_set(properties, CELIX_FRAMEWORK_SERVICE_VERSION, serviceVersion);
+    if (opts->serviceVersion != NULL && strncmp("", opts->serviceVersion, 1) != 0) {
+        celix_properties_set(props, CELIX_FRAMEWORK_SERVICE_VERSION, opts->serviceVersion);
     }
-    if (serviceName != NULL) {
-        properties_set(properties, CELIX_FRAMEWORK_SERVICE_LANGUAGE, lang == NULL ? CELIX_FRAMEWORK_SERVICE_C_LANGUAGE : lang);
-        bundleContext_registerService(ctx, serviceName, svc, properties, &reg);
+    const char *lang = opts->serviceLanguage != NULL && strncmp("", opts->serviceLanguage, 1) != 0 ? opts->serviceLanguage : CELIX_FRAMEWORK_SERVICE_C_LANGUAGE;
+    celix_properties_set(props, CELIX_FRAMEWORK_SERVICE_LANGUAGE, lang);
+    if (opts->serviceName != NULL && strncmp("", opts->serviceName, 1) != 0) {
+        if (opts->factory != NULL) {
+            reg = celix_framework_registerServiceFactory(ctx->framework, ctx->bundle, opts->serviceName, opts->factory, props);
+        } else {
+            bundleContext_registerService(ctx, opts->serviceName, opts->svc, props, &reg);
+        }
         svcId = serviceRegistration_getServiceId(reg); //save to call with NULL
     } else {
         framework_logIfError(logger, CELIX_ILLEGAL_ARGUMENT, NULL, "Required serviceName argument is NULL");
     }
     if (svcId < 0) {
-        properties_destroy(properties);
+        properties_destroy(props);
     } else {
         celixThreadMutex_lock(&ctx->mutex);
         arrayList_add(ctx->svcRegistrations, reg);
@@ -803,30 +821,6 @@ long celix_bundleContext_trackServicesWithOptions(bundle_context_t *ctx, const c
     return trackerId;
 }
 
-long celix_bundleContext_registerServiceFactory(celix_bundle_context_t *ctx, const char *serviceName, celix_service_factory_t *factory, const char *serviceVersion, celix_properties_t *props) {
-    return celix_bundleContext_registerServiceFactorForLang(ctx, serviceName, factory, serviceVersion, NULL, props);
-}
-
-long celix_bundleContext_registerServiceFactorForLang(celix_bundle_context_t *ctx, const char *serviceName, celix_service_factory_t *factory, const char *serviceVersion, const char *lang, celix_properties_t *props) {
-    if (props == NULL) {
-        props = celix_properties_create();
-    }
-    if (serviceVersion != NULL) {
-        celix_properties_set(props, CELIX_FRAMEWORK_SERVICE_VERSION, serviceVersion);
-    }
-    celix_properties_set(props, CELIX_FRAMEWORK_SERVICE_LANGUAGE, lang == NULL ? CELIX_FRAMEWORK_SERVICE_C_LANGUAGE : lang);
-    service_registration_t *reg = celix_framework_registerServiceFactory(ctx->framework, ctx->bundle, serviceName, factory, props);
-    long facId = serviceRegistration_getServiceId(reg); //save to call with NULL
-    if (facId < 0) {
-        properties_destroy(props);
-    } else {
-        celixThreadMutex_lock(&ctx->mutex);
-        arrayList_add(ctx->svcRegistrations, reg);
-        celixThreadMutex_unlock(&ctx->mutex);
-    }
-    return facId;
-}
-
 long celix_bundleContext_findService(celix_bundle_context_t *ctx, const char *serviceName) {
     celix_service_filter_options_t opts = CELIX_EMPTY_SERVICE_FILTER_OPTIONS;
     opts.serviceName = serviceName;

http://git-wip-us.apache.org/repos/asf/celix/blob/3391d88d/framework/tst/bundle_context_services_test.cpp
----------------------------------------------------------------------
diff --git a/framework/tst/bundle_context_services_test.cpp b/framework/tst/bundle_context_services_test.cpp
index ec7b92d..9162212 100644
--- a/framework/tst/bundle_context_services_test.cpp
+++ b/framework/tst/bundle_context_services_test.cpp
@@ -70,7 +70,7 @@ TEST(CelixBundleContextServicesTests, registerService) {
         return n * 42;
     };
 
-    long svcId = celix_bundleContext_registerService(ctx, calcName, &svc, NULL, NULL);
+    long svcId = celix_bundleContext_registerService(ctx, &svc, calcName, NULL);
     CHECK(svcId >= 0);
     celix_bundleContext_unregisterService(ctx, svcId);
 };
@@ -93,13 +93,13 @@ TEST(CelixBundleContextServicesTests, registerMultipleAndUseServices) {
         return n * 42;
     };
 
-    long svcId1 = celix_bundleContext_registerService(ctx, calcName, &svc, NULL, NULL);
+    long svcId1 = celix_bundleContext_registerService(ctx, &svc, calcName, NULL);
     CHECK(svcId1 >= 0);
 
-    long svcId2 = celix_bundleContext_registerService(ctx, calcName, &svc, NULL, NULL);
+    long svcId2 = celix_bundleContext_registerService(ctx, &svc, calcName, NULL);
     CHECK(svcId2 >= 0);
 
-    long svcId3 = celix_bundleContext_registerService(ctx, calcName, &svc, NULL, NULL);
+    long svcId3 = celix_bundleContext_registerService(ctx, &svc, calcName, NULL);
     CHECK(svcId3 >= 0);
 
     auto use = [](void *handle, void *svc) {
@@ -140,7 +140,7 @@ TEST(CelixBundleContextServicesTests, registerAndUseService) {
         return n * 42;
     };
 
-    long svcId = celix_bundleContext_registerService(ctx, calcName, &svc, NULL, NULL);
+    long svcId = celix_bundleContext_registerService(ctx, &svc, calcName, NULL);
     CHECK(svcId >= 0);
 
     int result = 0;
@@ -179,7 +179,7 @@ TEST(CelixBundleContextServicesTests, registerAndUseWithForcedRaceCondition) {
         return n * 42;
     };
 
-    long svcId = celix_bundleContext_registerService(ctx, calcName, &svc, NULL, NULL);
+    long svcId = celix_bundleContext_registerService(ctx, &svc, calcName, NULL);
     CHECK(svcId >= 0);
 
     struct sync {
@@ -265,11 +265,11 @@ TEST(CelixBundleContextServicesTests, servicesTrackerTest) {
     CHECK(trackerId > 0);
     CHECK_EQUAL(0, count);
 
-    long svcId1 = celix_bundleContext_registerService(ctx, "calc", (void*)0x100, NULL, NULL);
+    long svcId1 = celix_bundleContext_registerService(ctx, (void*)0x100, "calc", NULL);
     CHECK(svcId1 > 0);
     CHECK_EQUAL(1, count);
 
-    long svcId2 = celix_bundleContext_registerService(ctx, "calc", (void*)0x200, NULL, NULL);
+    long svcId2 = celix_bundleContext_registerService(ctx, (void*)0x200, "calc", NULL);
     CHECK(svcId2 > 0);
     CHECK_EQUAL(2, count);
 
@@ -318,8 +318,8 @@ TEST(CelixBundleContextServicesTests, servicesTrackerTestWithAlreadyRegisteredSe
         *c -= 1;
     };
 
-    long svcId1 = celix_bundleContext_registerService(ctx, "calc", (void*)0x010, NULL, NULL);
-    long svcId2 = celix_bundleContext_registerService(ctx, "calc", (void*)0x020, NULL, NULL);
+    long svcId1 = celix_bundleContext_registerService(ctx, (void*)0x010, "calc", NULL);
+    long svcId2 = celix_bundleContext_registerService(ctx, (void*)0x020, "calc", NULL);
 
 
 
@@ -327,11 +327,11 @@ TEST(CelixBundleContextServicesTests, servicesTrackerTestWithAlreadyRegisteredSe
     CHECK(trackerId > 0);
     CHECK_EQUAL(2, count);
 
-    long svcId3 = celix_bundleContext_registerService(ctx, "calc", (void*)0x100, NULL, NULL);
+    long svcId3 = celix_bundleContext_registerService(ctx, (void*)0x100, "calc", NULL);
     CHECK(svcId1 > 0);
     CHECK_EQUAL(3, count);
 
-    long svcId4 = celix_bundleContext_registerService(ctx, "calc", (void*)0x200, NULL, NULL);
+    long svcId4 = celix_bundleContext_registerService(ctx, (void*)0x200, "calc", NULL);
     CHECK(svcId2 > 0);
     CHECK_EQUAL(4, count);
 
@@ -359,7 +359,7 @@ TEST(CelixBundleContextServicesTests, servicesTrackerTestWithProperties) {
         *c -= 1;
     };
 
-    long svcId1 = celix_bundleContext_registerService(ctx, "calc", (void*)0x100, NULL, NULL);
+    long svcId1 = celix_bundleContext_registerService(ctx, (void*)0x100, "calc", NULL);
 
     celix_service_tracking_options_t opts;
     memset(&opts, 0, sizeof(opts));
@@ -371,7 +371,7 @@ TEST(CelixBundleContextServicesTests, servicesTrackerTestWithProperties) {
     CHECK(trackerId > 0);
     CHECK_EQUAL(1, count);
 
-    long svcId2 = celix_bundleContext_registerService(ctx, "calc", (void*)0x200, NULL, NULL);
+    long svcId2 = celix_bundleContext_registerService(ctx, (void*)0x200, "calc", NULL);
     CHECK(svcId1 > 0);
     CHECK_EQUAL(2, count);
 
@@ -399,7 +399,7 @@ TEST(CelixBundleContextServicesTests, servicesTrackerTestWithOwner) {
         *c -= 1;
     };
 
-    long svcId1 = celix_bundleContext_registerService(ctx, "calc", (void*)0x100, NULL, NULL);
+    long svcId1 = celix_bundleContext_registerService(ctx, (void*)0x100, "calc", NULL);
 
     celix_service_tracking_options_t opts;
     memset(&opts, 0, sizeof(opts));
@@ -411,7 +411,7 @@ TEST(CelixBundleContextServicesTests, servicesTrackerTestWithOwner) {
     CHECK(trackerId > 0);
     CHECK_EQUAL(1, count);
 
-    long svcId2 = celix_bundleContext_registerService(ctx, "calc", (void*)0x200, NULL, NULL);
+    long svcId2 = celix_bundleContext_registerService(ctx, (void*)0x200, "calc", NULL);
     CHECK(svcId1 > 0);
     CHECK_EQUAL(2, count);
 
@@ -479,7 +479,7 @@ TEST(CelixBundleContextServicesTests, serviceTrackerWithRaceConditionTest) {
     long trackerId = celix_bundleContext_trackServices(ctx, calcName, &data, add, remove);
 
     std::thread registerThread{[&]{
-        long id = celix_bundleContext_registerService(ctx, calcName, &svc, NULL, NULL);
+        long id = celix_bundleContext_registerService(ctx, &svc, calcName, NULL);
         std::cout << "registered service with id " << id << std::endl;
         std::lock_guard<std::mutex> lock{data.mutex};
         data.svcId = id;
@@ -552,8 +552,8 @@ TEST(CelixBundleContextServicesTests, servicesTrackerSetTest) {
         *c = callCount;
     };
 
-    long svcId1 = celix_bundleContext_registerService(ctx, "NA", svc1, NULL, NULL);
-    long svcId2 = celix_bundleContext_registerService(ctx, "NA", svc2, NULL, NULL);
+    long svcId1 = celix_bundleContext_registerService(ctx, svc1, "NA", NULL);
+    long svcId2 = celix_bundleContext_registerService(ctx, svc2, "NA", NULL);
 
     //starting tracker should lead to first set call
     celix_service_tracking_options_t opts;
@@ -567,12 +567,12 @@ TEST(CelixBundleContextServicesTests, servicesTrackerSetTest) {
     //register svc3 should lead to second set call
     properties_t *props3 = celix_properties_create();
     celix_properties_set(props3, OSGI_FRAMEWORK_SERVICE_RANKING, "10");
-    long svcId3 = celix_bundleContext_registerService(ctx, "NA", svc3, NULL, props3);
+    long svcId3 = celix_bundleContext_registerService(ctx, svc3, "NA", props3);
 
     //register svc4 should lead to no set (lower ranking)
     properties_t *props4 = celix_properties_create();
     celix_properties_set(props4, OSGI_FRAMEWORK_SERVICE_RANKING, "10");
-    long svcId4 = celix_bundleContext_registerService(ctx, "NA", svc4, NULL, props4);
+    long svcId4 = celix_bundleContext_registerService(ctx, svc4, "NA", props4);
 
     //unregister svc3 should lead to set (new highest ranking)
     celix_bundleContext_unregisterService(ctx, svcId3);
@@ -593,8 +593,6 @@ TEST(CelixBundleContextServicesTests, serviceFactoryTest) {
         int (*calc)(int);
     };
     auto name = "CALC";
-    auto version = "1.0.0";
-
 
     int count = 0;
     celix_service_factory_t fac;
@@ -612,7 +610,7 @@ TEST(CelixBundleContextServicesTests, serviceFactoryTest) {
         *c += 1;
     };
 
-    long facId = celix_bundleContext_registerServiceFactory(ctx, name, &fac, version, NULL);
+    long facId = celix_bundleContext_registerServiceFactory(ctx, &fac, name, NULL);
     CHECK_TRUE(facId >= 0);
 
 
@@ -631,8 +629,8 @@ TEST(CelixBundleContextServicesTests, serviceFactoryTest) {
 }
 
 TEST(CelixBundleContextServicesTests, findServicesTest) {
-    long svcId1 = celix_bundleContext_registerService(ctx, "example", (void*)0x100, NULL, NULL);
-    long svcId2 = celix_bundleContext_registerService(ctx, "example", (void*)0x100, NULL, NULL);
+    long svcId1 = celix_bundleContext_registerService(ctx, (void*)0x100, "example", NULL);
+    long svcId2 = celix_bundleContext_registerService(ctx, (void*)0x100, "example", NULL);
 
     long foundId = celix_bundleContext_findService(ctx, "non existing service name");
     CHECK_EQUAL(-1L, foundId);

http://git-wip-us.apache.org/repos/asf/celix/blob/3391d88d/shell/src/activator.c
----------------------------------------------------------------------
diff --git a/shell/src/activator.c b/shell/src/activator.c
index b5b8e6e..16923cf 100644
--- a/shell/src/activator.c
+++ b/shell/src/activator.c
@@ -211,12 +211,12 @@ celix_status_t bundleActivator_start(void *_ptr, bundle_context_pt context_ptr)
 
     if (status == CELIX_SUCCESS) {
         for (unsigned int i = 0; instance_ptr->std_commands[i].exec != NULL; i++) {
-            instance_ptr->std_commands[i].svcId = celix_bundleContext_registerService(
-                    context_ptr,
-                    OSGI_SHELL_COMMAND_SERVICE_NAME,
-                    instance_ptr->std_commands[i].service,
-                    OSGI_SHELL_COMMAND_SERVICE_VERSION,
-                    instance_ptr->std_commands[i].props);
+            celix_service_registration_options_t opts = CELIX_EMPTY_SERVICE_REGISTRATION_OPTIONS;
+            opts.svc = instance_ptr->std_commands[i].service;
+            opts.serviceName = OSGI_SHELL_COMMAND_SERVICE_NAME;
+            opts.serviceVersion = OSGI_SHELL_COMMAND_SERVICE_VERSION;
+            opts.properties = instance_ptr->std_commands[i].props;
+            instance_ptr->std_commands[i].svcId = celix_bundleContext_registerServiceWithOptions(context_ptr, &opts);
         }
 	}
 


[07/12] celix git commit: CELIX-446: Fixes a forgotten (gcc only) example function

Posted by pn...@apache.org.
CELIX-446: Fixes a forgotten (gcc only) example function


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

Branch: refs/heads/feature/CELIX-426-cxx-api
Commit: d7546831aa063a69aa9e592cd7a4634e2c6cd4bc
Parents: 48aada3
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Fri May 11 15:23:37 2018 +0200
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Fri May 11 15:23:37 2018 +0200

----------------------------------------------------------------------
 .../services_example_c/src/dynamic_consumer_example.c         | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/d7546831/examples/celix-examples/services_example_c/src/dynamic_consumer_example.c
----------------------------------------------------------------------
diff --git a/examples/celix-examples/services_example_c/src/dynamic_consumer_example.c b/examples/celix-examples/services_example_c/src/dynamic_consumer_example.c
index 7a7f177..b935271 100644
--- a/examples/celix-examples/services_example_c/src/dynamic_consumer_example.c
+++ b/examples/celix-examples/services_example_c/src/dynamic_consumer_example.c
@@ -75,11 +75,10 @@ static void gccExample(activator_data_t *data) {
         result = calc->calc(calc->handle, 1);
     }
 
-    celix_service_use_options_t opts;
-    memset(&opts, 0, sizeof(opts));
+    celix_service_use_options_t opts = CELIX_EMPTY_SERVICE_USE_OPTIONS;
 
-    opts.serviceName = EXAMPLE_CALC_NAME;
-    opts.callbackHandle = NULL; //can be null for trampolines
+    opts.filter.serviceName = EXAMPLE_CALC_NAME;
+    opts.callbackHandle = NULL; //can be null
     opts.useWithProperties = use;
     bool called = celix_bundleContext_useServiceWithOptions(data->ctx, &opts);
 


[06/12] celix git commit: CELIX-446: Adds celix_bundleContext_findService(s) implementation. Also adds support setting/getting different primitive types for the celix array list.

Posted by pn...@apache.org.
CELIX-446: Adds celix_bundleContext_findService(s) implementation. Also adds support setting/getting different primitive types for the celix array list.


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

Branch: refs/heads/feature/CELIX-426-cxx-api
Commit: 48aada3abace985b22adbe082f9e754028d6362c
Parents: ae09682
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Fri May 11 14:58:13 2018 +0200
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Fri May 11 14:58:13 2018 +0200

----------------------------------------------------------------------
 .../src/dynamic_consumer_example.c              |   9 +-
 .../src/dynamic_provider_example.c              |   7 +-
 framework/include/bundle_context.h              |  93 +++++++++---
 framework/private/mock/bundle_context_mock.c    |  30 ++++
 framework/src/bundle_context.c                  |  94 ++++++++----
 framework/src/service_tracker.c                 |  32 ++--
 framework/tst/bundle_context_services_test.cpp  |  35 ++++-
 utils/include/array_list.h                      |  43 +++++-
 utils/src/array_list.c                          | 152 +++++++++++++------
 utils/src/array_list_private.h                  |   2 +-
 10 files changed, 370 insertions(+), 127 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/48aada3a/examples/celix-examples/services_example_c/src/dynamic_consumer_example.c
----------------------------------------------------------------------
diff --git a/examples/celix-examples/services_example_c/src/dynamic_consumer_example.c b/examples/celix-examples/services_example_c/src/dynamic_consumer_example.c
index 5a676d6..7a7f177 100644
--- a/examples/celix-examples/services_example_c/src/dynamic_consumer_example.c
+++ b/examples/celix-examples/services_example_c/src/dynamic_consumer_example.c
@@ -112,8 +112,8 @@ void * run(void *handle) {
     activator_data_t *data = handle;
 
     printf("starting consumer thread\n");
-    celix_service_tracking_options_t opts;
-    opts.serviceName = EXAMPLE_CALC_NAME;
+    celix_service_tracking_options_t opts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS;
+    opts.filter.serviceName = EXAMPLE_CALC_NAME;
     opts.callbackHandle = data;
     opts.addWithProperties = (void*)addSvc;
     opts.removeWithProperties = (void*)removeSvc;
@@ -128,10 +128,9 @@ void * run(void *handle) {
 
         gccExample(data); //gcc trampolines example (nested functions)
 
-        celix_service_use_options_t opts;
-        memset(&opts, 0, sizeof(opts));
+        celix_service_use_options_t opts = CELIX_EMPTY_SERVICE_USE_OPTIONS;
 
-        opts.serviceName = EXAMPLE_CALC_NAME;
+        opts.filter.serviceName = EXAMPLE_CALC_NAME;
         opts.callbackHandle = data;
         opts.useWithProperties = (void*)useHighest;
         celix_bundleContext_useServiceWithOptions(data->ctx, &opts);

http://git-wip-us.apache.org/repos/asf/celix/blob/48aada3a/examples/celix-examples/services_example_c/src/dynamic_provider_example.c
----------------------------------------------------------------------
diff --git a/examples/celix-examples/services_example_c/src/dynamic_provider_example.c b/examples/celix-examples/services_example_c/src/dynamic_provider_example.c
index f322303..4127c4b 100644
--- a/examples/celix-examples/services_example_c/src/dynamic_provider_example.c
+++ b/examples/celix-examples/services_example_c/src/dynamic_provider_example.c
@@ -67,7 +67,8 @@ void * run(void *handle) {
             celix_properties_setLong(props, OSGI_FRAMEWORK_SERVICE_RANKING, rand());
             data->svcIds[i++] = celix_bundleContext_registerService(data->ctx, EXAMPLE_CALC_NAME, &data->svc, NULL, props);
         } else { //down
-            celix_bundleContext_unregisterService(data->ctx, data->svcIds[i--]);
+            celix_bundleContext_unregisterService(data->ctx, data->svcIds[i]);
+            data->svcIds[--i] = -1L;
         }
         if (i == 99) {
             up = false;
@@ -79,9 +80,7 @@ void * run(void *handle) {
 
     for (int i = 0; i < 100; ++i) {
         long id = data->svcIds[i];
-        if (id >=0 ) {
-            celix_bundleContext_unregisterService(data->ctx, id);
-        }
+        celix_bundleContext_unregisterService(data->ctx, id);
     }
 
     printf("exiting service register thread\n");

http://git-wip-us.apache.org/repos/asf/celix/blob/48aada3a/framework/include/bundle_context.h
----------------------------------------------------------------------
diff --git a/framework/include/bundle_context.h b/framework/include/bundle_context.h
index 44cca39..5daaff9 100644
--- a/framework/include/bundle_context.h
+++ b/framework/include/bundle_context.h
@@ -272,13 +272,51 @@ long celix_bundleContext_registerServiceFactorForLang(celix_bundle_context_t *ct
 void celix_bundleContext_unregisterService(celix_bundle_context_t *ctx, long serviceId);
 
 
-//TODO 
-//typedef struct celix_service_find_filter_options {
-// servicname, versionrange, filter, lang
-//} celix_service_find_filter_options_t;
-//celix_array_list_t* celix_bundleContext_findServices(celix_bundle_context_t *ctx, const char *serviceName);
-//celix_array_list_t* celix_bundleContext_findServices(celix_bundle_context_t *ctx, const char *serviceName);
-//alts WithOptions
+typedef struct celix_service_filter_options {
+    const char* serviceName; //REQUIRED
+    const char* versionRange;
+    const char* filter;
+    const char* lang; //NULL -> 'CELIX_LANG_C'
+} celix_service_filter_options_t;
+
+#define CELIX_EMPTY_SERVICE_FILTER_OPTIONS {.serviceName = NULL, .versionRange = NULL, .filter = NULL, .lang = NULL}
+
+
+/**
+ * Finds the highest ranking service and returns the service id.
+ *
+ * @param ctx The bundle context
+ * @param serviceName The required service name
+ * @return If found a valid service id (>= 0) if not found -1.
+ */
+long celix_bundleContext_findService(celix_bundle_context_t *ctx, const char *serviceName);
+
+/**
+ * Finds the highest ranking service and returns the service id.
+ *
+ * @param ctx The bundle context
+ * @param opts The pointer to the filter options.
+ * @return If found a valid service id (>= 0) if not found -1.
+ */
+long celix_bundleContext_findServiceWithOptions(celix_bundle_context_t *ctx, const celix_service_filter_options_t *opts);
+
+/**
+ * Finds the services with the provided service name and returns a list of the found service ids.
+ *
+ * @param ctx The bundle context
+ * @param serviceName The required service name
+ * @return A array list with as value a long int.
+ */
+celix_array_list_t* celix_bundleContext_findServices(celix_bundle_context_t *ctx, const char *serviceName);
+
+/**
+ * Finds the services conform the provider filter options and returns a list of the found service ids.
+ *
+ * @param ctx The bundle context
+ * @param opts The pointer to the filter options.
+ * @return A array list with as value a long int.
+ */
+celix_array_list_t* celix_bundleContext_findServicesWithOptions(celix_bundle_context_t *ctx, const celix_service_filter_options_t *opts);
 
 
 /**
@@ -323,11 +361,7 @@ long celix_bundleContext_trackServices(
 );
 
 typedef struct celix_service_tracker_options {
-    //service filter options
-    const char* serviceName;
-    const char* versionRange;
-    const char* filter;
-    const char* lang; //NULL -> 'CELIX_LANG_C'
+    celix_service_filter_options_t filter;
 
     //callback options
     void* callbackHandle;
@@ -335,19 +369,31 @@ typedef struct celix_service_tracker_options {
     void (*set)(void *handle, void *svc); //highest ranking
     void (*add)(void *handle, void *svc);
     void (*remove)(void *handle, void *svc);
-    void (*modified)(void *handle, void *svc);
 
     void (*setWithProperties)(void *handle, void *svc, const celix_properties_t *props); //highest ranking
     void (*addWithProperties)(void *handle, void *svc, const celix_properties_t *props);
     void (*removeWithProperties)(void *handle, void *svc, const celix_properties_t *props);
-    void (*modifiedWithProperties)(void *handle, void *svc, const celix_properties_t *props);
 
     void (*setWithOwner)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *svcOwner); //highest ranking
     void (*addWithOwner)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *svcOwner);
     void (*removeWithOwner)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *svcOwner);
-    void (*modifiedWithOwner)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *svcOwner);
 } celix_service_tracking_options_t;
 
+#define CELIX_EMPTY_SERVICE_TRACKING_OPTIONS { .filter.serviceName = NULL, \
+    .filter.versionRange = NULL, \
+    .filter.filter = NULL, \
+    .filter.lang = NULL, \
+    .callbackHandle = NULL, \
+    .set = NULL, \
+    .add = NULL, \
+    .remove = NULL, \
+    .setWithProperties = NULL, \
+    .addWithProperties = NULL, \
+    .removeWithProperties = NULL, \
+    .setWithOwner = NULL, \
+    .addWithOwner = NULL, \
+    .removeWithOwner = NULL}
+
 /**
  * Tracks services using the provided tracker options.
  * The tracker options are only using during this call and can safely be freed/reused after this call returns.
@@ -431,13 +477,7 @@ void celix_bundleContext_useServices(
 
 
 typedef struct celix_service_use_options {
-    /**
-     * service filter options. Note the serviceName is required.
-     */
-    const char *serviceName; //REQUIRED
-    const char *versionRange; //default will be empty
-    const char *filter; //default will be empty
-    const char *lang; //default will be LANG_C
+    celix_service_filter_options_t filter;
 
     /**
      * Callback info
@@ -449,6 +489,15 @@ typedef struct celix_service_use_options {
      void (*useWithOwner)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *svcOwner);
 } celix_service_use_options_t;
 
+#define CELIX_EMPTY_SERVICE_USE_OPTIONS {.filter.serviceName = NULL, \
+    .filter.versionRange = NULL, \
+    .filter.filter = NULL, \
+    .filter.lang = NULL, \
+    .callbackHandle = NULL, \
+    .use = NULL, \
+    .useWithProperties = NULL, \
+    .useWithOwner = NULL}
+
 /**
  * Get and lock the current highest ranking service conform the service filter info from the provided options.
  *

http://git-wip-us.apache.org/repos/asf/celix/blob/48aada3a/framework/private/mock/bundle_context_mock.c
----------------------------------------------------------------------
diff --git a/framework/private/mock/bundle_context_mock.c b/framework/private/mock/bundle_context_mock.c
index 749e3ca..b763b5a 100644
--- a/framework/private/mock/bundle_context_mock.c
+++ b/framework/private/mock/bundle_context_mock.c
@@ -346,4 +346,34 @@ long celix_bundleContext_registerServiceFactorForLang(celix_bundle_context_t *ct
 			->withStringParameters("lang", lang)
 			->withPointerParameters("props", props);
 	return mock_c()->returnValue().value.longIntValue;
+}
+
+long celix_bundleContext_findService(celix_bundle_context_t *ctx, const char *serviceName) {
+	mock_c()->actualCall("celix_bundleContext_findService")
+			->withPointerParameters("ctx", ctx)
+			->withStringParameters("serviceName", serviceName);
+	return mock_c()->returnValue().value.longIntValue;
+}
+
+
+long celix_bundleContext_findServiceWithOptions(celix_bundle_context_t *ctx, const celix_service_filter_options_t *opts) {
+	mock_c()->actualCall("celix_bundleContext_findServiceWithOptions")
+			->withPointerParameters("ctx", ctx)
+			->withConstPointerParameters("opts", opts);
+	return mock_c()->returnValue().value.longIntValue;
+}
+
+
+celix_array_list_t* celix_bundleContext_findServices(celix_bundle_context_t *ctx, const char *serviceName) {
+	mock_c()->actualCall("celix_bundleContext_findServices")
+			->withPointerParameters("ctx", ctx)
+			->withStringParameters("serviceName", serviceName);
+	return mock_c()->returnValue().value.pointerValue;
+}
+
+celix_array_list_t* celix_bundleContext_findServicesWithOptions(celix_bundle_context_t *ctx, const celix_service_filter_options_t *opts) {
+	mock_c()->actualCall("celix_bundleContext_findServicesWithOptions")
+			->withPointerParameters("ctx", ctx)
+			->withConstPointerParameters("opts", opts);
+	return mock_c()->returnValue().value.pointerValue;
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/48aada3a/framework/src/bundle_context.c
----------------------------------------------------------------------
diff --git a/framework/src/bundle_context.c b/framework/src/bundle_context.c
index 7d5dea9..ffb1704 100644
--- a/framework/src/bundle_context.c
+++ b/framework/src/bundle_context.c
@@ -672,14 +672,13 @@ bool celix_bundleContext_useServiceWithId(
         const char *serviceName,
         void *callbackHandle,
         void (*use)(void *handle, void *svc)) {
-    celix_service_use_options_t opts;
-    memset(&opts, 0, sizeof(opts));
+    celix_service_use_options_t opts = CELIX_EMPTY_SERVICE_USE_OPTIONS;
 
     char filter[64];
     snprintf(filter, 64, "(%s=%li)", OSGI_FRAMEWORK_SERVICE_ID, serviceId);
 
-    opts.serviceName = serviceName;
-    opts.filter = filter;
+    opts.filter.serviceName = serviceName;
+    opts.filter.filter = filter;
     opts.callbackHandle = callbackHandle;
     opts.use = use;
     return celix_bundleContext_useServiceWithOptions(ctx, &opts);
@@ -690,9 +689,8 @@ bool celix_bundleContext_useService(
         const char* serviceName,
         void *callbackHandle,
         void (*use)(void *handle, void *svc)) {
-    celix_service_use_options_t opts;
-    memset(&opts, 0, sizeof(opts));
-    opts.serviceName = serviceName;
+    celix_service_use_options_t opts = CELIX_EMPTY_SERVICE_USE_OPTIONS;
+    opts.filter.serviceName = serviceName;
     opts.callbackHandle = callbackHandle;
     opts.use = use;
     return celix_bundleContext_useServiceWithOptions(ctx, &opts);
@@ -704,9 +702,8 @@ void celix_bundleContext_useServices(
         const char* serviceName,
         void *callbackHandle,
         void (*use)(void *handle, void *svc)) {
-    celix_service_use_options_t opts;
-    memset(&opts, 0, sizeof(opts));
-    opts.serviceName = serviceName;
+    celix_service_use_options_t opts = CELIX_EMPTY_SERVICE_USE_OPTIONS;
+    opts.filter.serviceName = serviceName;
     opts.callbackHandle = callbackHandle;
     opts.use = use;
     celix_bundleContext_useServicesWithOptions(ctx, &opts);
@@ -721,10 +718,10 @@ bool celix_bundleContext_useServiceWithOptions(
     memset(&trkOpts, 0, sizeof(trkOpts));
 
     if (opts != NULL) {
-        trkOpts.serviceName = opts->serviceName;
+        trkOpts.filter.serviceName = opts->filter.serviceName;
         trkOpts.filter = opts->filter;
-        trkOpts.versionRange = opts->versionRange;
-        trkOpts.lang = opts->lang;
+        trkOpts.filter.versionRange = opts->filter.versionRange;
+        trkOpts.filter.lang = opts->filter.lang;
 
         service_tracker_t *trk = celix_serviceTracker_createWithOptions(ctx, &trkOpts);
         if (trk != NULL) {
@@ -737,7 +734,7 @@ bool celix_bundleContext_useServiceWithOptions(
             if (opts->useWithOwner != NULL) {
 
             }
-            called = celix_serviceTracker_useHighestRankingService(trk, opts->serviceName, opts->callbackHandle, opts->use, opts->useWithProperties, opts->useWithOwner);
+            called = celix_serviceTracker_useHighestRankingService(trk, opts->filter.serviceName, opts->callbackHandle, opts->use, opts->useWithProperties, opts->useWithOwner);
             celix_serviceTracker_destroy(trk);
         }
     }
@@ -749,18 +746,17 @@ bool celix_bundleContext_useServiceWithOptions(
 void celix_bundleContext_useServicesWithOptions(
         celix_bundle_context_t *ctx,
         const celix_service_use_options_t *opts) {
-    celix_service_tracking_options_t trkOpts;
-    memset(&trkOpts, 0, sizeof(trkOpts));
+    celix_service_tracking_options_t trkOpts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS;
 
     if (opts != NULL) {
-        trkOpts.serviceName = opts->serviceName;
-        trkOpts.filter = opts->filter;
-        trkOpts.versionRange = opts->versionRange;
-        trkOpts.lang = opts->lang;
+        trkOpts.filter.serviceName = opts->filter.serviceName;
+        trkOpts.filter.filter = opts->filter.filter;
+        trkOpts.filter.versionRange = opts->filter.versionRange;
+        trkOpts.filter.lang = opts->filter.lang;
 
         service_tracker_t *trk = celix_serviceTracker_createWithOptions(ctx, &trkOpts);
         if (trk != NULL) {
-            celix_serviceTracker_useServices(trk, opts->serviceName, opts->callbackHandle, opts->use, opts->useWithProperties, opts->useWithOwner);
+            celix_serviceTracker_useServices(trk, opts->filter.serviceName, opts->callbackHandle, opts->use, opts->useWithProperties, opts->useWithOwner);
             celix_serviceTracker_destroy(trk);
         }
     }
@@ -772,9 +768,8 @@ long celix_bundleContext_trackService(
         const char* serviceName,
         void* callbackHandle,
         void (*set)(void* handle, void* svc)) {
-    celix_service_tracking_options_t opts;
-    memset(&opts, 0, sizeof(opts));
-    opts.serviceName = serviceName;
+    celix_service_tracking_options_t opts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS;
+    opts.filter.serviceName = serviceName;
     opts.callbackHandle = callbackHandle;
     opts.set = set;
     return celix_bundleContext_trackServicesWithOptions(ctx, &opts);
@@ -787,9 +782,8 @@ long celix_bundleContext_trackServices(
         void* callbackHandle,
         void (*add)(void* handle, void* svc),
         void (*remove)(void* handle, void* svc)) {
-    celix_service_tracking_options_t opts;
-    memset(&opts, 0, sizeof(opts));
-    opts.serviceName = serviceName;
+    celix_service_tracking_options_t opts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS;
+    opts.filter.serviceName = serviceName;
     opts.callbackHandle = callbackHandle;
     opts.add = add;
     opts.remove = remove;
@@ -831,4 +825,50 @@ long celix_bundleContext_registerServiceFactorForLang(celix_bundle_context_t *ct
         celixThreadMutex_unlock(&ctx->mutex);
     }
     return facId;
+}
+
+long celix_bundleContext_findService(celix_bundle_context_t *ctx, const char *serviceName) {
+    celix_service_filter_options_t opts = CELIX_EMPTY_SERVICE_FILTER_OPTIONS;
+    opts.serviceName = serviceName;
+    return celix_bundleContext_findServiceWithOptions(ctx, &opts);
+}
+
+static void bundleContext_retrieveSvcId(void *handle, void *svc __attribute__((unused)), const celix_properties_t *props) {
+    long *svcId = handle;
+    *svcId = celix_properties_getAsLong(props, OSGI_FRAMEWORK_SERVICE_ID, -1L);
+}
+
+long celix_bundleContext_findServiceWithOptions(celix_bundle_context_t *ctx, const celix_service_filter_options_t *opts) {
+    long svcId = -1L;
+    celix_service_use_options_t useOpts = CELIX_EMPTY_SERVICE_USE_OPTIONS;
+    memcpy(&useOpts.filter, opts, sizeof(useOpts.filter));
+    useOpts.callbackHandle = &svcId;
+    useOpts.useWithProperties = bundleContext_retrieveSvcId;
+    celix_bundleContext_useServiceWithOptions(ctx, &useOpts);
+    return svcId;
+}
+
+
+celix_array_list_t* celix_bundleContext_findServices(celix_bundle_context_t *ctx, const char *serviceName) {
+    celix_service_filter_options_t opts = CELIX_EMPTY_SERVICE_FILTER_OPTIONS;
+    opts.serviceName = serviceName;
+    return celix_bundleContext_findServicesWithOptions(ctx, &opts);
+}
+
+static void bundleContext_retrieveSvcIds(void *handle, void *svc __attribute__((unused)), const celix_properties_t *props) {
+    celix_array_list_t *list = handle;
+    if (list != NULL) {
+        long svcId = celix_properties_getAsLong(props, OSGI_FRAMEWORK_SERVICE_ID, -1L);
+        celix_arrayList_addLong(list, svcId);
+    }
+}
+
+celix_array_list_t* celix_bundleContext_findServicesWithOptions(celix_bundle_context_t *ctx, const celix_service_filter_options_t *opts) {
+    celix_array_list_t* list = celix_arrayList_create();
+    celix_service_use_options_t useOpts = CELIX_EMPTY_SERVICE_USE_OPTIONS;
+    memcpy(&useOpts.filter, opts, sizeof(useOpts.filter));
+    useOpts.callbackHandle = list;
+    useOpts.useWithProperties = bundleContext_retrieveSvcIds;
+    celix_bundleContext_useServicesWithOptions(ctx, &useOpts);
+    return list;
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/48aada3a/framework/src/service_tracker.c
----------------------------------------------------------------------
diff --git a/framework/src/service_tracker.c b/framework/src/service_tracker.c
index c92efa3..56ad199 100644
--- a/framework/src/service_tracker.c
+++ b/framework/src/service_tracker.c
@@ -560,11 +560,10 @@ celix_service_tracker_t* celix_serviceTracker_create(
         const char *serviceName,
         const char *versionRange,
         const char *filter) {
-    celix_service_tracking_options_t opts;
-    memset(&opts, 0, sizeof(opts));
-    opts.serviceName = serviceName;
-    opts.filter = filter;
-    opts.versionRange = versionRange;
+    celix_service_tracking_options_t opts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS;
+    opts.filter.serviceName = serviceName;
+    opts.filter.filter = filter;
+    opts.filter.versionRange = versionRange;
     return celix_serviceTracker_createWithOptions(ctx, &opts);
 }
 
@@ -573,7 +572,7 @@ celix_service_tracker_t* celix_serviceTracker_createWithOptions(
         const celix_service_tracking_options_t *opts
 ) {
     celix_service_tracker_t *tracker = NULL;
-    if (ctx != NULL && opts != NULL && opts->serviceName != NULL) {
+    if (ctx != NULL && opts != NULL && opts->filter.serviceName != NULL) {
         tracker = calloc(1, sizeof(*tracker));
         if (tracker != NULL) {
             tracker->context = ctx;
@@ -586,44 +585,41 @@ celix_service_tracker_t* celix_serviceTracker_createWithOptions(
             tracker->set = opts->set;
             tracker->add = opts->add;
             tracker->remove = opts->remove;
-            tracker->modified = opts->modified;
             tracker->setWithProperties = opts->setWithProperties;
             tracker->addWithProperties = opts->addWithProperties;
             tracker->removeWithProperties = opts->removeWithProperties;
-            tracker->modifiedWithProperties = opts->modifiedWithProperties;
             tracker->setWithOwner = opts->setWithOwner;
             tracker->addWithOwner = opts->addWithOwner;
             tracker->removeWithOwner = opts->removeWithOwner;
-            tracker->modifiedWithOwner = opts->modifiedWithOwner;
 
             //highest service state
             celixThreadMutex_create(&tracker->mutex, NULL);
             tracker->currentHighestServiceId = -1;
 
             //setting lang
-            const char *lang = opts->lang;
+            const char *lang = opts->filter.lang;
             if (lang == NULL || strncmp("", lang, 1) == 0) {
                 lang = CELIX_FRAMEWORK_SERVICE_C_LANGUAGE;
             }
 
             //setting filter
-            if (opts->filter != NULL && opts->versionRange != NULL) {
+            if (opts->filter.filter != NULL && opts->filter.versionRange != NULL) {
                 //TODO version range
-                asprintf(&tracker->filter, "&((%s=%s)(%s=%s)%s)", OSGI_FRAMEWORK_OBJECTCLASS, opts->serviceName, CELIX_FRAMEWORK_SERVICE_LANGUAGE, lang, opts->filter);
-            } else if (opts->versionRange != NULL) {
+                asprintf(&tracker->filter, "&((%s=%s)(%s=%s)%s)", OSGI_FRAMEWORK_OBJECTCLASS, opts->filter.serviceName, CELIX_FRAMEWORK_SERVICE_LANGUAGE, lang, opts->filter.filter);
+            } else if (opts->filter.versionRange != NULL) {
                 //TODO version range
-                asprintf(&tracker->filter, "&((%s=%s)(%s=%s))", OSGI_FRAMEWORK_OBJECTCLASS, opts->serviceName, CELIX_FRAMEWORK_SERVICE_LANGUAGE, lang);
-            } else if (opts->filter != NULL) {
-                asprintf(&tracker->filter, "(&(%s=%s)(%s=%s)%s)", OSGI_FRAMEWORK_OBJECTCLASS, opts->serviceName, CELIX_FRAMEWORK_SERVICE_LANGUAGE, lang, opts->filter);
+                asprintf(&tracker->filter, "&((%s=%s)(%s=%s))", OSGI_FRAMEWORK_OBJECTCLASS, opts->filter.serviceName, CELIX_FRAMEWORK_SERVICE_LANGUAGE, lang);
+            } else if (opts->filter.filter != NULL) {
+                asprintf(&tracker->filter, "(&(%s=%s)(%s=%s)%s)", OSGI_FRAMEWORK_OBJECTCLASS, opts->filter.serviceName, CELIX_FRAMEWORK_SERVICE_LANGUAGE, lang, opts->filter.filter);
             } else {
-                asprintf(&tracker->filter, "(&(%s=%s)(%s=%s))", OSGI_FRAMEWORK_OBJECTCLASS, opts->serviceName, CELIX_FRAMEWORK_SERVICE_LANGUAGE, lang);
+                asprintf(&tracker->filter, "(&(%s=%s)(%s=%s))", OSGI_FRAMEWORK_OBJECTCLASS, opts->filter.serviceName, CELIX_FRAMEWORK_SERVICE_LANGUAGE, lang);
             }
 
             //TODO open on other thread?
             serviceTracker_open(tracker);
         }
     } else {
-        if (opts != NULL && opts->serviceName == NULL) {
+        if (opts != NULL && opts->filter.serviceName == NULL) {
             framework_log(logger, OSGI_FRAMEWORK_LOG_ERROR, __FUNCTION__, __BASE_FILE__, __LINE__,
                           "Error incorrect arguments. Missing service name.");
         } else {

http://git-wip-us.apache.org/repos/asf/celix/blob/48aada3a/framework/tst/bundle_context_services_test.cpp
----------------------------------------------------------------------
diff --git a/framework/tst/bundle_context_services_test.cpp b/framework/tst/bundle_context_services_test.cpp
index 2597ece..6fa1204 100644
--- a/framework/tst/bundle_context_services_test.cpp
+++ b/framework/tst/bundle_context_services_test.cpp
@@ -297,7 +297,7 @@ TEST(CelixBundleContextServicesTests, servicesTrackerInvalidArgsTest) {
     memset(&opts, 0, sizeof(opts));
     trackerId = celix_bundleContext_trackServicesWithOptions(ctx, &opts);
     CHECK(trackerId < 0); //required opts->serviceName missing
-    opts.serviceName = "calc";
+    opts.filter.serviceName = "calc";
     trackerId = celix_bundleContext_trackServicesWithOptions(ctx, &opts);
     CHECK(trackerId >= 0); //valid
     celix_bundleContext_stopTracker(ctx, trackerId);
@@ -361,7 +361,7 @@ TEST(CelixBundleContextServicesTests, servicesTrackerTestWithProperties) {
 
     celix_service_tracking_options_t opts;
     memset(&opts, 0, sizeof(opts));
-    opts.serviceName = "calc";
+    opts.filter.serviceName = "calc";
     opts.callbackHandle = &count;
     opts.addWithProperties = add;
     opts.removeWithProperties = remove;
@@ -401,7 +401,7 @@ TEST(CelixBundleContextServicesTests, servicesTrackerTestWithOwner) {
 
     celix_service_tracking_options_t opts;
     memset(&opts, 0, sizeof(opts));
-    opts.serviceName = "calc";
+    opts.filter.serviceName = "calc";
     opts.callbackHandle = &count;
     opts.addWithOwner = add;
     opts.removeWithOwner = remove;
@@ -557,7 +557,7 @@ TEST(CelixBundleContextServicesTests, servicesTrackerSetTest) {
     celix_service_tracking_options_t opts;
     memset(&opts, 0, sizeof(opts));
     opts.callbackHandle = (void*)&count;
-    opts.serviceName = "NA";
+    opts.filter.serviceName = "NA";
     opts.set = set;
     long trackerId = celix_bundleContext_trackServicesWithOptions(ctx, &opts);
     CHECK(trackerId > 0);
@@ -628,3 +628,30 @@ TEST(CelixBundleContextServicesTests, serviceFactoryTest) {
     celix_bundleContext_unregisterService(ctx, facId);
 }
 
+TEST(CelixBundleContextServicesTests, findServicesTest) {
+    long svcId1 = celix_bundleContext_registerService(ctx, "example", (void*)0x100, NULL, NULL);
+    long svcId2 = celix_bundleContext_registerService(ctx, "example", (void*)0x100, NULL, NULL);
+
+    long foundId = celix_bundleContext_findService(ctx, "non existing service name");
+    CHECK_EQUAL(-1L, foundId);
+
+    foundId = celix_bundleContext_findService(ctx, "example");
+    CHECK_EQUAL(foundId, svcId1); //oldest should have highest ranking
+
+    array_list_t *list = celix_bundleContext_findServices(ctx, "non existintg service name");
+    CHECK_EQUAL(0, celix_arrayList_size(list));
+    arrayList_destroy(list);
+
+    list = celix_bundleContext_findServices(ctx, "example");
+    CHECK_EQUAL(2, celix_arrayList_size(list));
+    arrayList_destroy(list);
+
+    celix_bundleContext_unregisterService(ctx, svcId1);
+
+    celix_service_filter_options_t opts = CELIX_EMPTY_SERVICE_FILTER_OPTIONS;
+    opts.serviceName = "example";
+    foundId = celix_bundleContext_findServiceWithOptions(ctx, &opts);
+    CHECK_EQUAL(foundId, svcId2); //only one left
+
+    celix_bundleContext_unregisterService(ctx, svcId2);
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/48aada3a/utils/include/array_list.h
----------------------------------------------------------------------
diff --git a/utils/include/array_list.h b/utils/include/array_list.h
index 46a0697..fa8602b 100644
--- a/utils/include/array_list.h
+++ b/utils/include/array_list.h
@@ -30,11 +30,24 @@
 #include "celixbool.h"
 #include "exports.h"
 #include "celix_errno.h"
+#include "stdbool.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+typedef union celix_array_list_entry {
+    void *voidPtrVal;
+    int intVal;
+    long int longVal;
+    unsigned int uintVal;
+    unsigned long ulongVal;
+    double doubleVal;
+    float floatVal;
+    bool boolVal;
+    size_t sizeVal;
+} celix_array_list_entry_t;
+
 typedef struct celix_arrayList celix_array_list_t;
 
 typedef struct celix_arrayList *array_list_pt;
@@ -45,7 +58,7 @@ typedef struct arrayListIterator array_list_iterator_t;
 
 typedef celix_status_t (*array_list_element_equals_pt)(const void *, const void *, bool *equals);
 
-typedef bool (*celix_arrayList_equals_fp)(const void *, const void *);
+typedef bool (*celix_arrayList_equals_fp)(celix_array_list_entry_t, celix_array_list_entry_t);
 
 UTILS_EXPORT celix_status_t arrayList_create(array_list_pt *list);
 
@@ -107,6 +120,7 @@ UTILS_EXPORT void arrayListIterator_remove(array_list_iterator_pt iterator);
  **********************************************************************************************************************
  **********************************************************************************************************************/
 
+
 celix_array_list_t* celix_arrayList_create();
 
 celix_array_list_t* celix_arrayList_createWithEquals(celix_arrayList_equals_fp equals);
@@ -117,8 +131,31 @@ size_t celix_arrayList_size(const celix_array_list_t *list);
 
 void* celix_arrayList_get(const celix_array_list_t *list, int index);
 
-//TODO rest
-
+//more of the same for the different entry types
+int celix_arrayList_getInt(const celix_array_list_t *list, int index);
+long int celix_arrayList_getLong(const celix_array_list_t *list, int index);
+unsigned int celix_arrayList_getUInt(const celix_array_list_t *list, int index);
+unsigned long int celix_arrayList_getULong(const celix_array_list_t *list, int index);
+float celix_arrayList_getFloat(const celix_array_list_t *list, int index);
+double celix_arrayList_getDouble(const celix_array_list_t *list, int index);
+bool celix_arrayList_getBool(const celix_array_list_t *list, int index);
+size_t celix_arrayList_getSize(const celix_array_list_t *list, int index);
+
+void celix_arrayList_add(celix_array_list_t *list, void* val);
+
+//more of the same for the different entry types
+void celix_arrayList_addInt(celix_array_list_t *list, int val);
+void celix_arrayList_addLong(celix_array_list_t *list, long val);
+void celix_arrayList_addUInt(celix_array_list_t *list, unsigned int val);
+void celix_arrayList_addULong(celix_array_list_t *list, unsigned long val);
+void celix_arrayList_addFloat(celix_array_list_t *list, float val);
+void celix_arrayList_addDouble(celix_array_list_t *list, double val);
+void celix_arrayList_addBool(celix_array_list_t *list, bool val);
+void celix_arrayList_addSize(celix_array_list_t *list, size_t val);
+
+int celix_arrayList_indexOf(celix_array_list_t *list, celix_array_list_entry_t entry);
+void celix_arrayList_remove(celix_array_list_t *list, int index);
+void celix_arrayList_removeEntry(celix_array_list_t *list, celix_array_list_entry_t entry);
 
 #ifdef __cplusplus
 }

http://git-wip-us.apache.org/repos/asf/celix/blob/48aada3a/utils/src/array_list.c
----------------------------------------------------------------------
diff --git a/utils/src/array_list.c b/utils/src/array_list.c
index 751712e..ca12798 100644
--- a/utils/src/array_list.c
+++ b/utils/src/array_list.c
@@ -31,8 +31,8 @@
 #include "array_list_private.h"
 
 static celix_status_t arrayList_elementEquals(const void *a, const void *b, bool *equals);
-static bool celix_arrayList_defaultEquals(const void *a, const void *b);
-static bool celix_arrayList_equalsForElement(celix_array_list_t *list, void *a, void *b);
+static bool celix_arrayList_defaultEquals(const celix_array_list_entry_t a, const celix_array_list_entry_t b);
+static bool celix_arrayList_equalsForElement(celix_array_list_t *list, celix_array_list_entry_t a, celix_array_list_entry_t b);
 
 
 celix_status_t arrayList_create(array_list_pt *list) {
@@ -57,15 +57,15 @@ static celix_status_t arrayList_elementEquals(const void *a, const void *b, bool
 	return CELIX_SUCCESS;
 }
 
-static bool celix_arrayList_defaultEquals(const void *a, const void *b) {
-	return a == b;
+static bool celix_arrayList_defaultEquals(celix_array_list_entry_t a, celix_array_list_entry_t b) {
+	return a.longVal == b.longVal; //just compare as long int
 }
 
-static bool celix_arrayList_equalsForElement(celix_array_list_t *list, void *a, void *b) {
+static bool celix_arrayList_equalsForElement(celix_array_list_t *list, celix_array_list_entry_t a, celix_array_list_entry_t b) {
 	bool equals = false;
 	if (list != NULL) {
 		if (list->equalsDeprecated != NULL) {
-			list->equalsDeprecated(a, b, &equals);
+			list->equalsDeprecated(a.voidPtrVal, b.voidPtrVal, &equals);
 		} else if (list->equals != NULL) {
 			equals = list->equals(a, b);
 		}
@@ -74,34 +74,32 @@ static bool celix_arrayList_equalsForElement(celix_array_list_t *list, void *a,
 }
 
 void arrayList_trimToSize(array_list_pt list) {
-	unsigned int oldCapacity;
 	list->modCount++;
-	oldCapacity = list->capacity;
+	size_t oldCapacity = list->capacity;
 	if (list->size < oldCapacity) {
-		void ** newList = (void **) realloc(list->elementData, sizeof(void *) * list->size);
+		celix_array_list_entry_t * newList = realloc(list->elementData, sizeof(void *) * list->size);
 		list->capacity = list->size;
 		list->elementData = newList;
 	}
 }
 
 void arrayList_ensureCapacity(array_list_pt list, int capacity) {
-	void ** newList;
-	unsigned int oldCapacity;
+	celix_array_list_entry_t *newList;
 	list->modCount++;
-	oldCapacity = list->capacity;
+	size_t oldCapacity = list->capacity;
 	if (capacity > oldCapacity) {
-		unsigned int newCapacity = (oldCapacity * 3) / 2 + 1;
+		size_t newCapacity = (oldCapacity * 3) / 2 + 1;
 		if (newCapacity < capacity) {
 			newCapacity = capacity;
 		}
-		newList = (void **) realloc(list->elementData, sizeof(void *) * newCapacity);
+		newList = realloc(list->elementData, sizeof(void *) * newCapacity);
 		list->capacity = newCapacity;
 		list->elementData = newList;
 	}
 }
 
 unsigned int arrayList_size(array_list_pt list) {
-	return list->size;
+	return (int)list->size;
 }
 
 bool arrayList_isEmpty(array_list_pt list) {
@@ -117,14 +115,15 @@ int arrayList_indexOf(array_list_pt list, void * element) {
 	if (element == NULL) {
 		unsigned int i = 0;
 		for (i = 0; i < list->size; i++) {
-			if (list->elementData[i] == NULL) {
+			if (list->elementData[i].voidPtrVal == NULL) {
 				return i;
 			}
 		}
 	} else {
 		unsigned int i = 0;
 		for (i = 0; i < list->size; i++) {
-			bool equals = celix_arrayList_equalsForElement(list, element, list->elementData[i]);
+			celix_array_list_entry_t entry = { .voidPtrVal = element };
+			bool equals = celix_arrayList_equalsForElement(list, entry, list->elementData[i]);
 			if (equals) {
 				return i;
 			}
@@ -136,17 +135,21 @@ int arrayList_indexOf(array_list_pt list, void * element) {
 int arrayList_lastIndexOf(array_list_pt list, void * element) {
 	if (element == NULL) {
 		int i = 0;
-		for (i = list->size - 1; i >= 0; i--) {
-			if (list->elementData[i] == NULL) {
-				return i;
+		int size = (int)list->size;
+		for (i = size - 1; i >= 0; i--) {
+			if (list->elementData[i].voidPtrVal == NULL) {
+				return (int)i;
 			}
 		}
 	} else {
 		int i = 0;
-		for (i = list->size - 1; i >= 0; i--) {
-			bool equals = celix_arrayList_equalsForElement(list, element, list->elementData[i]);
+		int size = (int)list->size;
+		for (i = size - 1; i >= 0; i--) {
+			celix_array_list_entry_t entry = { .voidPtrVal = element };
+
+			bool equals = celix_arrayList_equalsForElement(list, entry, list->elementData[i]);
 			if (equals) {
-				return i;
+				return (int)i;
 			}
 		}
 	}
@@ -158,7 +161,7 @@ void * arrayList_get(array_list_pt list, unsigned int index) {
 		return NULL;
 	}
 
-	return list->elementData[index];
+	return list->elementData[index].voidPtrVal;
 }
 
 void * arrayList_set(array_list_pt list, unsigned int index, void * element) {
@@ -167,61 +170,63 @@ void * arrayList_set(array_list_pt list, unsigned int index, void * element) {
 		return NULL;
 	}
 
-	oldElement = list->elementData[index];
-	list->elementData[index] = element;
+	oldElement = list->elementData[index].voidPtrVal;
+	memset(&list->elementData[index], 0, sizeof(celix_array_list_entry_t));
+	list->elementData[index].voidPtrVal = element;
 	return oldElement;
 }
 
 bool arrayList_add(array_list_pt list, void * element) {
-	arrayList_ensureCapacity(list, list->size + 1);
-	list->elementData[list->size++] = element;
+	arrayList_ensureCapacity(list, (int)list->size + 1);
+	memset(&list->elementData[list->size], 0, sizeof(celix_array_list_entry_t));
+	list->elementData[list->size++].voidPtrVal = element;
 	return true;
 }
 
 int arrayList_addIndex(array_list_pt list, unsigned int index, void * element) {
-	unsigned int numMoved;
+	size_t numMoved;
 	if (index > list->size) {
 		return -1;
 	}
-	arrayList_ensureCapacity(list, list->size+1);
+	arrayList_ensureCapacity(list, (int)list->size+1);
 	numMoved = list->size - index;
 	memmove(list->elementData+(index+1), list->elementData+index, sizeof(void *) * numMoved);
 
-	list->elementData[index] = element;
+	list->elementData[index].voidPtrVal = element;
 	list->size++;
 	return 0;
 }
 
 void * arrayList_remove(array_list_pt list, unsigned int index) {
 	void * oldElement;
-	unsigned int numMoved;
+	size_t numMoved;
 	if (index >= list->size) {
 		return NULL;
 	}
 
 	list->modCount++;
-	oldElement = list->elementData[index];
+	oldElement = list->elementData[index].voidPtrVal;
 	numMoved = list->size - index - 1;
 	memmove(list->elementData+index, list->elementData+index+1, sizeof(void *) * numMoved);
-	list->elementData[--list->size] = NULL;
+	memset(&list->elementData[--list->size], 0, sizeof(celix_array_list_entry_t));
 
 	return oldElement;
 }
 
 void arrayList_fastRemove(array_list_pt list, unsigned int index) {
-	unsigned int numMoved;
+	size_t numMoved;
 	list->modCount++;
 
 	numMoved = list->size - index - 1;
 	memmove(list->elementData+index, list->elementData+index+1, sizeof(void *) * numMoved);
-	list->elementData[--list->size] = NULL;
+	memset(&list->elementData[--list->size], 0, sizeof(celix_array_list_entry_t));
 }
 
 bool arrayList_removeElement(array_list_pt list, void * element) {
 	if (element == NULL) {
 		unsigned int i = 0;
 		for (i = 0; i < list->size; i++) {
-			if (list->elementData[i] == NULL) {
+			if (list->elementData[i].voidPtrVal == NULL) {
 				arrayList_fastRemove(list, i);
 				return true;
 			}
@@ -229,7 +234,9 @@ bool arrayList_removeElement(array_list_pt list, void * element) {
 	} else {
 		unsigned int i = 0;
 		for (i = 0; i < list->size; i++) {
-			bool equals = celix_arrayList_equalsForElement(list, element, list->elementData[i]);
+			celix_array_list_entry_t entry;
+			entry.voidPtrVal = element;
+			bool equals = celix_arrayList_equalsForElement(list, entry, list->elementData[i]);
 			if (equals) {
 				arrayList_fastRemove(list, i);
 				return true;
@@ -245,7 +252,7 @@ void arrayList_clear(array_list_pt list) {
 
 	for (i = 0; i < list->size; i++) {
 		// free(list->elementData[i]);
-		list->elementData[i] = NULL;
+		memset(&list->elementData[i], 0, sizeof(celix_array_list_entry_t));
 	}
 	list->size = 0;
 }
@@ -375,15 +382,74 @@ size_t celix_arrayList_size(const celix_array_list_t *list) {
 	return list->size;
 }
 
-void* celix_arrayList_get(const celix_array_list_t *list, int index) {
-	void *el = NULL;
+static celix_array_list_entry_t arrayList_getEntry(const celix_array_list_t *list, int index) {
+	celix_array_list_entry_t entry;
+	memset(&entry, 0, sizeof(entry));
 	if (index < list->size) {
-		el = list->elementData[index];
+		entry = list->elementData[index];
 	}
-	return el;
+	return entry;
+}
+
+void* celix_arrayList_get(const celix_array_list_t *list, int index) {
+	return arrayList_getEntry(list, index).voidPtrVal;
+}
+
+int celix_arrayList_getInt(const celix_array_list_t *list, int index) { return arrayList_getEntry(list, index).intVal; }
+long int celix_arrayList_getLong(const celix_array_list_t *list, int index) { return arrayList_getEntry(list, index).longVal; }
+unsigned int celix_arrayList_getUInt(const celix_array_list_t *list, int index) { return arrayList_getEntry(list, index).uintVal; }
+unsigned long int celix_arrayList_getULong(const celix_array_list_t *list, int index) { return arrayList_getEntry(list, index).ulongVal; }
+float celix_arrayList_getFloat(const celix_array_list_t *list, int index) { return arrayList_getEntry(list, index).floatVal; }
+double celix_arrayList_getDouble(const celix_array_list_t *list, int index) { return arrayList_getEntry(list, index).doubleVal; }
+bool celix_arrayList_getBool(const celix_array_list_t *list, int index) { return arrayList_getEntry(list, index).boolVal; }
+size_t celix_arrayList_getSize(const celix_array_list_t *list, int index) { return arrayList_getEntry(list, index).sizeVal; }
+
+static void arrayList_addEntry(celix_array_list_t *list, celix_array_list_entry_t entry) {
+	arrayList_ensureCapacity(list, (int)list->size + 1);
+	memset(&list->elementData[list->size], 0, sizeof(entry));
+	list->elementData[list->size++] = entry;
+}
+
+void celix_arrayList_add(celix_array_list_t *list, void * element) {
+	celix_array_list_entry_t entry = { .voidPtrVal = element };
+	arrayList_addEntry(list, entry);
 }
 
+void celix_arrayList_addInt(celix_array_list_t *list, int val) { celix_array_list_entry_t entry = { .intVal = val }; arrayList_addEntry(list, entry);}
+void celix_arrayList_addLong(celix_array_list_t *list, long val)  { celix_array_list_entry_t entry = { .longVal = val }; arrayList_addEntry(list, entry);}
+void celix_arrayList_addUInt(celix_array_list_t *list, unsigned int val)  { celix_array_list_entry_t entry = { .uintVal = val }; arrayList_addEntry(list, entry);}
+void celix_arrayList_addULong(celix_array_list_t *list, unsigned long val)  { celix_array_list_entry_t entry = { .ulongVal = val }; arrayList_addEntry(list, entry);}
+void celix_arrayList_addFloat(celix_array_list_t *list, float val)  { celix_array_list_entry_t entry = { .floatVal = val }; arrayList_addEntry(list, entry);}
+void celix_arrayList_addDouble(celix_array_list_t *list, double val)  { celix_array_list_entry_t entry = { .doubleVal = val }; arrayList_addEntry(list, entry);}
+void celix_arrayList_addBool(celix_array_list_t *list, bool val)  { celix_array_list_entry_t entry = { .boolVal = val }; arrayList_addEntry(list, entry);}
+void celix_arrayList_addSize(celix_array_list_t *list, size_t val)  { celix_array_list_entry_t entry = { .sizeVal = val }; arrayList_addEntry(list, entry);}
+
+int celix_arrayList_indexOf(celix_array_list_t *list, celix_array_list_entry_t entry) {
+	size_t size = celix_arrayList_size(list);
+	int i;
+	int index = -1;
+	for (i = 0 ; i < size ; ++i) {
+		bool eq = celix_arrayList_equalsForElement(list, entry, list->elementData[i]);
+		if (eq) {
+			index = i;
+			break;
+		}
+	}
+	return index;
+}
+void celix_arrayList_remove(celix_array_list_t *list, int index) {
+	if (index >= 0 && index < list->size) {
+		list->modCount++;
+		size_t numMoved = list->size - index - 1;
+		memmove(list->elementData+index, list->elementData+index+1, sizeof(void *) * numMoved);
+		memset(&list->elementData[--list->size], 0, sizeof(celix_array_list_entry_t));
+	}
+}
 
+void celix_arrayList_removeEntry(celix_array_list_t *list, celix_array_list_entry_t entry) {
+	int index = celix_arrayList_indexOf(list, entry);
+	celix_arrayList_remove(list, index);
+}
 
 
 

http://git-wip-us.apache.org/repos/asf/celix/blob/48aada3a/utils/src/array_list_private.h
----------------------------------------------------------------------
diff --git a/utils/src/array_list_private.h b/utils/src/array_list_private.h
index e5394cd..5f83605 100644
--- a/utils/src/array_list_private.h
+++ b/utils/src/array_list_private.h
@@ -30,7 +30,7 @@
 #include "array_list.h"
 
 struct celix_arrayList {
-	void ** elementData;
+	celix_array_list_entry_t* elementData;
 	size_t size;
 	size_t capacity;
 


[02/12] celix git commit: CELIX-446: Renames services example to best practice and create a new services example for C.

Posted by pn...@apache.org.
CELIX-446: Renames services example to best practice and create a new services example for C.


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

Branch: refs/heads/feature/CELIX-426-cxx-api
Commit: 5872268f2862bf52b441796b7a5c958946bfef83
Parents: 673837f
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Wed May 9 21:33:42 2018 +0200
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Wed May 9 21:33:42 2018 +0200

----------------------------------------------------------------------
 examples/celix-examples/CMakeLists.txt          |   2 +
 .../best_practice_example_c/CMakeLists.txt      |  40 ++++
 .../best_practice_example_c/api/example.h       |  34 ++++
 .../best_practice_example_c/bar/CMakeLists.txt  |  39 ++++
 .../bar/private/include/bar.h                   |  32 ++++
 .../bar/private/src/bar.c                       |  58 ++++++
 .../bar/private/src/bar_activator.c             |  70 +++++++
 .../best_practice_example_c/foo1/CMakeLists.txt |  39 ++++
 .../foo1/private/include/foo1.h                 |  36 ++++
 .../foo1/private/src/foo1.c                     | 102 +++++++++++
 .../foo1/private/src/foo1_activator.c           |  88 +++++++++
 .../best_practice_example_c/foo2/CMakeLists.txt |  39 ++++
 .../foo2/private/include/foo2.h                 |  36 ++++
 .../foo2/private/src/foo2.c                     | 113 ++++++++++++
 .../foo2/private/src/foo2_activator.c           |  88 +++++++++
 .../services_example_c/CMakeLists.txt           |  47 +++--
 .../services_example_c/api/example.h            |  34 ----
 .../services_example_c/api/example_calc.h       |  32 ++++
 .../services_example_c/bar/CMakeLists.txt       |  39 ----
 .../bar/private/include/bar.h                   |  32 ----
 .../services_example_c/bar/private/src/bar.c    |  58 ------
 .../bar/private/src/bar_activator.c             |  70 -------
 .../services_example_c/foo1/CMakeLists.txt      |  39 ----
 .../foo1/private/include/foo1.h                 |  36 ----
 .../services_example_c/foo1/private/src/foo1.c  | 102 -----------
 .../foo1/private/src/foo1_activator.c           |  88 ---------
 .../services_example_c/foo2/CMakeLists.txt      |  39 ----
 .../foo2/private/include/foo2.h                 |  36 ----
 .../services_example_c/foo2/private/src/foo2.c  | 113 ------------
 .../foo2/private/src/foo2_activator.c           |  88 ---------
 .../services_example_c/src/consumer_example.c   | 182 +++++++++++++++++++
 .../services_example_c/src/provider_example.c   | 134 ++++++++++++++
 framework/include/bundle_context.h              |  11 +-
 framework/include/service_tracker.h             |   8 +-
 framework/private/mock/bundle_context_mock.c    |   2 +-
 framework/src/bundle_context.c                  |  20 +-
 framework/src/service_tracker.c                 |  32 +++-
 framework/tst/bundle_context_services_test.cpp  |  14 +-
 38 files changed, 1245 insertions(+), 827 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/celix-examples/CMakeLists.txt b/examples/celix-examples/CMakeLists.txt
index 0937cc9..2ade793 100644
--- a/examples/celix-examples/CMakeLists.txt
+++ b/examples/celix-examples/CMakeLists.txt
@@ -25,6 +25,8 @@ if (EXAMPLES)
     add_subdirectory(hello_world_test)
 
     add_subdirectory(services_example_c)
+
+    add_subdirectory(best_practice_example_c)
     add_subdirectory(services_example_cxx)
 
     add_subdirectory(dm_example)

http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/best_practice_example_c/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/celix-examples/best_practice_example_c/CMakeLists.txt b/examples/celix-examples/best_practice_example_c/CMakeLists.txt
new file mode 100644
index 0000000..075a6e7
--- /dev/null
+++ b/examples/celix-examples/best_practice_example_c/CMakeLists.txt
@@ -0,0 +1,40 @@
+# 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_directories(
+        ${PROJECT_SOURCE_DIR}/dependency_manager/public/include
+        ${PROJECT_SOURCE_DIR}/utils/public/include
+        api
+)
+
+add_subdirectory(foo1)
+add_subdirectory(foo2)
+add_subdirectory(bar)
+
+add_celix_container(best_practice_example_c
+    GROUP services_example
+    COPY
+    BUNDLES
+        Celix::shell
+        Celix::shell_tui
+        dm_shell
+        bar
+        foo1
+        foo2
+    PROPERTIES
+        example=value
+)

http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/best_practice_example_c/api/example.h
----------------------------------------------------------------------
diff --git a/examples/celix-examples/best_practice_example_c/api/example.h b/examples/celix-examples/best_practice_example_c/api/example.h
new file mode 100644
index 0000000..b0e0166
--- /dev/null
+++ b/examples/celix-examples/best_practice_example_c/api/example.h
@@ -0,0 +1,34 @@
+/**
+ *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.
+ */
+#ifndef EXAMPLE_H_
+#define EXAMPLE_H_
+
+#define EXAMPLE_NAME 			"org.example"
+#define EXAMPLE_VERSION 		"1.0.0"
+#define EXAMPLE_CONSUMER_RANGE   "[1.0.0,2.0.0)"
+
+
+struct example_struct {
+	void *handle;
+	int (*method)(void *handle, int arg1, double arg2, double *result);
+} ;
+
+typedef struct example_struct example_t;
+
+#endif /* EXAMPLE_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/best_practice_example_c/bar/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/celix-examples/best_practice_example_c/bar/CMakeLists.txt b/examples/celix-examples/best_practice_example_c/bar/CMakeLists.txt
new file mode 100644
index 0000000..7df3051
--- /dev/null
+++ b/examples/celix-examples/best_practice_example_c/bar/CMakeLists.txt
@@ -0,0 +1,39 @@
+# 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_directories(
+        private/include
+)
+
+add_celix_bundle(bar
+    SYMBOLIC_NAME bar
+    VERSION 1.0.0
+    SOURCES
+        private/src/bar_activator
+        private/src/bar.c
+)
+
+IF(APPLE)
+    target_link_libraries(bar PRIVATE Celix::framework  -Wl,-all_load dependency_manager_static)
+else()
+    if(ENABLE_ADDRESS_SANITIZER)
+        #With asan there can be undefined symbols
+        target_link_libraries(bar PRIVATE -Wl,--whole-archive dependency_manager_static -Wl,--no-whole-archive Celix::framework )
+    else()
+        target_link_libraries(bar PRIVATE -Wl,--no-undefined -Wl,--whole-archive dependency_manager_static -Wl,--no-whole-archive Celix::framework )
+    endif()
+endif()

http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/best_practice_example_c/bar/private/include/bar.h
----------------------------------------------------------------------
diff --git a/examples/celix-examples/best_practice_example_c/bar/private/include/bar.h b/examples/celix-examples/best_practice_example_c/bar/private/include/bar.h
new file mode 100644
index 0000000..5e1da8b
--- /dev/null
+++ b/examples/celix-examples/best_practice_example_c/bar/private/include/bar.h
@@ -0,0 +1,32 @@
+/**
+ *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.
+ */
+
+#ifndef BAR_H_
+#define BAR_H_
+
+#include "example.h"
+
+typedef struct bar_struct bar_t;
+
+bar_t* bar_create(void);
+void bar_destroy(bar_t *self);
+
+int bar_method(bar_t *self, int arg1, double arg2, double *out);
+
+#endif //BAR_H_

http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/best_practice_example_c/bar/private/src/bar.c
----------------------------------------------------------------------
diff --git a/examples/celix-examples/best_practice_example_c/bar/private/src/bar.c b/examples/celix-examples/best_practice_example_c/bar/private/src/bar.c
new file mode 100644
index 0000000..5099201
--- /dev/null
+++ b/examples/celix-examples/best_practice_example_c/bar/private/src/bar.c
@@ -0,0 +1,58 @@
+/**
+ *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 "bar.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <signal.h>
+#include <stdbool.h>
+#include <pthread.h>
+#include <assert.h>
+
+
+#define OK 0
+#define ERROR 1
+
+struct bar_struct {
+    double prefValue;
+};
+
+bar_t* bar_create(void) {
+    bar_t *self = calloc(1, sizeof(*self));
+    if (self != NULL) {
+        self->prefValue = 42;
+    } else {
+        //log error
+    }
+    return self;
+};
+
+void bar_destroy(bar_t *self) {
+    free(self);
+}
+
+int bar_method(bar_t *self, int arg1, double arg2, double *out) {
+    double update = (self->prefValue + arg1) * arg2;
+    self->prefValue = update;
+    *out = update;
+    return OK;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/best_practice_example_c/bar/private/src/bar_activator.c
----------------------------------------------------------------------
diff --git a/examples/celix-examples/best_practice_example_c/bar/private/src/bar_activator.c b/examples/celix-examples/best_practice_example_c/bar/private/src/bar_activator.c
new file mode 100644
index 0000000..0fa7889
--- /dev/null
+++ b/examples/celix-examples/best_practice_example_c/bar/private/src/bar_activator.c
@@ -0,0 +1,70 @@
+/**
+ *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 "dm_activator.h"
+#include "bar.h"
+
+#include <stdlib.h>
+
+struct activator {
+	bar_t *bar;
+	example_t exampleService;
+};
+
+celix_status_t dm_create(bundle_context_pt context, void **userData) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator *act = calloc(1, sizeof(*act));
+	if (act != NULL) {
+
+		act->bar = bar_create();
+		act->exampleService.handle = act->bar;
+		act->exampleService.method = (void*) bar_method;
+
+		if (act->bar != NULL) {
+            *userData = act;
+        } else {
+            free(act);
+        }
+	} else {
+		status = CELIX_ENOMEM;
+	}
+	return status;
+}
+
+celix_status_t dm_init(void *userData, bundle_context_pt context, dm_dependency_manager_pt manager) {
+    celix_status_t status = CELIX_SUCCESS;
+	struct activator *activator = userData;
+
+	dm_component_pt cmp = NULL;
+	component_create(context, "BAR", &cmp);
+	component_setImplementation(cmp, activator->bar);
+	component_addInterface(cmp, EXAMPLE_NAME, EXAMPLE_VERSION, &activator->exampleService, NULL);
+
+	dependencyManager_add(manager, cmp);
+    return status;
+}
+
+celix_status_t dm_destroy(void *userData, bundle_context_pt context, dm_dependency_manager_pt manager) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator *activator = userData;
+	bar_destroy(activator->bar);
+	free(activator);
+	return status;
+};
+

http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/best_practice_example_c/foo1/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/celix-examples/best_practice_example_c/foo1/CMakeLists.txt b/examples/celix-examples/best_practice_example_c/foo1/CMakeLists.txt
new file mode 100644
index 0000000..d732c76
--- /dev/null
+++ b/examples/celix-examples/best_practice_example_c/foo1/CMakeLists.txt
@@ -0,0 +1,39 @@
+# 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_directories(
+        private/include
+)
+
+add_celix_bundle(foo1
+    SYMBOLIC_NAME foo1
+    VERSION 1.0.0
+    SOURCES
+        private/src/foo1_activator
+        private/src/foo1.c
+)
+
+IF(APPLE)
+    target_link_libraries(foo1 PRIVATE -Wl,-all_load dependency_manager_static)
+else()
+    if(ENABLE_ADDRESS_SANITIZER)
+        #With asan there can be undefined symbols
+        target_link_libraries(foo1 PRIVATE -Wl,--whole-archive dependency_manager_static -Wl,--no-whole-archive)
+    else()
+        target_link_libraries(foo1 PRIVATE -Wl,--no-undefined -Wl,--whole-archive dependency_manager_static -Wl,--no-whole-archive)
+    endif()
+endif()

http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/best_practice_example_c/foo1/private/include/foo1.h
----------------------------------------------------------------------
diff --git a/examples/celix-examples/best_practice_example_c/foo1/private/include/foo1.h b/examples/celix-examples/best_practice_example_c/foo1/private/include/foo1.h
new file mode 100644
index 0000000..f556b44
--- /dev/null
+++ b/examples/celix-examples/best_practice_example_c/foo1/private/include/foo1.h
@@ -0,0 +1,36 @@
+/**
+ *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.
+ */
+
+#ifndef FOO1_H_
+#define FOO1_H_
+
+#include "example.h"
+
+typedef struct foo1_struct foo1_t;
+
+foo1_t* foo1_create(void);
+void foo1_destroy(foo1_t *self);
+
+int foo1_start(foo1_t *self);
+int foo1_stop(foo1_t *self);
+
+int foo1_setExample(foo1_t *self, const example_t *example);
+
+
+#endif //FOO1_H_

http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/best_practice_example_c/foo1/private/src/foo1.c
----------------------------------------------------------------------
diff --git a/examples/celix-examples/best_practice_example_c/foo1/private/src/foo1.c b/examples/celix-examples/best_practice_example_c/foo1/private/src/foo1.c
new file mode 100644
index 0000000..1f1f56f
--- /dev/null
+++ b/examples/celix-examples/best_practice_example_c/foo1/private/src/foo1.c
@@ -0,0 +1,102 @@
+/**
+ *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 "foo1.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <signal.h>
+#include <stdbool.h>
+#include <pthread.h>
+#include <assert.h>
+
+
+#define OK 0
+#define ERROR 1
+
+static void* foo1_thread(void*);
+
+struct foo1_struct {
+    const example_t *example;
+    pthread_mutex_t mutex; //protecting example
+    pthread_t thread;
+    bool running;
+};
+
+foo1_t* foo1_create(void) {
+    foo1_t *self = calloc(1, sizeof(*self));
+    if (self != NULL) {
+        pthread_mutex_init(&self->mutex, NULL);
+        self->running = false;
+    } else {
+        //log error
+    }
+    return self;
+};
+
+void foo1_destroy(foo1_t *self) {
+    assert(!self->running);
+    pthread_mutex_destroy(&self->mutex);
+    free(self);
+}
+
+int foo1_start(foo1_t *self) {
+    printf("starting foo1\n");
+    self->running = true;
+    pthread_create(&self->thread, NULL, foo1_thread, self);
+    return OK;
+}
+
+int foo1_stop(foo1_t *self) {
+    printf("stopping foo1\n");
+    self->running = false;
+    pthread_kill(self->thread, SIGUSR1);
+    pthread_join(self->thread, NULL);
+    return OK;
+}
+
+int foo1_setExample(foo1_t *self, const example_t *example) {
+    printf("Setting example %p for foo1\n", example);
+    pthread_mutex_lock(&self->mutex);
+    self->example = example; //NOTE could be NULL if req is not mandatory
+    pthread_mutex_unlock(&self->mutex);
+    return OK;
+}
+
+static void* foo1_thread(void *userdata) {
+    foo1_t *self = userdata;
+    double result;
+    int rc;
+    while (self->running) {
+        pthread_mutex_lock(&self->mutex);
+        if (self->example != NULL) {
+            rc = self->example->method(self->example->handle, 1, 2.0, &result);
+            if (rc == 0) {
+                printf("Result is %f\n", result);
+            } else {
+                printf("Error invoking method for example\n");
+            }
+        }
+        pthread_mutex_unlock(&self->mutex);
+        usleep(30000000);
+    }
+    return NULL;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/best_practice_example_c/foo1/private/src/foo1_activator.c
----------------------------------------------------------------------
diff --git a/examples/celix-examples/best_practice_example_c/foo1/private/src/foo1_activator.c b/examples/celix-examples/best_practice_example_c/foo1/private/src/foo1_activator.c
new file mode 100644
index 0000000..f94888b
--- /dev/null
+++ b/examples/celix-examples/best_practice_example_c/foo1/private/src/foo1_activator.c
@@ -0,0 +1,88 @@
+/**
+ *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 "dm_activator.h"
+#include "foo1.h"
+
+#include <stdlib.h>
+
+struct activator {
+	foo1_t *foo;
+};
+
+celix_status_t dm_create(bundle_context_pt context, void **userData) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator *act = calloc(1, sizeof(*act));
+	if (act != NULL) {
+		act->foo = foo1_create();
+        if (act->foo != NULL) {
+            *userData = act;
+        } else {
+            free(act);
+        }
+	} else {
+		status = CELIX_ENOMEM;
+	}
+	return status;
+}
+
+celix_status_t dm_init(void *userData, bundle_context_pt context, dm_dependency_manager_pt manager) {
+    celix_status_t status = CELIX_SUCCESS;
+	struct activator *activator = userData;
+
+	dm_component_pt cmp = NULL;
+	component_create(context, "FOO1", &cmp);
+	component_setImplementation(cmp, activator->foo);
+
+	/*
+	With the component_setCallbacksSafe we register callbacks when a component is started / stopped using a component
+	 with type foo1_t*
+	*/
+    component_setCallbacksSafe(cmp, foo1_t*, NULL, foo1_start, foo1_stop, NULL);
+
+	dm_service_dependency_pt dep = NULL;
+	serviceDependency_create(&dep);
+	serviceDependency_setRequired(dep, true);
+	serviceDependency_setService(dep, EXAMPLE_NAME, EXAMPLE_CONSUMER_RANGE, NULL);
+	serviceDependency_setStrategy(dep, DM_SERVICE_DEPENDENCY_STRATEGY_LOCKING);
+
+	/*
+	With the serviceDependency_setCallbacksSafe we register callbacks when a service
+	is added and about to be removed for the component type foo1_t* and service type example_t*.
+
+	We should protect the usage of the
+ 	service because after removal of the service the memory location of that service
+	could be freed
+	*/
+    serviceDependency_setCallbacksSafe(dep, foo1_t*, const example_t*, foo1_setExample, NULL, NULL, NULL, NULL);
+	component_addServiceDependency(cmp, dep);
+
+	dependencyManager_add(manager, cmp);
+
+    return status;
+}
+
+celix_status_t dm_destroy(void *userData, bundle_context_pt context, dm_dependency_manager_pt manager) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator *activator = userData;
+	foo1_destroy(activator->foo);
+	free(activator);
+	return status;
+};
+

http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/best_practice_example_c/foo2/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/celix-examples/best_practice_example_c/foo2/CMakeLists.txt b/examples/celix-examples/best_practice_example_c/foo2/CMakeLists.txt
new file mode 100644
index 0000000..adb8f64
--- /dev/null
+++ b/examples/celix-examples/best_practice_example_c/foo2/CMakeLists.txt
@@ -0,0 +1,39 @@
+# 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_directories(
+        private/include
+)
+
+add_celix_bundle(foo2
+    SYMBOLIC_NAME foo2
+    VERSION 1.0.0
+    SOURCES
+        private/src/foo2_activator
+        private/src/foo2.c
+)
+
+IF(APPLE)
+    target_link_libraries(foo2 PRIVATE -Wl,-all_load dependency_manager_static)
+else()
+    if(ENABLE_ADDRESS_SANITIZER)
+        #With asan there can be undefined symbols
+        target_link_libraries(foo2 PRIVATE -Wl,--whole-archive dependency_manager_static -Wl,--no-whole-archive)
+    else()
+        target_link_libraries(foo2 PRIVATE -Wl,--no-undefined -Wl,--whole-archive dependency_manager_static -Wl,--no-whole-archive)
+    endif()
+endif()

http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/best_practice_example_c/foo2/private/include/foo2.h
----------------------------------------------------------------------
diff --git a/examples/celix-examples/best_practice_example_c/foo2/private/include/foo2.h b/examples/celix-examples/best_practice_example_c/foo2/private/include/foo2.h
new file mode 100644
index 0000000..9f09276
--- /dev/null
+++ b/examples/celix-examples/best_practice_example_c/foo2/private/include/foo2.h
@@ -0,0 +1,36 @@
+/**
+ *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.
+ */
+
+#ifndef FOO2_H_
+#define FOO2_H_
+
+#include "example.h"
+
+typedef struct foo2_struct foo2_t;
+
+foo2_t* foo2_create(void);
+void foo2_destroy(foo2_t *self);
+
+int foo2_start(foo2_t *self);
+int foo2_stop(foo2_t *self);
+
+int foo2_addExample(foo2_t *self, const example_t *example);
+int foo2_removeExample(foo2_t *self, const example_t *example);
+
+#endif //FOO2_H_
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/best_practice_example_c/foo2/private/src/foo2.c
----------------------------------------------------------------------
diff --git a/examples/celix-examples/best_practice_example_c/foo2/private/src/foo2.c b/examples/celix-examples/best_practice_example_c/foo2/private/src/foo2.c
new file mode 100644
index 0000000..b98e20b
--- /dev/null
+++ b/examples/celix-examples/best_practice_example_c/foo2/private/src/foo2.c
@@ -0,0 +1,113 @@
+/**
+ *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 "foo2.h"
+
+#include "array_list.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <signal.h>
+#include <stdbool.h>
+#include <pthread.h>
+#include <assert.h>
+
+
+#define OK 0
+#define ERROR 1
+
+static void* foo2_thread(void*);
+
+struct foo2_struct {
+    array_list_pt examples;
+    pthread_t thread;
+    bool running;
+};
+
+foo2_t* foo2_create(void) {
+    foo2_t *self = calloc(1, sizeof(*self));
+    if (self != NULL) {
+        self->examples = NULL;
+        arrayList_create(&self->examples);
+        self->running = false;
+    } else {
+        //log error
+    }
+    return self;
+};
+
+void foo2_destroy(foo2_t *self) {
+    assert(!self->running);
+    arrayList_destroy(self->examples);
+    free(self);
+}
+
+int foo2_start(foo2_t *self) {
+    printf("starting foo2\n");
+    self->running = true;
+    pthread_create(&self->thread, NULL, foo2_thread, self);
+    return OK;
+}
+
+int foo2_stop(foo2_t *self) {
+    printf("stopping foo2\n");
+    self->running = false;
+    pthread_kill(self->thread, SIGUSR1);
+    pthread_join(self->thread, NULL);
+    return OK;
+}
+
+int foo2_addExample(foo2_t *self, const example_t *example) {
+    //NOTE foo2 is suspended -> thread is not running  -> safe to update
+    int status = OK;
+    printf("Adding example %p for foo2\n", example);
+    status = arrayList_add(self->examples, (void *)example);
+    return status;
+}
+
+int foo2_removeExample(foo2_t *self, const example_t *example) {
+    //NOTE foo2 is suspended -> thread is not running  -> safe to update
+    int status = OK;
+    printf("Removing example %p for foo2\n", example);
+    status = arrayList_removeElement(self->examples, (void*)example);
+    return status;
+}
+
+static void* foo2_thread(void *userdata) {
+    foo2_t *self = userdata;
+    double result;
+    int rc;
+    while (self->running) {
+        unsigned int size = arrayList_size(self->examples);
+        int i;
+        for (i = 0; i < size; i += 1) {
+            const example_t* example = arrayList_get(self->examples, i);
+            rc = example->method(example->handle, 1, 2.0, &result);
+            if (rc == 0) {
+                printf("Result is %f\n", result);
+            } else {
+                printf("Error invoking method for example\n");
+            }
+        }
+        usleep(15000000);
+    }
+    return NULL;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/best_practice_example_c/foo2/private/src/foo2_activator.c
----------------------------------------------------------------------
diff --git a/examples/celix-examples/best_practice_example_c/foo2/private/src/foo2_activator.c b/examples/celix-examples/best_practice_example_c/foo2/private/src/foo2_activator.c
new file mode 100644
index 0000000..5c047da
--- /dev/null
+++ b/examples/celix-examples/best_practice_example_c/foo2/private/src/foo2_activator.c
@@ -0,0 +1,88 @@
+/**
+ *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 "dm_activator.h"
+#include "foo2.h"
+
+#include <stdlib.h>
+
+struct activator {
+	foo2_t *foo;
+};
+
+celix_status_t dm_create(bundle_context_pt context, void **userData) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator *act = calloc(1, sizeof(*act));
+	if (act != NULL) {
+		act->foo = foo2_create();
+        if (act->foo != NULL) {
+            *userData = act;
+        } else {
+            free(act);
+        }
+	} else {
+		status = CELIX_ENOMEM;
+	}
+	return status;
+}
+
+celix_status_t dm_init(void *userData, bundle_context_pt context, dm_dependency_manager_pt manager) {
+    celix_status_t status = CELIX_SUCCESS;
+	struct activator *activator = userData;
+
+	dm_component_pt cmp = NULL;
+	component_create(context, "FOO2", &cmp);
+	component_setImplementation(cmp, activator->foo);
+
+	/*
+	With the component_setCallbacksSafe we register callbacks when a component is started / stopped using a component
+	 with type foo1_t*
+	*/
+    component_setCallbacksSafe(cmp, foo2_t*, NULL, foo2_start, foo2_stop, NULL);
+
+	dm_service_dependency_pt dep = NULL;
+	serviceDependency_create(&dep);
+	serviceDependency_setRequired(dep, false);
+	serviceDependency_setService(dep, EXAMPLE_NAME, EXAMPLE_CONSUMER_RANGE, NULL);
+	serviceDependency_setStrategy(dep, DM_SERVICE_DEPENDENCY_STRATEGY_SUSPEND);
+
+	/*
+	With the serviceDependency_setCallbacksSafe we register callbacks when a service
+	is added and about to be removed for the component type foo1_t* and service type example_t*.
+
+	We should protect the usage of the
+ 	service because after removal of the service the memory location of that service
+	could be freed
+	*/
+    serviceDependency_setCallbacksSafe(dep, foo2_t*, const example_t*, NULL, foo2_addExample, NULL, foo2_removeExample, NULL);
+	component_addServiceDependency(cmp, dep);
+
+	dependencyManager_add(manager, cmp);
+
+    return status;
+}
+
+celix_status_t dm_destroy(void *userData, bundle_context_pt context, dm_dependency_manager_pt manager) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator *activator = userData;
+	foo2_destroy(activator->foo);
+	free(activator);
+	return status;
+};
+

http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/services_example_c/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/celix-examples/services_example_c/CMakeLists.txt b/examples/celix-examples/services_example_c/CMakeLists.txt
index 65760b7..6f7913b 100644
--- a/examples/celix-examples/services_example_c/CMakeLists.txt
+++ b/examples/celix-examples/services_example_c/CMakeLists.txt
@@ -5,39 +5,36 @@
 # 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.
-if (BUILD_DEPENDENCY_MANAGER)
 
-    include_directories(
-            ${PROJECT_SOURCE_DIR}/dependency_manager/public/include
-            ${PROJECT_SOURCE_DIR}/utils/public/include
-            api
-    )
+add_library(services_example_c_api INTERFACE)
+target_include_directories(services_example_c_api INTERFACE api)
 
-    add_subdirectory(foo1)
-    add_subdirectory(foo2)
-    add_subdirectory(bar)
 
-    add_celix_container(services_example_c
-        GROUP services_example
-        COPY
-        BUNDLES
-            Celix::shell
-            Celix::shell_tui
-            dm_shell
-            bar
-            foo1
-            foo2
-        PROPERTIES
-            example=value
-    )
+add_celix_bundle(provider_example
+        VERSION 1.0.0
+        SOURCES src/provider_example.c
+)
+target_link_libraries(provider_example PRIVATE services_example_c_api)
 
-endif ()
+add_celix_bundle(consumer_example
+        VERSION 1.0.0
+        SOURCES src/consumer_example.c
+        )
+target_link_libraries(consumer_example PRIVATE services_example_c_api)
+
+add_celix_container(services_example_c
+    BUNDLES
+        Celix::shell
+        Celix::shell_tui
+        provider_example
+        consumer_example
+)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/services_example_c/api/example.h
----------------------------------------------------------------------
diff --git a/examples/celix-examples/services_example_c/api/example.h b/examples/celix-examples/services_example_c/api/example.h
deleted file mode 100644
index b0e0166..0000000
--- a/examples/celix-examples/services_example_c/api/example.h
+++ /dev/null
@@ -1,34 +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.
- */
-#ifndef EXAMPLE_H_
-#define EXAMPLE_H_
-
-#define EXAMPLE_NAME 			"org.example"
-#define EXAMPLE_VERSION 		"1.0.0"
-#define EXAMPLE_CONSUMER_RANGE   "[1.0.0,2.0.0)"
-
-
-struct example_struct {
-	void *handle;
-	int (*method)(void *handle, int arg1, double arg2, double *result);
-} ;
-
-typedef struct example_struct example_t;
-
-#endif /* EXAMPLE_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/services_example_c/api/example_calc.h
----------------------------------------------------------------------
diff --git a/examples/celix-examples/services_example_c/api/example_calc.h b/examples/celix-examples/services_example_c/api/example_calc.h
new file mode 100644
index 0000000..89481fa
--- /dev/null
+++ b/examples/celix-examples/services_example_c/api/example_calc.h
@@ -0,0 +1,32 @@
+/**
+ *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.
+ */
+
+#ifndef CELIX_EXAMPLE_CALC_H
+#define CELIX_EXAMPLE_CALC_H
+
+#define EXAMPLE_CALC_NAME "example_calc"
+
+struct example_calc {
+    void *handle;
+    int (*calc)(void *handle, int input);
+};
+
+typedef struct example_calc example_calc_t;
+
+#endif //CELIX_EXAMPLE_CALC_H

http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/services_example_c/bar/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/celix-examples/services_example_c/bar/CMakeLists.txt b/examples/celix-examples/services_example_c/bar/CMakeLists.txt
deleted file mode 100644
index 7df3051..0000000
--- a/examples/celix-examples/services_example_c/bar/CMakeLists.txt
+++ /dev/null
@@ -1,39 +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_directories(
-        private/include
-)
-
-add_celix_bundle(bar
-    SYMBOLIC_NAME bar
-    VERSION 1.0.0
-    SOURCES
-        private/src/bar_activator
-        private/src/bar.c
-)
-
-IF(APPLE)
-    target_link_libraries(bar PRIVATE Celix::framework  -Wl,-all_load dependency_manager_static)
-else()
-    if(ENABLE_ADDRESS_SANITIZER)
-        #With asan there can be undefined symbols
-        target_link_libraries(bar PRIVATE -Wl,--whole-archive dependency_manager_static -Wl,--no-whole-archive Celix::framework )
-    else()
-        target_link_libraries(bar PRIVATE -Wl,--no-undefined -Wl,--whole-archive dependency_manager_static -Wl,--no-whole-archive Celix::framework )
-    endif()
-endif()

http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/services_example_c/bar/private/include/bar.h
----------------------------------------------------------------------
diff --git a/examples/celix-examples/services_example_c/bar/private/include/bar.h b/examples/celix-examples/services_example_c/bar/private/include/bar.h
deleted file mode 100644
index 5e1da8b..0000000
--- a/examples/celix-examples/services_example_c/bar/private/include/bar.h
+++ /dev/null
@@ -1,32 +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.
- */
-
-#ifndef BAR_H_
-#define BAR_H_
-
-#include "example.h"
-
-typedef struct bar_struct bar_t;
-
-bar_t* bar_create(void);
-void bar_destroy(bar_t *self);
-
-int bar_method(bar_t *self, int arg1, double arg2, double *out);
-
-#endif //BAR_H_

http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/services_example_c/bar/private/src/bar.c
----------------------------------------------------------------------
diff --git a/examples/celix-examples/services_example_c/bar/private/src/bar.c b/examples/celix-examples/services_example_c/bar/private/src/bar.c
deleted file mode 100644
index 5099201..0000000
--- a/examples/celix-examples/services_example_c/bar/private/src/bar.c
+++ /dev/null
@@ -1,58 +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 "bar.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <signal.h>
-#include <stdbool.h>
-#include <pthread.h>
-#include <assert.h>
-
-
-#define OK 0
-#define ERROR 1
-
-struct bar_struct {
-    double prefValue;
-};
-
-bar_t* bar_create(void) {
-    bar_t *self = calloc(1, sizeof(*self));
-    if (self != NULL) {
-        self->prefValue = 42;
-    } else {
-        //log error
-    }
-    return self;
-};
-
-void bar_destroy(bar_t *self) {
-    free(self);
-}
-
-int bar_method(bar_t *self, int arg1, double arg2, double *out) {
-    double update = (self->prefValue + arg1) * arg2;
-    self->prefValue = update;
-    *out = update;
-    return OK;
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/services_example_c/bar/private/src/bar_activator.c
----------------------------------------------------------------------
diff --git a/examples/celix-examples/services_example_c/bar/private/src/bar_activator.c b/examples/celix-examples/services_example_c/bar/private/src/bar_activator.c
deleted file mode 100644
index 0fa7889..0000000
--- a/examples/celix-examples/services_example_c/bar/private/src/bar_activator.c
+++ /dev/null
@@ -1,70 +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 "dm_activator.h"
-#include "bar.h"
-
-#include <stdlib.h>
-
-struct activator {
-	bar_t *bar;
-	example_t exampleService;
-};
-
-celix_status_t dm_create(bundle_context_pt context, void **userData) {
-	celix_status_t status = CELIX_SUCCESS;
-	struct activator *act = calloc(1, sizeof(*act));
-	if (act != NULL) {
-
-		act->bar = bar_create();
-		act->exampleService.handle = act->bar;
-		act->exampleService.method = (void*) bar_method;
-
-		if (act->bar != NULL) {
-            *userData = act;
-        } else {
-            free(act);
-        }
-	} else {
-		status = CELIX_ENOMEM;
-	}
-	return status;
-}
-
-celix_status_t dm_init(void *userData, bundle_context_pt context, dm_dependency_manager_pt manager) {
-    celix_status_t status = CELIX_SUCCESS;
-	struct activator *activator = userData;
-
-	dm_component_pt cmp = NULL;
-	component_create(context, "BAR", &cmp);
-	component_setImplementation(cmp, activator->bar);
-	component_addInterface(cmp, EXAMPLE_NAME, EXAMPLE_VERSION, &activator->exampleService, NULL);
-
-	dependencyManager_add(manager, cmp);
-    return status;
-}
-
-celix_status_t dm_destroy(void *userData, bundle_context_pt context, dm_dependency_manager_pt manager) {
-	celix_status_t status = CELIX_SUCCESS;
-	struct activator *activator = userData;
-	bar_destroy(activator->bar);
-	free(activator);
-	return status;
-};
-

http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/services_example_c/foo1/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/celix-examples/services_example_c/foo1/CMakeLists.txt b/examples/celix-examples/services_example_c/foo1/CMakeLists.txt
deleted file mode 100644
index d732c76..0000000
--- a/examples/celix-examples/services_example_c/foo1/CMakeLists.txt
+++ /dev/null
@@ -1,39 +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_directories(
-        private/include
-)
-
-add_celix_bundle(foo1
-    SYMBOLIC_NAME foo1
-    VERSION 1.0.0
-    SOURCES
-        private/src/foo1_activator
-        private/src/foo1.c
-)
-
-IF(APPLE)
-    target_link_libraries(foo1 PRIVATE -Wl,-all_load dependency_manager_static)
-else()
-    if(ENABLE_ADDRESS_SANITIZER)
-        #With asan there can be undefined symbols
-        target_link_libraries(foo1 PRIVATE -Wl,--whole-archive dependency_manager_static -Wl,--no-whole-archive)
-    else()
-        target_link_libraries(foo1 PRIVATE -Wl,--no-undefined -Wl,--whole-archive dependency_manager_static -Wl,--no-whole-archive)
-    endif()
-endif()

http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/services_example_c/foo1/private/include/foo1.h
----------------------------------------------------------------------
diff --git a/examples/celix-examples/services_example_c/foo1/private/include/foo1.h b/examples/celix-examples/services_example_c/foo1/private/include/foo1.h
deleted file mode 100644
index f556b44..0000000
--- a/examples/celix-examples/services_example_c/foo1/private/include/foo1.h
+++ /dev/null
@@ -1,36 +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.
- */
-
-#ifndef FOO1_H_
-#define FOO1_H_
-
-#include "example.h"
-
-typedef struct foo1_struct foo1_t;
-
-foo1_t* foo1_create(void);
-void foo1_destroy(foo1_t *self);
-
-int foo1_start(foo1_t *self);
-int foo1_stop(foo1_t *self);
-
-int foo1_setExample(foo1_t *self, const example_t *example);
-
-
-#endif //FOO1_H_

http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/services_example_c/foo1/private/src/foo1.c
----------------------------------------------------------------------
diff --git a/examples/celix-examples/services_example_c/foo1/private/src/foo1.c b/examples/celix-examples/services_example_c/foo1/private/src/foo1.c
deleted file mode 100644
index 1f1f56f..0000000
--- a/examples/celix-examples/services_example_c/foo1/private/src/foo1.c
+++ /dev/null
@@ -1,102 +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 "foo1.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <signal.h>
-#include <stdbool.h>
-#include <pthread.h>
-#include <assert.h>
-
-
-#define OK 0
-#define ERROR 1
-
-static void* foo1_thread(void*);
-
-struct foo1_struct {
-    const example_t *example;
-    pthread_mutex_t mutex; //protecting example
-    pthread_t thread;
-    bool running;
-};
-
-foo1_t* foo1_create(void) {
-    foo1_t *self = calloc(1, sizeof(*self));
-    if (self != NULL) {
-        pthread_mutex_init(&self->mutex, NULL);
-        self->running = false;
-    } else {
-        //log error
-    }
-    return self;
-};
-
-void foo1_destroy(foo1_t *self) {
-    assert(!self->running);
-    pthread_mutex_destroy(&self->mutex);
-    free(self);
-}
-
-int foo1_start(foo1_t *self) {
-    printf("starting foo1\n");
-    self->running = true;
-    pthread_create(&self->thread, NULL, foo1_thread, self);
-    return OK;
-}
-
-int foo1_stop(foo1_t *self) {
-    printf("stopping foo1\n");
-    self->running = false;
-    pthread_kill(self->thread, SIGUSR1);
-    pthread_join(self->thread, NULL);
-    return OK;
-}
-
-int foo1_setExample(foo1_t *self, const example_t *example) {
-    printf("Setting example %p for foo1\n", example);
-    pthread_mutex_lock(&self->mutex);
-    self->example = example; //NOTE could be NULL if req is not mandatory
-    pthread_mutex_unlock(&self->mutex);
-    return OK;
-}
-
-static void* foo1_thread(void *userdata) {
-    foo1_t *self = userdata;
-    double result;
-    int rc;
-    while (self->running) {
-        pthread_mutex_lock(&self->mutex);
-        if (self->example != NULL) {
-            rc = self->example->method(self->example->handle, 1, 2.0, &result);
-            if (rc == 0) {
-                printf("Result is %f\n", result);
-            } else {
-                printf("Error invoking method for example\n");
-            }
-        }
-        pthread_mutex_unlock(&self->mutex);
-        usleep(30000000);
-    }
-    return NULL;
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/services_example_c/foo1/private/src/foo1_activator.c
----------------------------------------------------------------------
diff --git a/examples/celix-examples/services_example_c/foo1/private/src/foo1_activator.c b/examples/celix-examples/services_example_c/foo1/private/src/foo1_activator.c
deleted file mode 100644
index f94888b..0000000
--- a/examples/celix-examples/services_example_c/foo1/private/src/foo1_activator.c
+++ /dev/null
@@ -1,88 +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 "dm_activator.h"
-#include "foo1.h"
-
-#include <stdlib.h>
-
-struct activator {
-	foo1_t *foo;
-};
-
-celix_status_t dm_create(bundle_context_pt context, void **userData) {
-	celix_status_t status = CELIX_SUCCESS;
-	struct activator *act = calloc(1, sizeof(*act));
-	if (act != NULL) {
-		act->foo = foo1_create();
-        if (act->foo != NULL) {
-            *userData = act;
-        } else {
-            free(act);
-        }
-	} else {
-		status = CELIX_ENOMEM;
-	}
-	return status;
-}
-
-celix_status_t dm_init(void *userData, bundle_context_pt context, dm_dependency_manager_pt manager) {
-    celix_status_t status = CELIX_SUCCESS;
-	struct activator *activator = userData;
-
-	dm_component_pt cmp = NULL;
-	component_create(context, "FOO1", &cmp);
-	component_setImplementation(cmp, activator->foo);
-
-	/*
-	With the component_setCallbacksSafe we register callbacks when a component is started / stopped using a component
-	 with type foo1_t*
-	*/
-    component_setCallbacksSafe(cmp, foo1_t*, NULL, foo1_start, foo1_stop, NULL);
-
-	dm_service_dependency_pt dep = NULL;
-	serviceDependency_create(&dep);
-	serviceDependency_setRequired(dep, true);
-	serviceDependency_setService(dep, EXAMPLE_NAME, EXAMPLE_CONSUMER_RANGE, NULL);
-	serviceDependency_setStrategy(dep, DM_SERVICE_DEPENDENCY_STRATEGY_LOCKING);
-
-	/*
-	With the serviceDependency_setCallbacksSafe we register callbacks when a service
-	is added and about to be removed for the component type foo1_t* and service type example_t*.
-
-	We should protect the usage of the
- 	service because after removal of the service the memory location of that service
-	could be freed
-	*/
-    serviceDependency_setCallbacksSafe(dep, foo1_t*, const example_t*, foo1_setExample, NULL, NULL, NULL, NULL);
-	component_addServiceDependency(cmp, dep);
-
-	dependencyManager_add(manager, cmp);
-
-    return status;
-}
-
-celix_status_t dm_destroy(void *userData, bundle_context_pt context, dm_dependency_manager_pt manager) {
-	celix_status_t status = CELIX_SUCCESS;
-	struct activator *activator = userData;
-	foo1_destroy(activator->foo);
-	free(activator);
-	return status;
-};
-

http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/services_example_c/foo2/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/celix-examples/services_example_c/foo2/CMakeLists.txt b/examples/celix-examples/services_example_c/foo2/CMakeLists.txt
deleted file mode 100644
index adb8f64..0000000
--- a/examples/celix-examples/services_example_c/foo2/CMakeLists.txt
+++ /dev/null
@@ -1,39 +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_directories(
-        private/include
-)
-
-add_celix_bundle(foo2
-    SYMBOLIC_NAME foo2
-    VERSION 1.0.0
-    SOURCES
-        private/src/foo2_activator
-        private/src/foo2.c
-)
-
-IF(APPLE)
-    target_link_libraries(foo2 PRIVATE -Wl,-all_load dependency_manager_static)
-else()
-    if(ENABLE_ADDRESS_SANITIZER)
-        #With asan there can be undefined symbols
-        target_link_libraries(foo2 PRIVATE -Wl,--whole-archive dependency_manager_static -Wl,--no-whole-archive)
-    else()
-        target_link_libraries(foo2 PRIVATE -Wl,--no-undefined -Wl,--whole-archive dependency_manager_static -Wl,--no-whole-archive)
-    endif()
-endif()

http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/services_example_c/foo2/private/include/foo2.h
----------------------------------------------------------------------
diff --git a/examples/celix-examples/services_example_c/foo2/private/include/foo2.h b/examples/celix-examples/services_example_c/foo2/private/include/foo2.h
deleted file mode 100644
index 9f09276..0000000
--- a/examples/celix-examples/services_example_c/foo2/private/include/foo2.h
+++ /dev/null
@@ -1,36 +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.
- */
-
-#ifndef FOO2_H_
-#define FOO2_H_
-
-#include "example.h"
-
-typedef struct foo2_struct foo2_t;
-
-foo2_t* foo2_create(void);
-void foo2_destroy(foo2_t *self);
-
-int foo2_start(foo2_t *self);
-int foo2_stop(foo2_t *self);
-
-int foo2_addExample(foo2_t *self, const example_t *example);
-int foo2_removeExample(foo2_t *self, const example_t *example);
-
-#endif //FOO2_H_
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/services_example_c/foo2/private/src/foo2.c
----------------------------------------------------------------------
diff --git a/examples/celix-examples/services_example_c/foo2/private/src/foo2.c b/examples/celix-examples/services_example_c/foo2/private/src/foo2.c
deleted file mode 100644
index b98e20b..0000000
--- a/examples/celix-examples/services_example_c/foo2/private/src/foo2.c
+++ /dev/null
@@ -1,113 +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 "foo2.h"
-
-#include "array_list.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <signal.h>
-#include <stdbool.h>
-#include <pthread.h>
-#include <assert.h>
-
-
-#define OK 0
-#define ERROR 1
-
-static void* foo2_thread(void*);
-
-struct foo2_struct {
-    array_list_pt examples;
-    pthread_t thread;
-    bool running;
-};
-
-foo2_t* foo2_create(void) {
-    foo2_t *self = calloc(1, sizeof(*self));
-    if (self != NULL) {
-        self->examples = NULL;
-        arrayList_create(&self->examples);
-        self->running = false;
-    } else {
-        //log error
-    }
-    return self;
-};
-
-void foo2_destroy(foo2_t *self) {
-    assert(!self->running);
-    arrayList_destroy(self->examples);
-    free(self);
-}
-
-int foo2_start(foo2_t *self) {
-    printf("starting foo2\n");
-    self->running = true;
-    pthread_create(&self->thread, NULL, foo2_thread, self);
-    return OK;
-}
-
-int foo2_stop(foo2_t *self) {
-    printf("stopping foo2\n");
-    self->running = false;
-    pthread_kill(self->thread, SIGUSR1);
-    pthread_join(self->thread, NULL);
-    return OK;
-}
-
-int foo2_addExample(foo2_t *self, const example_t *example) {
-    //NOTE foo2 is suspended -> thread is not running  -> safe to update
-    int status = OK;
-    printf("Adding example %p for foo2\n", example);
-    status = arrayList_add(self->examples, (void *)example);
-    return status;
-}
-
-int foo2_removeExample(foo2_t *self, const example_t *example) {
-    //NOTE foo2 is suspended -> thread is not running  -> safe to update
-    int status = OK;
-    printf("Removing example %p for foo2\n", example);
-    status = arrayList_removeElement(self->examples, (void*)example);
-    return status;
-}
-
-static void* foo2_thread(void *userdata) {
-    foo2_t *self = userdata;
-    double result;
-    int rc;
-    while (self->running) {
-        unsigned int size = arrayList_size(self->examples);
-        int i;
-        for (i = 0; i < size; i += 1) {
-            const example_t* example = arrayList_get(self->examples, i);
-            rc = example->method(example->handle, 1, 2.0, &result);
-            if (rc == 0) {
-                printf("Result is %f\n", result);
-            } else {
-                printf("Error invoking method for example\n");
-            }
-        }
-        usleep(15000000);
-    }
-    return NULL;
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/services_example_c/foo2/private/src/foo2_activator.c
----------------------------------------------------------------------
diff --git a/examples/celix-examples/services_example_c/foo2/private/src/foo2_activator.c b/examples/celix-examples/services_example_c/foo2/private/src/foo2_activator.c
deleted file mode 100644
index 5c047da..0000000
--- a/examples/celix-examples/services_example_c/foo2/private/src/foo2_activator.c
+++ /dev/null
@@ -1,88 +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 "dm_activator.h"
-#include "foo2.h"
-
-#include <stdlib.h>
-
-struct activator {
-	foo2_t *foo;
-};
-
-celix_status_t dm_create(bundle_context_pt context, void **userData) {
-	celix_status_t status = CELIX_SUCCESS;
-	struct activator *act = calloc(1, sizeof(*act));
-	if (act != NULL) {
-		act->foo = foo2_create();
-        if (act->foo != NULL) {
-            *userData = act;
-        } else {
-            free(act);
-        }
-	} else {
-		status = CELIX_ENOMEM;
-	}
-	return status;
-}
-
-celix_status_t dm_init(void *userData, bundle_context_pt context, dm_dependency_manager_pt manager) {
-    celix_status_t status = CELIX_SUCCESS;
-	struct activator *activator = userData;
-
-	dm_component_pt cmp = NULL;
-	component_create(context, "FOO2", &cmp);
-	component_setImplementation(cmp, activator->foo);
-
-	/*
-	With the component_setCallbacksSafe we register callbacks when a component is started / stopped using a component
-	 with type foo1_t*
-	*/
-    component_setCallbacksSafe(cmp, foo2_t*, NULL, foo2_start, foo2_stop, NULL);
-
-	dm_service_dependency_pt dep = NULL;
-	serviceDependency_create(&dep);
-	serviceDependency_setRequired(dep, false);
-	serviceDependency_setService(dep, EXAMPLE_NAME, EXAMPLE_CONSUMER_RANGE, NULL);
-	serviceDependency_setStrategy(dep, DM_SERVICE_DEPENDENCY_STRATEGY_SUSPEND);
-
-	/*
-	With the serviceDependency_setCallbacksSafe we register callbacks when a service
-	is added and about to be removed for the component type foo1_t* and service type example_t*.
-
-	We should protect the usage of the
- 	service because after removal of the service the memory location of that service
-	could be freed
-	*/
-    serviceDependency_setCallbacksSafe(dep, foo2_t*, const example_t*, NULL, foo2_addExample, NULL, foo2_removeExample, NULL);
-	component_addServiceDependency(cmp, dep);
-
-	dependencyManager_add(manager, cmp);
-
-    return status;
-}
-
-celix_status_t dm_destroy(void *userData, bundle_context_pt context, dm_dependency_manager_pt manager) {
-	celix_status_t status = CELIX_SUCCESS;
-	struct activator *activator = userData;
-	foo2_destroy(activator->foo);
-	free(activator);
-	return status;
-};
-

http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/services_example_c/src/consumer_example.c
----------------------------------------------------------------------
diff --git a/examples/celix-examples/services_example_c/src/consumer_example.c b/examples/celix-examples/services_example_c/src/consumer_example.c
new file mode 100644
index 0000000..c472662
--- /dev/null
+++ b/examples/celix-examples/services_example_c/src/consumer_example.c
@@ -0,0 +1,182 @@
+/**
+ *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 <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <constants.h>
+
+#include "example_calc.h"
+#include "bundle_activator.h"
+
+typedef struct activator_data {
+    int trackCount;
+    celix_bundle_context_t *ctx;
+    pthread_t thread;
+
+    pthread_mutex_t mutex; //protects running
+    bool running;
+} activator_data_t;
+
+static bool isRunning(activator_data_t *data) {
+    bool result = false;
+    pthread_mutex_lock(&data->mutex);
+    result = data->running;
+    pthread_mutex_unlock(&data->mutex);
+    return result;
+}
+
+static void setRunning(activator_data_t *data, bool val) {
+    pthread_mutex_lock(&data->mutex);
+    data->running = val;
+    pthread_mutex_unlock(&data->mutex);
+}
+
+struct info {
+    int result;
+    int count;
+};
+
+static void useCalc(void *handle, void *svc) {
+    struct info *i = handle;
+    example_calc_t *calc = svc;
+    i->result += calc->calc(calc->handle, 1);
+    i->count += 1;
+}
+
+static void gccExample(activator_data_t *data) {
+#ifdef __GNUC__
+
+    int result = 0;
+    long rank = 0;
+    long svcId = 0;
+
+    void use(void *handle, void *svc, const celix_properties_t *props) {
+        example_calc_t *calc = svc;
+        rank = celix_properties_getAsLong(props, OSGI_FRAMEWORK_SERVICE_RANKING, -1L);
+        svcId = celix_properties_getAsLong(props, OSGI_FRAMEWORK_SERVICE_ID, -1L);
+        result = calc->calc(calc->handle, 1);
+    }
+
+    celix_service_use_options_t opts;
+    memset(&opts, 0, sizeof(opts));
+
+    opts.serviceName = EXAMPLE_CALC_NAME;
+    opts.callbackHandle = NULL; //can be null for trampolines
+    opts.useWithProperties = use;
+    bool called = celix_bundleContext_useServiceWithOptions(data->ctx, &opts);
+
+    printf("Called func %s. Result is %i, rank is %li and svc id is %li\n", called ? "called" : "not called", result, rank, svcId);
+
+#endif
+}
+
+static void clangExample(activator_data_t *data) {
+#ifdef __clang__
+    /*TODO
+#include <Block.h>
+    __block result = 0;
+    __block rank = 0;
+    __block svcId = 0;
+
+    void (^use)(void *handle, void *svc, const celix_properties_t *props)  =  ^(void *handle, void *svc, const celix_properties_t *props) {
+        example_calc_t *calc = svc;
+        rank = celix_properties_getAsLong(props, OSGI_FRAMEWORK_SERVICE_RANKING, -1L);
+        svcId = celix_properties_getAsLong(props, OSGI_FRAMEWORK_SERVICE_ID, -1L);
+        result = calc->calc(calc->handle, 1);
+    };
+
+    celix_service_use_options_t opts;
+    memset(&opts, 0, sizeof(opts));
+
+    opts.serviceName = EXAMPLE_CALC_NAME;
+    opts.callbackHandle = NULL; //can be null for trampolines
+    opts.useWithProperties = use;
+    bool called = celix_bundleContext_useServiceWithOptions(data->ctx, &opts);
+
+    printf("Called func %s. Result is %i, rank is %li and svc id is %li\n", called ? "called" : "not called", result, rank, svcId);
+     */
+#endif
+}
+
+void * run(void *handle) {
+    activator_data_t *data = handle;
+
+    printf("starting consumer thread\n");
+
+    while (isRunning(data)) {
+
+        struct info info;
+        info.result = 0;
+        info.count = 0;
+        celix_bundleContext_useServices(data->ctx, EXAMPLE_CALC_NAME, &info, useCalc);
+        printf("Called calc services %i times, total result is %i\n", info.count, info.result);
+
+        gccExample(data); //gcc trampolines example (nested functions)
+
+        clangExample(data); //TODO use clang blocks
+
+        //TODO tracker example
+
+        sleep(5);
+    }
+
+    printf("exiting consumer thread\n");
+
+    pthread_exit(NULL);
+    return NULL;
+}
+
+celix_status_t bundleActivator_create(celix_bundle_context_t *ctx, void **out) {
+	celix_status_t status = CELIX_SUCCESS;
+    activator_data_t *data = calloc(1, sizeof(*data));
+    if (data != NULL) {
+       data->ctx = ctx;
+       data->trackCount = 0;
+       data->running = true;
+       pthread_mutex_init(&data->mutex, NULL);
+       *out = data;
+	} else {
+		status = CELIX_ENOMEM;
+	}
+	return status;
+}
+
+celix_status_t bundleActivator_start(void * handle, celix_bundle_context_t *ctx) {
+    activator_data_t *data = handle;
+    pthread_create(&data->thread, NULL, run, data);
+	return CELIX_SUCCESS;
+}
+
+celix_status_t bundleActivator_stop(void * handle, celix_bundle_context_t *ctx) {
+    activator_data_t *data = handle;
+    setRunning(data, false);
+    pthread_join(data->thread, NULL);
+    return CELIX_SUCCESS;
+}
+
+celix_status_t bundleActivator_destroy(void * handle, celix_bundle_context_t *ctx) {
+    activator_data_t *data = handle;
+    if (data != NULL) {
+        pthread_mutex_destroy(&data->mutex);
+        free(data);
+    }
+	return CELIX_SUCCESS;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/examples/celix-examples/services_example_c/src/provider_example.c
----------------------------------------------------------------------
diff --git a/examples/celix-examples/services_example_c/src/provider_example.c b/examples/celix-examples/services_example_c/src/provider_example.c
new file mode 100644
index 0000000..f322303
--- /dev/null
+++ b/examples/celix-examples/services_example_c/src/provider_example.c
@@ -0,0 +1,134 @@
+/**
+ *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 <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "example_calc.h"
+#include "bundle_activator.h"
+#include "constants.h"
+
+typedef struct activator_data {
+    long svcIds[100];
+    example_calc_t svc;
+    celix_bundle_context_t *ctx;
+    pthread_t thread;
+
+    pthread_mutex_t mutex; //protects running
+    bool running;
+} activator_data_t;
+
+
+static int calc(void *handle __attribute__((unused)), int input) {
+    return 42 * input;
+}
+
+static bool isRunning(activator_data_t *data) {
+    bool result = false;
+    pthread_mutex_lock(&data->mutex);
+    result = data->running;
+    pthread_mutex_unlock(&data->mutex);
+    return result;
+}
+
+static void setRunning(activator_data_t *data, bool val) {
+    pthread_mutex_lock(&data->mutex);
+    data->running = val;
+    pthread_mutex_unlock(&data->mutex);
+}
+
+void * run(void *handle) {
+    activator_data_t *data = handle;
+
+    printf("starting service register thread\n");
+
+    int i = 0;
+    bool up = true;
+    while (isRunning(data)) {
+        if (up) {
+            properties_t *props = properties_create();
+            celix_properties_setLong(props, OSGI_FRAMEWORK_SERVICE_RANKING, rand());
+            data->svcIds[i++] = celix_bundleContext_registerService(data->ctx, EXAMPLE_CALC_NAME, &data->svc, NULL, props);
+        } else { //down
+            celix_bundleContext_unregisterService(data->ctx, data->svcIds[i--]);
+        }
+        if (i == 99) {
+            up = false;
+        } else if (i == 0) {
+            up = true;
+        }
+        usleep(100000);
+    }
+
+    for (int i = 0; i < 100; ++i) {
+        long id = data->svcIds[i];
+        if (id >=0 ) {
+            celix_bundleContext_unregisterService(data->ctx, id);
+        }
+    }
+
+    printf("exiting service register thread\n");
+
+    pthread_exit(NULL);
+    return NULL;
+}
+
+celix_status_t bundleActivator_create(celix_bundle_context_t *ctx, void **out) {
+	celix_status_t status = CELIX_SUCCESS;
+    activator_data_t *data = calloc(1, sizeof(*data));
+    if (data != NULL) {
+       data->svc.handle = data;
+       data->svc.calc = calc;
+       data->ctx = ctx;
+       data->running = true;
+       pthread_mutex_init(&data->mutex, NULL);
+
+       for (int i = 0; i < 100; ++i) {
+           data->svcIds[i] = -1L;
+       }
+
+       *out = data;
+	} else {
+		status = CELIX_ENOMEM;
+	}
+	return status;
+}
+
+celix_status_t bundleActivator_start(void * handle, celix_bundle_context_t *ctx) {
+    activator_data_t *data = handle;
+    pthread_create(&data->thread, NULL, run ,data);
+	return CELIX_SUCCESS;
+}
+
+celix_status_t bundleActivator_stop(void * handle, celix_bundle_context_t *ctx) {
+    activator_data_t *data = handle;
+    setRunning(data, false);
+    pthread_join(data->thread, NULL);
+    return CELIX_SUCCESS;
+}
+
+celix_status_t bundleActivator_destroy(void * handle, celix_bundle_context_t *ctx) {
+    activator_data_t *data = handle;
+    if (data != NULL) {
+        pthread_mutex_destroy(&data->mutex);
+        free(data);
+    }
+	return CELIX_SUCCESS;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/framework/include/bundle_context.h
----------------------------------------------------------------------
diff --git a/framework/include/bundle_context.h b/framework/include/bundle_context.h
index 4ba5904..5ab777a 100644
--- a/framework/include/bundle_context.h
+++ b/framework/include/bundle_context.h
@@ -330,7 +330,7 @@ bool celix_bundleContext_useServiceWithId(
         long serviceId,
         const char *serviceName /*sanity check*/,
         void *callbackHandle,
-        void (*use)(void *handle, void* svc, const celix_properties_t *props, const celix_bundle_t *svcOwner)
+        void (*use)(void *handle, void* svc)
 );
 
 /**
@@ -352,7 +352,7 @@ bool celix_bundleContext_useService(
         celix_bundle_context_t *ctx,
         const char* serviceName,
         void *callbackHandle,
-        void (*use)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *svcOwner)
+        void (*use)(void *handle, void *svc)
 );
 
 /**
@@ -375,7 +375,7 @@ void celix_bundleContext_useServices(
         celix_bundle_context_t *ctx,
         const char* serviceName,
         void *callbackHandle,
-        void (*use)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *svcOwner)
+        void (*use)(void *handle, void *svc)
 );
 
 
@@ -392,7 +392,10 @@ typedef struct celix_service_use_options {
      * Callback info
      */
      void *callbackHandle;
-     void (*use)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *svcOwner);
+
+     void (*use)(void *handle, void *svc);
+     void (*useWithProperties)(void *handle, void *svc, const celix_properties_t *props);
+     void (*useWithOwner)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *svcOwner);
 } celix_service_use_options_t;
 
 /**

http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/framework/include/service_tracker.h
----------------------------------------------------------------------
diff --git a/framework/include/service_tracker.h b/framework/include/service_tracker.h
index 513b8cc..baf2a00 100644
--- a/framework/include/service_tracker.h
+++ b/framework/include/service_tracker.h
@@ -116,7 +116,9 @@ bool celix_serviceTracker_useHighestRankingService(
         celix_service_tracker_t *tracker,
         const char *serviceName /*sanity*/,
         void *callbackHandle,
-        void (*use)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *owner)
+        void (*use)(void *handle, void *svc),
+        void (*useWithProperties)(void *handle, void *svc, const celix_properties_t *props),
+        void (*useWithOwner)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *owner)
 );
 
 
@@ -127,7 +129,9 @@ void celix_serviceTracker_useServices(
         service_tracker_t *tracker,
         const char* serviceName /*sanity*/,
         void *callbackHandle,
-        void (*use)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *owner)
+        void (*use)(void *handle, void *svc),
+        void (*useWithProperties)(void *handle, void *svc, const celix_properties_t *props),
+        void (*useWithOwner)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *owner)
 );
 
 #ifdef __cplusplus

http://git-wip-us.apache.org/repos/asf/celix/blob/5872268f/framework/private/mock/bundle_context_mock.c
----------------------------------------------------------------------
diff --git a/framework/private/mock/bundle_context_mock.c b/framework/private/mock/bundle_context_mock.c
index bddd7fd..8225580 100644
--- a/framework/private/mock/bundle_context_mock.c
+++ b/framework/private/mock/bundle_context_mock.c
@@ -226,7 +226,7 @@ bool celix_bundleContext_useServiceWithId(
 		long serviceId,
 		const char *serviceName,
 		void *callbackHandle,
-		void (*use)(void *handle, void* svc, const properties_t *props, const bundle_t *owner)
+		void (*use)(void *handle, void* svc)
 ) {
 	mock_c()->actualCall("celix_bundleContext_registerServiceForLang")
 			->withPointerParameters("ctx", ctx)


[12/12] celix git commit: Merge branch 'develop' into feature/CELIX-426-cxx-api

Posted by pn...@apache.org.
Merge branch 'develop' into feature/CELIX-426-cxx-api


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

Branch: refs/heads/feature/CELIX-426-cxx-api
Commit: 8464f3d5c653af8076fc76e45c4b6f6ddf9b5e24
Parents: e3339ca 03df0ed
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Mon May 14 19:45:56 2018 +0200
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Mon May 14 19:45:56 2018 +0200

----------------------------------------------------------------------
 examples/celix-examples/CMakeLists.txt          |    8 +-
 .../best_practice_example_c/CMakeLists.txt      |   40 +
 .../best_practice_example_c/api/example.h       |   34 +
 .../best_practice_example_c/bar/CMakeLists.txt  |   39 +
 .../bar/private/include/bar.h                   |   32 +
 .../bar/private/src/bar.c                       |   58 +
 .../bar/private/src/bar_activator.c             |   70 +
 .../best_practice_example_c/foo1/CMakeLists.txt |   39 +
 .../foo1/private/include/foo1.h                 |   36 +
 .../foo1/private/src/foo1.c                     |  102 +
 .../foo1/private/src/foo1_activator.c           |   88 +
 .../best_practice_example_c/foo2/CMakeLists.txt |   39 +
 .../foo2/private/include/foo2.h                 |   36 +
 .../foo2/private/src/foo2.c                     |  113 +
 .../foo2/private/src/foo2_activator.c           |   88 +
 .../services_example_c/CMakeLists.txt           |   83 +-
 .../celix-examples/services_example_c/README.md |   58 +
 .../services_example_c/api/example.h            |   34 -
 .../services_example_c/api/example_calc.h       |   33 +
 .../services_example_c/bar/CMakeLists.txt       |   39 -
 .../bar/private/include/bar.h                   |   32 -
 .../services_example_c/bar/private/src/bar.c    |   58 -
 .../bar/private/src/bar_activator.c             |   70 -
 .../services_example_c/foo1/CMakeLists.txt      |   39 -
 .../foo1/private/include/foo1.h                 |   36 -
 .../services_example_c/foo1/private/src/foo1.c  |  102 -
 .../foo1/private/src/foo1_activator.c           |   88 -
 .../services_example_c/foo2/CMakeLists.txt      |   39 -
 .../foo2/private/include/foo2.h                 |   36 -
 .../services_example_c/foo2/private/src/foo2.c  |  113 -
 .../foo2/private/src/foo2_activator.c           |   88 -
 .../src/dynamic_consumer_example.c              |  187 ++
 .../src/dynamic_provider_example.c              |  133 +
 .../src/simple_consumer_example.c               |   85 +
 .../src/simple_provider_example.c               |   73 +
 framework/include/bundle.h                      |  115 +-
 framework/include/bundle_activator.h            |    1 +
 framework/include/bundle_context.h              |  640 +----
 framework/include/celix/dm/DependencyManager.h  |   80 +-
 framework/include/celix_api.h                   |   13 +-
 framework/include/celix_bundle.h                |  139 +-
 framework/include/celix_bundle_context.h        |  691 +++++
 framework/include/celix_service_factory.h       |   44 +
 framework/include/celix_types.h                 |    2 +
 framework/include/service_factory.h             |   22 +-
 framework/include/service_registry.h            |   14 +-
 framework/include/service_tracker.h             |    9 +-
 framework/private/mock/bundle_context_mock.c    |   59 +-
 framework/private/mock/framework_mock.c         |   10 +-
 .../private/mock/service_registration_mock.c    |   17 +
 framework/private/mock/service_registry_mock.c  |   18 +
 .../private/test/service_registration_test.cpp  |    9 +-
 framework/src/BundleImpl.c                      |    8 +-
 framework/src/bundle_context.c                  |  167 +-
 framework/src/bundle_context_private.h          |    3 +-
 framework/src/bundle_private.h                  |    9 +-
 framework/src/framework.c                       | 2566 +++++++++---------
 framework/src/framework_private.h               |    5 +-
 framework/src/service_registration.c            |   65 +-
 framework/src/service_registration_private.h    |   22 +-
 framework/src/service_registry.c                |   29 +-
 framework/src/service_registry_private.h        |    2 +-
 framework/src/service_tracker.c                 |   65 +-
 framework/tst/bundle_context_bundles_tests.cpp  |    4 +-
 framework/tst/bundle_context_services_test.cpp  |  147 +-
 shell/src/activator.c                           |   12 +-
 shell/src/dm_shell_list_command.c               |    2 +-
 utils/include/array_list.h                      |   36 +-
 utils/include/celix_array_list.h                |   84 +
 utils/include/celix_properties.h                |   78 +
 utils/include/properties.h                      |   40 -
 utils/src/array_list.c                          |  157 +-
 utils/src/array_list_private.h                  |    2 +-
 utils/src/properties.c                          |    1 +
 74 files changed, 4533 insertions(+), 3102 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/8464f3d5/examples/celix-examples/CMakeLists.txt
----------------------------------------------------------------------
diff --cc examples/celix-examples/CMakeLists.txt
index bd70065,2ade793..426e854
--- a/examples/celix-examples/CMakeLists.txt
+++ b/examples/celix-examples/CMakeLists.txt
@@@ -21,16 -21,14 +21,18 @@@ else (
      set(EXAMPLES true) #celix_subproject is only available in the celix project -> using examples dir in other project is also supported
  endif ()
  if (EXAMPLES)
 -    add_subdirectory(hello_world)
 -    add_subdirectory(hello_world_test)
 +    add_subdirectory(bundle_example_cxx)
  
+     add_subdirectory(services_example_c)
 +    add_subdirectory(services_example_cxx)
 +
-     add_subdirectory(hello_world)
-     add_subdirectory(hello_world_test)
  
-     add_subdirectory(services_example_c)
+     add_subdirectory(best_practice_example_c)
 -    add_subdirectory(services_example_cxx)
 +    add_subdirectory(best_practice_example_cxx)
 +
++    add_subdirectory(hello_world)
++    add_subdirectory(hello_world_test)
+ 
      add_subdirectory(dm_example)
      add_subdirectory(dm_example_cxx)
  

http://git-wip-us.apache.org/repos/asf/celix/blob/8464f3d5/framework/include/bundle.h
----------------------------------------------------------------------
diff --cc framework/include/bundle.h
index d33a96d,b105615..95ba61f
--- a/framework/include/bundle.h
+++ b/framework/include/bundle.h
@@@ -16,5 -16,125 +16,118 @@@
   *specific language governing permissions and limitations
   *under the License.
   */
 -/*
 - * bundle.h
 - *
 - *  \date       Mar 23, 2010
 - *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
 - *  \copyright	Apache License, Version 2.0
 - */
  
- #include "celix_bundle.h"
+ #ifndef BUNDLE_H_
+ #define BUNDLE_H_
+ 
+ #include "celix_types.h"
+ 
+ #include "celix_errno.h"
+ #include "bundle_state.h"
+ #include "bundle_archive.h"
+ #include "framework.h"
+ #include "wire.h"
+ #include "module.h"
+ #include "service_reference.h"
+ #include "bundle_context.h"
+ #include "celix_log.h"
+ #include "celix_threads.h"
+ 
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+ 
+ FRAMEWORK_EXPORT celix_status_t bundle_create(bundle_pt *bundle);
+ 
+ FRAMEWORK_EXPORT celix_status_t
+ bundle_createFromArchive(bundle_pt *bundle, framework_pt framework, bundle_archive_pt archive);
+ 
+ FRAMEWORK_EXPORT celix_status_t bundle_destroy(bundle_pt bundle);
+ 
+ FRAMEWORK_EXPORT celix_status_t bundle_isSystemBundle(bundle_pt bundle, bool *systemBundle);
+ 
+ FRAMEWORK_EXPORT celix_status_t bundle_getArchive(bundle_pt bundle, bundle_archive_pt *archive);
+ 
+ FRAMEWORK_EXPORT celix_status_t bundle_getCurrentModule(bundle_pt bundle, module_pt *module);
+ 
+ FRAMEWORK_EXPORT array_list_pt bundle_getModules(bundle_pt bundle);
+ 
+ FRAMEWORK_EXPORT void *bundle_getHandle(bundle_pt bundle);
+ 
+ FRAMEWORK_EXPORT void bundle_setHandle(bundle_pt bundle, void *handle);
+ 
+ FRAMEWORK_EXPORT activator_pt bundle_getActivator(bundle_pt bundle);
+ 
+ FRAMEWORK_EXPORT celix_status_t bundle_setActivator(bundle_pt bundle, activator_pt activator);
+ 
+ FRAMEWORK_EXPORT celix_status_t bundle_getContext(bundle_pt bundle, bundle_context_pt *context);
+ 
+ FRAMEWORK_EXPORT celix_status_t bundle_setContext(bundle_pt bundle, bundle_context_pt context);
+ 
+ FRAMEWORK_EXPORT celix_status_t bundle_getEntry(bundle_pt bundle, const char *name, char **entry);
+ 
+ FRAMEWORK_EXPORT celix_status_t bundle_start(bundle_pt bundle);
+ 
+ FRAMEWORK_EXPORT celix_status_t bundle_startWithOptions(bundle_pt bundle, int options);
+ 
+ FRAMEWORK_EXPORT celix_status_t bundle_update(bundle_pt bundle, const char *inputFile);
+ 
+ FRAMEWORK_EXPORT celix_status_t bundle_stop(bundle_pt bundle);
+ 
+ FRAMEWORK_EXPORT celix_status_t bundle_stopWithOptions(bundle_pt bundle, int options);
+ 
+ FRAMEWORK_EXPORT celix_status_t bundle_uninstall(bundle_pt bundle);
+ 
+ FRAMEWORK_EXPORT celix_status_t bundle_setState(bundle_pt bundle, bundle_state_e state);
+ 
+ FRAMEWORK_EXPORT celix_status_t bundle_setPersistentStateInactive(bundle_pt bundle);
+ 
+ FRAMEWORK_EXPORT celix_status_t bundle_setPersistentStateUninstalled(bundle_pt bundle);
+ 
+ FRAMEWORK_EXPORT void uninstallBundle(bundle_pt bundle);
+ 
+ FRAMEWORK_EXPORT celix_status_t bundle_revise(bundle_pt bundle, const char *location, const char *inputFile);
+ 
+ FRAMEWORK_EXPORT celix_status_t bundle_addModule(bundle_pt bundle, module_pt module);
+ 
+ FRAMEWORK_EXPORT celix_status_t bundle_closeModules(bundle_pt bundle);
+ 
+ // Service Reference Functions
+ FRAMEWORK_EXPORT array_list_pt getUsingBundles(service_reference_pt reference);
+ 
+ FRAMEWORK_EXPORT int compareTo(service_reference_pt a, service_reference_pt b);
+ 
+ FRAMEWORK_EXPORT celix_status_t bundle_getState(bundle_pt bundle, bundle_state_e *state);
+ 
+ FRAMEWORK_EXPORT celix_status_t bundle_isLockable(bundle_pt bundle, bool *lockable);
+ 
+ FRAMEWORK_EXPORT celix_status_t bundle_getLockingThread(bundle_pt bundle, celix_thread_t *thread);
+ 
+ FRAMEWORK_EXPORT celix_status_t bundle_lock(bundle_pt bundle, bool *locked);
+ 
+ FRAMEWORK_EXPORT celix_status_t bundle_unlock(bundle_pt bundle, bool *unlocked);
+ 
+ FRAMEWORK_EXPORT celix_status_t bundle_closeAndDelete(bundle_pt bundle);
+ 
+ FRAMEWORK_EXPORT celix_status_t bundle_close(bundle_pt bundle);
+ 
+ FRAMEWORK_EXPORT celix_status_t bundle_refresh(bundle_pt bundle);
+ 
+ FRAMEWORK_EXPORT celix_status_t bundle_getBundleId(bundle_pt bundle, long *id);
+ 
+ FRAMEWORK_EXPORT celix_status_t bundle_getRegisteredServices(bundle_pt bundle, array_list_pt *list);
+ 
+ FRAMEWORK_EXPORT celix_status_t bundle_getServicesInUse(bundle_pt bundle, array_list_pt *list);
+ 
+ FRAMEWORK_EXPORT celix_status_t bundle_setFramework(bundle_pt bundle, framework_pt framework);
+ 
+ FRAMEWORK_EXPORT celix_status_t bundle_getFramework(bundle_pt bundle, framework_pt *framework);
+ 
+ FRAMEWORK_EXPORT celix_status_t bundle_getBundleLocation(bundle_pt bundle, const char **location);
+ 
+ 
+ #ifdef __cplusplus
+ }
+ #endif
+ 
+ #endif /* BUNDLE_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/8464f3d5/framework/include/bundle_context.h
----------------------------------------------------------------------
diff --cc framework/include/bundle_context.h
index 3611e23,cf42314..74f904e
--- a/framework/include/bundle_context.h
+++ b/framework/include/bundle_context.h
@@@ -40,546 -41,129 +41,129 @@@
  #ifdef __cplusplus
  extern "C" {
  #endif
--
--celix_status_t
--bundleContext_create(framework_pt framework, framework_logger_pt, bundle_pt bundle, bundle_context_pt *bundle_context);
--
--celix_status_t bundleContext_destroy(bundle_context_pt context);
--
--FRAMEWORK_EXPORT celix_status_t bundleContext_getBundle(bundle_context_pt context, bundle_pt *bundle);
--
--FRAMEWORK_EXPORT celix_status_t bundleContext_getFramework(bundle_context_pt context, framework_pt *framework);
--
--FRAMEWORK_EXPORT celix_status_t
--bundleContext_installBundle(bundle_context_pt context, const char *location, bundle_pt *bundle);
--
--FRAMEWORK_EXPORT celix_status_t
--bundleContext_installBundle2(bundle_context_pt context, const char *location, const char *inputFile, bundle_pt *bundle);
--
--FRAMEWORK_EXPORT celix_status_t
--bundleContext_registerService(bundle_context_pt context, const char *serviceName, const void *svcObj,
--                              properties_pt properties, service_registration_pt *service_registration);
--
--FRAMEWORK_EXPORT celix_status_t
--bundleContext_registerServiceFactory(bundle_context_pt context, const char *serviceName, service_factory_pt factory,
--                                     properties_pt properties, service_registration_pt *service_registration);
--
--/**
-- * Get a service reference for the bundle context. When the service reference is no longer needed use bundleContext_ungetServiceReference.
-- * ServiceReference are coupled to a bundle context. Do not share service reference between bundles. Exchange the service.id instead.
-- * 
-- * @param context The bundle context
-- * @param serviceName The name of the service (objectClass) to get
-- * @param service_reference _output_ The found service reference, or NULL when no service is found.
-- * @return CELIX_SUCCESS on success
-- */
--FRAMEWORK_EXPORT celix_status_t bundleContext_getServiceReference(bundle_context_pt context, const char *serviceName,
--                                                                  service_reference_pt *service_reference);
--
--/** Same as bundleContext_getServiceReference, but than for a optional serviceName combined with a optional filter.
-- * The resulting array_list should be destroyed by the caller. For all service references return a unget should be called.
-- * 
-- * @param context the bundle context
-- * @param serviceName the serviceName, can be NULL
-- * @param filter the filter, can be NULL. If present will be combined (and) with the serviceName 
-- * @param service_references _output_ a array list, can be size 0. 
-- * @return CELIX_SUCCESS on success
-- */
--FRAMEWORK_EXPORT celix_status_t
--bundleContext_getServiceReferences(bundle_context_pt context, const char *serviceName, const char *filter,
--                                   array_list_pt *service_references);
--
--/**
-- * Retains (increases the ref count) the provided service reference. Can be used to retain a service reference.
-- * Note that this is a deviation from the OSGi spec, due to the fact that C has no garbage collect.
-- * 
-- * @param context the bundle context
-- * @param reference the service reference to retain
-- * @return CELIX_SUCCES on success
-- */
--FRAMEWORK_EXPORT celix_status_t
--bundleContext_retainServiceReference(bundle_context_pt context, service_reference_pt reference);
--
--/**
-- * Ungets the service references. If the ref counter of the service refernce goes to 0, the reference will be destroyed.
-- * This is coupled with the bundleContext_getServiceReference(s) and bundleContext_retainServiceReferenc.
-- * Note: That this is a deviation from the OSGi standard, due to the fact that C has no garbage collect.
-- * 
-- * @param context The bundle context.
-- * @param reference the service reference to unget
-- * @return CELIX_SUCCESS on success.
-- */
--FRAMEWORK_EXPORT celix_status_t
--bundleContext_ungetServiceReference(bundle_context_pt context, service_reference_pt reference);
--
--FRAMEWORK_EXPORT celix_status_t
--bundleContext_getService(bundle_context_pt context, service_reference_pt reference, void **service_instance);
--
--FRAMEWORK_EXPORT celix_status_t
--bundleContext_ungetService(bundle_context_pt context, service_reference_pt reference, bool *result);
--
--FRAMEWORK_EXPORT celix_status_t bundleContext_getBundles(bundle_context_pt context, array_list_pt *bundles);
--
--FRAMEWORK_EXPORT celix_status_t bundleContext_getBundleById(bundle_context_pt context, long id, bundle_pt *bundle);
--
--FRAMEWORK_EXPORT celix_status_t
--bundleContext_addServiceListener(bundle_context_pt context, service_listener_pt listener, const char *filter);
--
--FRAMEWORK_EXPORT celix_status_t
--bundleContext_removeServiceListener(bundle_context_pt context, service_listener_pt listener);
--
--FRAMEWORK_EXPORT celix_status_t bundleContext_addBundleListener(bundle_context_pt context, bundle_listener_pt listener);
--
--FRAMEWORK_EXPORT celix_status_t
--bundleContext_removeBundleListener(bundle_context_pt context, bundle_listener_pt listener);
--
--FRAMEWORK_EXPORT celix_status_t
--bundleContext_addFrameworkListener(bundle_context_pt context, framework_listener_pt listener);
--
--FRAMEWORK_EXPORT celix_status_t
--bundleContext_removeFrameworkListener(bundle_context_pt context, framework_listener_pt listener);
--
--/**
-- * Gets the config property - or environment variable if the config property does not exist - for the provided name.
-- *
-- * @param context The bundle context.
-- * @param name The name of the config property / environment variable to get.
-- * @param value A ptr to the output value. This will be set when a value is found or else will be set to NULL.
-- * @return 0 if successful.
-- */
--FRAMEWORK_EXPORT celix_status_t
--bundleContext_getProperty(bundle_context_pt context, const char *name, const char **value);
--
--/**
-- * Gets the config property - or environment variable if the config property does not exist - for the provided name.
-- *
-- * @param context The bundle context.
-- * @param name The name of the config property / environment variable to get.
-- * @param defaultValue The default value to return if no value is found.
-- * @param value A ptr to the output value. This will be set when a value is found or else will be set to NULL.
-- * @return 0 if successful.
-- */
--FRAMEWORK_EXPORT celix_status_t
--bundleContext_getPropertyWithDefault(bundle_context_pt context, const char *name, const char *defaultValue, const char **value);
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- 
- /**********************************************************************************************************************
-  **********************************************************************************************************************
-  * Updated API
-  **********************************************************************************************************************
-  **********************************************************************************************************************/
- 
- /**
-  * Gets the dependency manager for this bundle context.
-  *
-  * @return the dependency manager or NULL if unsuccessful.
-  */
- dm_dependency_manager_t* celix_bundleContext_getDependencyManager(celix_bundle_context_t *ctx);
- 
- /**
-  * Register a C lang service to the framework.
-  *
-  * @param ctx The bundle context
-  * @param serviceName the service name, cannot be NULL
-  * @param svc the service object. Normally a pointer to a service struct (e.g. a struct with function pointers)
-  * @param properties The meta properties assiated with the service. The service registration will take ownership of the properties (e.g. no destroy needed)
-  * @return The serviceId, which should be >= 0. If < 0 then the registration was unsuccessful.
-  */
- long celix_bundleContext_registerService(celix_bundle_context_t *ctx, const char *serviceName, void *svc, const char *serviceVersion, celix_properties_t *properties);
- 
- /**
- * Register a service for the specified language to the framework.
- *
- * @param ctx The bundle context
- * @param serviceName the service name, cannot be NULL
- * @param svc the service object. Normally a pointer to a service struct (e.g. a struct with function pointers)
- * @param properties The meta properties assiated with the service. The service registration will take ownership of the properties
- * @return The serviceId, which should >= 0. If < 0 then the registration was unsuccessful.
- */
- long celix_bundleContext_registerServiceForLang(celix_bundle_context_t *ctx, const char *serviceName, void *svc, const char *serviceVersion, const char* lang, celix_properties_t *properties);
- 
- //TODO register service factory
- 
- /**
-  * Unregister the service with service id. The service will only be unregistered if the bundle of the bundle context
-  * is the owner of the service.
-  *
-  * Will log an error if service id is unknown. Will silently ignore services ids < 0.
-  *
-  * @param ctx The bundle context
-  * @param serviceId The service id
-  */
- void celix_bundleContext_unregisterService(celix_bundle_context_t *ctx, long serviceId);
- 
- /**
-  * track service for the provided serviceName and/or filter.
-  * The highest ranking services will used for the callback.
-  * If a new and higher ranking services the callback with be called again with the new service.
-  * If a service is removed a the callback with be called with next highest ranking service or NULL as service.
-  *
-  * @param ctx The bundle context.
-  * @param serviceName The required service name to track
-  * @param versionRange Optional the service version range to track
-  * @param filter Optional the LDAP filter to use
-  * @param callbackHandle The data pointer, which will be used in the callbacks
-  * @param set is a required callback, which will be called when a new highest ranking service is set.
-  * @return the tracker id or < 0 if unsuccessful.
-  */
- long celix_bundleContext_trackService(
-         celix_bundle_context_t* ctx,
-         const char* serviceName,
-         void* callbackHandle,
-         void (*set)(void* handle, void* svc)
- );
- 
- /**
-  * track services for the provided serviceName and/or filter.
-  *
-  * @param ctx The bundle context.
-  * @param serviceName The required service name to track
-  * @param versionRange Optional the service version range to track
-  * @param filter Optional the LDAP filter to use
-  * @param callbackHandle The data pointer, which will be used in the callbacks
-  * @param add is a required callback, which will be called when a service is added and initially for the existing service.
-  * @param remove is a required callback, which will be called when a service is removed
-  * @return the tracker id or < 0 if unsuccessful.
-  */
- long celix_bundleContext_trackServices(
-         celix_bundle_context_t* ctx,
-         const char* serviceName,
-         void* callbackHandle,
-         void (*add)(void* handle, void* svc),
-         void (*remove)(void* handle, void* svc)
- );
- 
- typedef struct celix_service_tracker_options {
-     //service filter options
-     const char* serviceName;
-     const char* versionRange;
-     const char* filter;
-     const char* lang; //NULL -> 'CELIX_LANG_C'
- 
-     //callback options
-     void* callbackHandle;
- 
-     void (*set)(void *handle, void *svc); //highest ranking
-     void (*add)(void *handle, void *svc);
-     void (*remove)(void *handle, void *svc);
-     void (*modified)(void *handle, void *svc);
- 
-     void (*setWithProperties)(void *handle, void *svc, const celix_properties_t *props); //highest ranking
-     void (*addWithProperties)(void *handle, void *svc, const celix_properties_t *props);
-     void (*removeWithProperties)(void *handle, void *svc, const celix_properties_t *props);
-     void (*modifiedWithProperties)(void *handle, void *svc, const celix_properties_t *props);
- 
-     void (*setWithOwner)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *svcOwner); //highest ranking
-     void (*addWithOwner)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *svcOwner);
-     void (*removeWithOwner)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *svcOwner);
-     void (*modifiedWithOwner)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *svcOwner);
- } celix_service_tracking_options_t;
- 
- /**
-  * Tracks services using the provided tracker options.
-  * The tracker options are only using during this call and can safely be freed/reused after this call returns.
-  *
-  * @param ctx The bundle context.
-  * @param opts The pointer to the tracker options.
-  * @return the tracker id or < 0 if unsuccessful.
-  */
- long celix_bundleContext_trackServicesWithOptions(celix_bundle_context_t *ctx, const celix_service_tracking_options_t *opts);
- 
- 
- //TODO find services -> list of service ids.
- celix_array_list_t* celix_bundleContext_findServices(
-         celix_bundle_context_t *ctx,
-         const char *serviceName,
-         const char *versionRange,
-         const char *filter,
-         const char *lang
- );
- 
- /**
-  * Get and lock the service with the provided service id
-  * Invokes the provided callback with the found service.
-  * The svc, props and owner in the callback are only valid during the callback.
-  * If no service is found the callback will not be invoked
-  *
-  * This function will block till the callback is finished. As result it is possible to provide callback data from the
-  * stack.
-  *
-  * @param ctx The bundle context
-  * @param serviceId the service id.
-  * @param serviceName the service name of the service. Should match with the registered service name of the provided service id (sanity check)
-  * @param callbackHandle The data pointer, which will be used in the callbacks
-  * @param use The callback, which will be called when service is retrieved.
-  * @param bool returns true if a service was found.
-  */
- bool celix_bundleContext_useServiceWithId(
-         celix_bundle_context_t *ctx,
-         long serviceId,
-         const char *serviceName /*sanity check*/,
-         void *callbackHandle,
-         void (*use)(void *handle, void* svc, const celix_properties_t *props, const celix_bundle_t *svcOwner)
- );
- 
- /**
-  * Get and lock the current highest ranking service conform serviceName, versionRange an filter.
-  * Invokes the provided callback with the found service.
-  * The svc, props and owner in the callback are only valid during the callback.
-  * If no service is found the callback will not be invoked.
-  *
-  * This function will block till the callback is finished. As result it is possible to provide callback data from the
-  * stack.
-  *
-  * @param   ctx The bundle context
-  * @param   serviceName the required service name.
-  * @param   callbackHandle The data pointer, which will be used in the callbacks
-  * @param   use The callback, which will be called when service is retrieved.
-  * @return  True if a service was found.
-  */
- bool celix_bundleContext_useService(
-         celix_bundle_context_t *ctx,
-         const char* serviceName,
-         void *callbackHandle,
-         void (*use)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *svcOwner)
- );
- 
- /**
-  * Get and lock the current services conform serviceName, versionRange an filter.
-  * Invokes the provided callback with the found services.
-  * The svc, props and owner in the callback are only valid during the callback.
-  * If no services are found the callback will not be invoked.
-  *
-  * This function will block till the callback is finished. As result it is possible to provide callback data from the
-  * stack.
-  *
-  * @param   ctx The bundle context
-  * @param   serviceName the required service name.
-  * @param   serviceRange the optional service version range (e.g. '[1.0.0,2.0.0)' )
-  * @param   filter the optional filter.
-  * @param   callbackHandle The data pointer, which will be used in the callbacks
-  * @param   use The callback, which will be called for every service found.
-  */
- void celix_bundleContext_useServices(
-         celix_bundle_context_t *ctx,
-         const char* serviceName,
-         void *callbackHandle,
-         void (*use)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *svcOwner)
- );
--
--
- typedef struct celix_service_use_options {
++    
++    celix_status_t
++    bundleContext_create(framework_pt framework, framework_logger_pt, bundle_pt bundle, bundle_context_pt *bundle_context);
++    
++    celix_status_t bundleContext_destroy(bundle_context_pt context);
++    
++    FRAMEWORK_EXPORT celix_status_t bundleContext_getBundle(bundle_context_pt context, bundle_pt *bundle);
++    
++    FRAMEWORK_EXPORT celix_status_t bundleContext_getFramework(bundle_context_pt context, framework_pt *framework);
++    
++    FRAMEWORK_EXPORT celix_status_t
++    bundleContext_installBundle(bundle_context_pt context, const char *location, bundle_pt *bundle);
++    
++    FRAMEWORK_EXPORT celix_status_t
++    bundleContext_installBundle2(bundle_context_pt context, const char *location, const char *inputFile, bundle_pt *bundle);
++    
++    FRAMEWORK_EXPORT celix_status_t
++    bundleContext_registerService(bundle_context_pt context, const char *serviceName, const void *svcObj,
++                                  properties_pt properties, service_registration_pt *service_registration);
++    
++    FRAMEWORK_EXPORT celix_status_t
++    bundleContext_registerServiceFactory(bundle_context_pt context, const char *serviceName, service_factory_pt factory,
++                                         properties_pt properties, service_registration_pt *service_registration);
++    
 +    /**
-      * service filter options. Note the serviceName is required.
++     * Get a service reference for the bundle context. When the service reference is no longer needed use bundleContext_ungetServiceReference.
++     * ServiceReference are coupled to a bundle context. Do not share service reference between bundles. Exchange the service.id instead.
++     *
++     * @param context The bundle context
++     * @param serviceName The name of the service (objectClass) to get
++     * @param service_reference _output_ The found service reference, or NULL when no service is found.
++     * @return CELIX_SUCCESS on success
 +     */
-     const char *serviceName; //REQUIRED
-     const char *versionRange; //default will be empty
-     const char *filter; //default will be empty
-     const char *lang; //default will be LANG_C
- 
-     /**
-      * Callback info
++    FRAMEWORK_EXPORT celix_status_t bundleContext_getServiceReference(bundle_context_pt context, const char *serviceName,
++                                                                      service_reference_pt *service_reference);
++    
++    /** Same as bundleContext_getServiceReference, but than for a optional serviceName combined with a optional filter.
++     * The resulting array_list should be destroyed by the caller. For all service references return a unget should be called.
++     *
++     * @param context the bundle context
++     * @param serviceName the serviceName, can be NULL
++     * @param filter the filter, can be NULL. If present will be combined (and) with the serviceName
++     * @param service_references _output_ a array list, can be size 0.
++     * @return CELIX_SUCCESS on success
 +     */
-      void *callbackHandle;
-      void (*use)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *svcOwner);
- } celix_service_use_options_t;
- 
- /**
-  * Get and lock the current highest ranking service conform the service filter info from the provided options.
-  *
-  * Invokes the provided callback with the found service.
-  * The svc, props and owner in the callback are only valid during the callback.
-  * If no service is found the callback will not be invoked.
-  *
-  * This function will block till the callback is finished. As result it is possible to provide callback data from the
-  * stack.
-  *
-  * @param   ctx The bundle context.
-  * @param   serviceName the required service name.
-  * @param   opts The required options. Note that the serviceName is required.
-  * @return  True if a service was found.
-  */
- bool celix_bundleContext_useServiceWithOptions(
-         celix_bundle_context_t *ctx,
-         const celix_service_use_options_t *opts);
- 
- 
- /**
-  * Get and lock the current services conform the service filter info from the provided options.
-  *
-  * Invokes the provided callback with the found services.
-  * The svc, props and owner in the callback are only valid during the callback.
-  * If no services are found the callback will not be invoked.
-  * At least a serviceName needs to be provided, if not the callback is not invoked.
-  *
-  * This function will block till all the callbacks are finished. As result it is possible to provide callback data from the
-  * stack.
-  *
-  * @param   ctx The bundle context.
-  * @param   serviceName the required service name.
-  * @param   opts The required options. Note that the serviceName is required.
-  * @param   callbackHandle The data pointer, which will be used in the callbacks.
-  * @param   use The callback, which will be called for every service found.
-  */
- void celix_bundleContext_useServicesWithOptions(
-         celix_bundle_context_t *ctx,
-         const celix_service_use_options_t *opts);
- 
- 
- /**
-  * Install and optional start a bundle.
-  *
-  * @param ctx The bundle context
-  * @param bundleLoc The bundle location to the bundle zip file.
-  * @param autoStart If the bundle should also be started.
-  * @return the bundleId >= 0 or < 0 if the bundle could not be installed and possibly started.
-  */
- long celix_bundleContext_installBundle(celix_bundle_context_t *ctx, const char *bundleLoc, bool autoStart);
- 
- /**
-  * Uninstall the bundle with the provided bundle id. If needed the bundle will be stopped first.
-  *
-  * @param ctx The bundle context
-  * @param bundleId The bundle id to stop
-  * @return true if the bundle is correctly uninstalled. False if not.
-  */
- bool celix_bundleContext_uninstallBundle(celix_bundle_context_t *ctx, long bundleId);
- 
- 
- /**
-  * Service tracker options. This struct can be used to fine grained tune the
-  * requested bundle tracker ootions.
-  */
- typedef struct celix_bundle_tracker_options {
-     //TODO options to track framework & own bundle
- 
++    FRAMEWORK_EXPORT celix_status_t
++    bundleContext_getServiceReferences(bundle_context_pt context, const char *serviceName, const char *filter,
++                                       array_list_pt *service_references);
++    
 +    /**
-      * Handle used in the tracker callbacks.
++     * Retains (increases the ref count) the provided service reference. Can be used to retain a service reference.
++     * Note that this is a deviation from the OSGi spec, due to the fact that C has no garbage collect.
++     *
++     * @param context the bundle context
++     * @param reference the service reference to retain
++     * @return CELIX_SUCCES on success
 +     */
-     void* callbackHandle;
- 
++    FRAMEWORK_EXPORT celix_status_t
++    bundleContext_retainServiceReference(bundle_context_pt context, service_reference_pt reference);
++    
 +    /**
-      * Tracker callback when a bundle is installed.
-      * @param handle    The handle, contains the value of the callbackHandle.
-      * @param bundle    The bundle which has been started.
-      *                  The bundle pointer is only guaranteed to be valid during the callback.
++     * Ungets the service references. If the ref counter of the service refernce goes to 0, the reference will be destroyed.
++     * This is coupled with the bundleContext_getServiceReference(s) and bundleContext_retainServiceReferenc.
++     * Note: That this is a deviation from the OSGi standard, due to the fact that C has no garbage collect.
++     *
++     * @param context The bundle context.
++     * @param reference the service reference to unget
++     * @return CELIX_SUCCESS on success.
 +     */
-     void (*onStarted)(void *handle, const celix_bundle_t *bundle); //highest ranking
- 
++    FRAMEWORK_EXPORT celix_status_t
++    bundleContext_ungetServiceReference(bundle_context_pt context, service_reference_pt reference);
++    
++    FRAMEWORK_EXPORT celix_status_t
++    bundleContext_getService(bundle_context_pt context, service_reference_pt reference, void **service_instance);
++    
++    FRAMEWORK_EXPORT celix_status_t
++    bundleContext_ungetService(bundle_context_pt context, service_reference_pt reference, bool *result);
++    
++    FRAMEWORK_EXPORT celix_status_t bundleContext_getBundles(bundle_context_pt context, array_list_pt *bundles);
++    
++    FRAMEWORK_EXPORT celix_status_t bundleContext_getBundleById(bundle_context_pt context, long id, bundle_pt *bundle);
++    
++    FRAMEWORK_EXPORT celix_status_t
++    bundleContext_addServiceListener(bundle_context_pt context, service_listener_pt listener, const char *filter);
++    
++    FRAMEWORK_EXPORT celix_status_t
++    bundleContext_removeServiceListener(bundle_context_pt context, service_listener_pt listener);
++    
++    FRAMEWORK_EXPORT celix_status_t bundleContext_addBundleListener(bundle_context_pt context, bundle_listener_pt listener);
++    
++    FRAMEWORK_EXPORT celix_status_t
++    bundleContext_removeBundleListener(bundle_context_pt context, bundle_listener_pt listener);
++    
++    FRAMEWORK_EXPORT celix_status_t
++    bundleContext_addFrameworkListener(bundle_context_pt context, framework_listener_pt listener);
++    
++    FRAMEWORK_EXPORT celix_status_t
++    bundleContext_removeFrameworkListener(bundle_context_pt context, framework_listener_pt listener);
++    
 +    /**
-      * Tracker callback when a bundle is removed.
-      * @param handle    The handle, contains the value of the callbackHandle.
-      * @param bundle    The bundle which has been started.
-      *                  The bundle pointer is only guaranteed to be valid during the callback.
++     * Gets the config property - or environment variable if the config property does not exist - for the provided name.
++     *
++     * @param context The bundle context.
++     * @param name The name of the config property / environment variable to get.
++     * @param value A ptr to the output value. This will be set when a value is found or else will be set to NULL.
++     * @return 0 if successful.
 +     */
-     void (*onStopped)(void *handle, const celix_bundle_t *bundle);
- 
++    FRAMEWORK_EXPORT celix_status_t
++    bundleContext_getProperty(bundle_context_pt context, const char *name, const char **value);
++    
 +    /**
++     * Gets the config property - or environment variable if the config property does not exist - for the provided name.
 +     *
-      * @param handle    The handle, contains the value of the callbackHandle.
-      * @param event     The bundle event. Is only valid during the callback.
++     * @param context The bundle context.
++     * @param name The name of the config property / environment variable to get.
++     * @param defaultValue The default value to return if no value is found.
++     * @param value A ptr to the output value. This will be set when a value is found or else will be set to NULL.
++     * @return 0 if successful.
 +     */
-     void (*onBundleEvent)(void *handle, const celix_bundle_event_t *event);
- } celix_bundle_tracker_options_t;
- 
- /**
-  * Tracks bundles using the provided bundle tracker options.
-  * The tracker options are only using during this call and can safely be freed/reused after this call returns.
-  * (i.e. can be on the stack)
-  *
-  * @param ctx   The bundle context.
-  * @param opts  The pointer to the bundle tracker options.
-  * @return      The bundle tracker id or < 0 if unsuccessful.
-  */
- long celix_bundleContext_trackBundlesWithOptions(
-         celix_bundle_context_t* ctx,
-         const celix_bundle_tracker_options_t *opts
- );
- 
- //TODO except framework & own bundle
- /**
-  * track bundles
-  * The add bundle callback will also be called for already installed bundles.
-  *
-  * @param ctx               The bundle context.
-  * @param callbackHandle    The data pointer, which will be used in the callbacks
-  * @param add               The callback which will be called for started bundles.
-  * @param remove            The callback which will be called when bundles are stopped.
-  * @return                  The bundle tracker id or < 0 if unsuccessful.
-  */
- long celix_bundleContext_trackBundles(
-         celix_bundle_context_t* ctx,
-         void* callbackHandle,
-         void (*onStarted)(void* handle, const celix_bundle_t *bundle),
-         void (*onStopped)(void *handle, const celix_bundle_t *bundle)
- );
- 
- /**
-  * Use the bundle with the provided bundle id if it is in the active (started) state
-  * The provided callback will be called if the bundle is found and in the active (started) state.
-  *
-  * @param ctx               The bundle context.
-  * @param bundleId          The bundle id.
-  * @param callbackHandle    The data pointer, which will be used in the callbacks
-  * @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.
-  */
- bool celix_bundleContext_useBundle(
-         celix_bundle_context_t *ctx,
-         long bundleId,
-         void *callbackHandle,
-         void (*use)(void *handle, const celix_bundle_t *bundle)
- );
- 
- //TODO except framework & own bundle
- /**
-  * Use the currently active (started) bundles.
-  * The provided callback will be called for all the currently started bundles.
-  *
-  * @param ctx               The bundle context.
-  * @param callbackHandle    The data pointer, which will be used in the callbacks
-  * @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_useBundles(
-         celix_bundle_context_t *ctx,
-         void *callbackHandle,
-         void (*use)(void *handle, const celix_bundle_t *bundle)
- );
- 
- 
- //TODO trackerServiceTracker
- 
- /**
-  * Stop the tracker with the provided track id.
-  * Could be a service tracker, bundle tracker or service tracker tracker.
-  * Only works for the trackers owned by the bundle of the bundle context.
-  *
-  * Will log a error if the provided tracker id is unknown. Will silently ignore trackerId < 0.
-  */
- void celix_bundleContext_stopTracker(celix_bundle_context_t *ctx, long trackerId);
- 
- 
- 
++    FRAMEWORK_EXPORT celix_status_t
++    bundleContext_getPropertyWithDefault(bundle_context_pt context, const char *name, const char *defaultValue, const char **value);
++    
++    
  #ifdef __cplusplus
  }
  #endif

http://git-wip-us.apache.org/repos/asf/celix/blob/8464f3d5/framework/include/celix/dm/DependencyManager.h
----------------------------------------------------------------------
diff --cc framework/include/celix/dm/DependencyManager.h
index e9a74a4,f90a03c..5a4dd99
--- a/framework/include/celix/dm/DependencyManager.h
+++ b/framework/include/celix/dm/DependencyManager.h
@@@ -31,36 -29,39 +31,36 @@@
  #include <vector>
  #include <mutex>
  
 -#ifndef CELIX_DM_DEPENDENCYMANAGER_H
 -#define CELIX_DM_DEPENDENCYMANAGER_H
 -
  namespace celix { namespace dm {
--
++    
      class DependencyManager {
      public:
          DependencyManager(bundle_context_pt ctx) : context(ctx) {
--                this->cDepMan = celix_bundleContext_getDependencyManager(ctx);
++            this->cDepMan = celix_bundleContext_getDependencyManager(ctx);
          }
--
++        
          virtual ~DependencyManager() {
--                this->cDepMan = nullptr;
++            this->cDepMan = nullptr;
          }
--
++        
          DependencyManager(DependencyManager&& mgr) : componentsMutex{} {
--                std::lock_guard<std::recursive_mutex> lock(this->componentsMutex);
--                mgr.context = this->context;
--                mgr.queuedComponents = std::move(this->queuedComponents);
--                mgr.startedComponents = std::move(this->startedComponents);
--                mgr.cDepMan = this->cDepMan;
--                this->cDepMan = nullptr;
--                this->context = nullptr;
++            std::lock_guard<std::recursive_mutex> lock(this->componentsMutex);
++            mgr.context = this->context;
++            mgr.queuedComponents = std::move(this->queuedComponents);
++            mgr.startedComponents = std::move(this->startedComponents);
++            mgr.cDepMan = this->cDepMan;
++            this->cDepMan = nullptr;
++            this->context = nullptr;
          }
          DependencyManager& operator=(DependencyManager&&) = default;
--
++        
          DependencyManager(const DependencyManager&) = delete;
          DependencyManager& operator=(const DependencyManager&) = delete;
--
++        
          bundle_context_pt bundleContext() const { return context; }
          dm_dependency_manager_pt cDependencyManager() const { return cDepMan; }
--
--
++        
++        
          /**
           * Creates and adds a new DM Component for a component of type T.
           *
@@@ -68,7 -69,7 +68,7 @@@
           */
          template<class T>
          Component<T>& createComponent(std::string name = std::string{});
--
++        
          /**
           * Creates and adds a new DM Component for a component of type T and setting
           * the instance using a unique ptr.
@@@ -77,7 -78,7 +77,7 @@@
           */
          template<class T>
          Component<T>& createComponent(std::unique_ptr<T>&& rhs, std::string name = std::string{});
--
++        
          /**
           * Creates and adds a new DM Component for a component of type T and setting
           * the instance using a shared ptr.
@@@ -86,7 -87,7 +86,7 @@@
           */
          template<class T>
          Component<T>& createComponent(std::shared_ptr<T> rhs, std::string name = std::string{});
--
++        
          /**
           * Creates and adds a new DM Component for a component of type T and setting
           * the instance.
@@@ -95,29 -96,29 +95,29 @@@
           */
          template<class T>
          Component<T>& createComponent(T rhs, std::string name = std::string{});
--
++        
          /**
           * Starts the Dependency Manager
           */
          void start() {
--                std::vector<std::unique_ptr<BaseComponent>> toBeStartedComponents {};
--                {
--                        std::lock_guard<std::recursive_mutex> lock(componentsMutex);
--                        for (auto it = queuedComponents.begin(); it != queuedComponents.end(); ++it) {
--                                toBeStartedComponents.push_back(std::move(*it));
--                        }
--                        queuedComponents.clear();
++            std::vector<std::unique_ptr<BaseComponent>> toBeStartedComponents {};
++            {
++                std::lock_guard<std::recursive_mutex> lock(componentsMutex);
++                for (auto it = queuedComponents.begin(); it != queuedComponents.end(); ++it) {
++                    toBeStartedComponents.push_back(std::move(*it));
                  }
--                for (auto it = toBeStartedComponents.begin(); it != toBeStartedComponents.end(); ++it) {
--
--                        dependencyManager_add(cDepMan, (*it)->cComponent());
--                        {
--                                std::lock_guard<std::recursive_mutex> lock(componentsMutex);
--                                startedComponents.push_back(std::move(*it));
--                        }
++                queuedComponents.clear();
++            }
++            for (auto it = toBeStartedComponents.begin(); it != toBeStartedComponents.end(); ++it) {
++                
++                dependencyManager_add(cDepMan, (*it)->cComponent());
++                {
++                    std::lock_guard<std::recursive_mutex> lock(componentsMutex);
++                    startedComponents.push_back(std::move(*it));
                  }
++            }
          }
--
++        
          /**
           * Removes a component from the  Dependency Manager and destroys it
           */
@@@ -125,14 -126,14 +125,14 @@@
          void destroyComponent(Component<T> &component) {
              dependencyManager_remove(cDepMan, component.cComponent());
          }
--
++        
          /**
           * Stops the Dependency Manager
           */
          void stop() {
--                dependencyManager_removeAllComponents(cDepMan);
--                queuedComponents.clear();
--                startedComponents.clear();
++            dependencyManager_removeAllComponents(cDepMan);
++            queuedComponents.clear();
++            startedComponents.clear();
          }
      private:
          bundle_context_pt context {nullptr};
@@@ -141,7 -142,7 +141,7 @@@
          dm_dependency_manager_pt cDepMan {nullptr};
          std::recursive_mutex componentsMutex{};
      };
--
++    
  }}
  
  #include "celix/dm/DependencyManager_Impl.h"

http://git-wip-us.apache.org/repos/asf/celix/blob/8464f3d5/framework/include/celix_bundle.h
----------------------------------------------------------------------
diff --cc framework/include/celix_bundle.h
index 6013635,74ea9bf..9b38627
--- a/framework/include/celix_bundle.h
+++ b/framework/include/celix_bundle.h
@@@ -36,116 -26,19 +26,19 @@@
  #ifdef __cplusplus
  extern "C" {
  #endif
- 
- FRAMEWORK_EXPORT celix_status_t bundle_create(bundle_pt *bundle);
- 
- FRAMEWORK_EXPORT celix_status_t
- bundle_createFromArchive(bundle_pt *bundle, framework_pt framework, bundle_archive_pt archive);
- 
- FRAMEWORK_EXPORT celix_status_t bundle_destroy(bundle_pt bundle);
- 
- FRAMEWORK_EXPORT celix_status_t bundle_isSystemBundle(bundle_pt bundle, bool *systemBundle);
- 
- FRAMEWORK_EXPORT celix_status_t bundle_getArchive(bundle_pt bundle, bundle_archive_pt *archive);
- 
- FRAMEWORK_EXPORT celix_status_t bundle_getCurrentModule(bundle_pt bundle, module_pt *module);
- 
- FRAMEWORK_EXPORT array_list_pt bundle_getModules(bundle_pt bundle);
- 
- FRAMEWORK_EXPORT void *bundle_getHandle(bundle_pt bundle);
- 
- FRAMEWORK_EXPORT void bundle_setHandle(bundle_pt bundle, void *handle);
- 
- FRAMEWORK_EXPORT activator_pt bundle_getActivator(bundle_pt bundle);
- 
- FRAMEWORK_EXPORT celix_status_t bundle_setActivator(bundle_pt bundle, activator_pt activator);
- 
- FRAMEWORK_EXPORT celix_status_t bundle_getContext(bundle_pt bundle, bundle_context_pt *context);
- 
- FRAMEWORK_EXPORT celix_status_t bundle_setContext(bundle_pt bundle, bundle_context_pt context);
- 
- FRAMEWORK_EXPORT celix_status_t bundle_getEntry(bundle_pt bundle, const char *name, char **entry);
- 
- FRAMEWORK_EXPORT celix_status_t bundle_start(bundle_pt bundle);
- 
- FRAMEWORK_EXPORT celix_status_t bundle_startWithOptions(bundle_pt bundle, int options);
- 
- FRAMEWORK_EXPORT celix_status_t bundle_update(bundle_pt bundle, const char *inputFile);
- 
- FRAMEWORK_EXPORT celix_status_t bundle_stop(bundle_pt bundle);
- 
- FRAMEWORK_EXPORT celix_status_t bundle_stopWithOptions(bundle_pt bundle, int options);
- 
- FRAMEWORK_EXPORT celix_status_t bundle_uninstall(bundle_pt bundle);
- 
- FRAMEWORK_EXPORT celix_status_t bundle_setState(bundle_pt bundle, bundle_state_e state);
- 
- FRAMEWORK_EXPORT celix_status_t bundle_setPersistentStateInactive(bundle_pt bundle);
- 
- FRAMEWORK_EXPORT celix_status_t bundle_setPersistentStateUninstalled(bundle_pt bundle);
- 
- FRAMEWORK_EXPORT void uninstallBundle(bundle_pt bundle);
- 
- FRAMEWORK_EXPORT celix_status_t bundle_revise(bundle_pt bundle, const char *location, const char *inputFile);
- 
- FRAMEWORK_EXPORT celix_status_t bundle_addModule(bundle_pt bundle, module_pt module);
- 
- FRAMEWORK_EXPORT celix_status_t bundle_closeModules(bundle_pt bundle);
- 
- // Service Reference Functions
- FRAMEWORK_EXPORT array_list_pt getUsingBundles(service_reference_pt reference);
- 
- FRAMEWORK_EXPORT int compareTo(service_reference_pt a, service_reference_pt b);
- 
- FRAMEWORK_EXPORT celix_status_t bundle_getState(bundle_pt bundle, bundle_state_e *state);
- 
- FRAMEWORK_EXPORT celix_status_t bundle_isLockable(bundle_pt bundle, bool *lockable);
- 
- FRAMEWORK_EXPORT celix_status_t bundle_getLockingThread(bundle_pt bundle, celix_thread_t *thread);
- 
- FRAMEWORK_EXPORT celix_status_t bundle_lock(bundle_pt bundle, bool *locked);
- 
- FRAMEWORK_EXPORT celix_status_t bundle_unlock(bundle_pt bundle, bool *unlocked);
- 
- FRAMEWORK_EXPORT celix_status_t bundle_closeAndDelete(bundle_pt bundle);
- 
- FRAMEWORK_EXPORT celix_status_t bundle_close(bundle_pt bundle);
- 
- FRAMEWORK_EXPORT celix_status_t bundle_refresh(bundle_pt bundle);
- 
- FRAMEWORK_EXPORT celix_status_t bundle_getBundleId(bundle_pt bundle, long *id);
- 
- FRAMEWORK_EXPORT celix_status_t bundle_getRegisteredServices(bundle_pt bundle, array_list_pt *list);
- 
- FRAMEWORK_EXPORT celix_status_t bundle_getServicesInUse(bundle_pt bundle, array_list_pt *list);
- 
- FRAMEWORK_EXPORT celix_status_t bundle_setFramework(bundle_pt bundle, framework_pt framework);
- 
- FRAMEWORK_EXPORT celix_status_t bundle_getFramework(bundle_pt bundle, framework_pt *framework);
- 
- FRAMEWORK_EXPORT celix_status_t bundle_getBundleLocation(bundle_pt bundle, const char **location);
- 
- 
--
--/**********************************************************************************************************************
-- **********************************************************************************************************************
-- * Updated API
-- **********************************************************************************************************************
-- **********************************************************************************************************************/
--
--long celix_bundle_getId(const bundle_t *bnd);
--
--celix_bundle_state_e celix_bundle_getState(const bundle_t *bnd);
--
- /**
-  * Note returned string pointer is owned by the caller.
-  * @param bnd
-  * @param relPath
-  * @return
-  */
- char* celix_bundle_getEntry(const bundle_t *bnd, const char *relPath);
--
--
++    
++    /**********************************************************************************************************************
++     **********************************************************************************************************************
++     * Updated API
++     **********************************************************************************************************************
++     **********************************************************************************************************************/
++    
++    long celix_bundle_getId(const bundle_t *bnd);
++    
++    celix_bundle_state_e celix_bundle_getState(const bundle_t *bnd);
++    
++    
++    
  #ifdef __cplusplus
  }
  #endif

http://git-wip-us.apache.org/repos/asf/celix/blob/8464f3d5/framework/private/mock/bundle_context_mock.c
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/celix/blob/8464f3d5/framework/private/mock/framework_mock.c
----------------------------------------------------------------------
diff --cc framework/private/mock/framework_mock.c
index 5aa06d3,7bbd752..86a2791
--- a/framework/private/mock/framework_mock.c
+++ b/framework/private/mock/framework_mock.c
@@@ -333,7 -333,14 +333,15 @@@ bool celix_framework_useBundle(framewor
  			->withLongIntParameters("bundleId", bundleId)
  			->withPointerParameters("callbackHandle", callbackHandle)
  			->withPointerParameters("use", use);
 +    return mock_c()->returnValue().value.boolValue;
  }
  
- 
+ 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) {
+ 	mock_c()->actualCall("celix_framework_registerServiceFactory")
+ 			->withPointerParameters("fw", fw)
+ 			->withConstPointerParameters("bnd", bnd)
+ 			->withStringParameters("serviceName", serviceName)
+ 			->withPointerParameters("factory", factory)
+ 			->withPointerParameters("properties", properties);
+ 	return mock_c()->returnValue().value.pointerValue;
+ }

http://git-wip-us.apache.org/repos/asf/celix/blob/8464f3d5/framework/src/BundleImpl.c
----------------------------------------------------------------------
diff --cc framework/src/BundleImpl.c
index fccabae,0000000..0fcba53
mode 100644,000000..100644
--- a/framework/src/BundleImpl.c
+++ b/framework/src/BundleImpl.c
@@@ -1,771 -1,0 +1,765 @@@
 +/**
 + *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.
 + */
- /*
-  * bundle.c
-  *
-  *  \date       Mar 23, 2010
-  *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
-  *  \copyright	Apache License, Version 2.0
-  */
++
 +#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/8464f3d5/framework/src/bundle_context.c
----------------------------------------------------------------------


[08/12] celix git commit: CELIX-446: Change a struct initialization for gcc 4

Posted by pn...@apache.org.
CELIX-446: Change a struct initialization for gcc 4


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

Branch: refs/heads/feature/CELIX-426-cxx-api
Commit: 3ba41cad6bab608d13e8a66d3865cab8cb578350
Parents: d754683
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Sat May 12 17:35:37 2018 +0200
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Sat May 12 17:35:37 2018 +0200

----------------------------------------------------------------------
 framework/tst/bundle_context_services_test.cpp | 10 ++++++----
 utils/include/array_list.h                     |  5 +++++
 utils/src/array_list.c                         | 10 +++++++---
 3 files changed, 18 insertions(+), 7 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/3ba41cad/framework/tst/bundle_context_services_test.cpp
----------------------------------------------------------------------
diff --git a/framework/tst/bundle_context_services_test.cpp b/framework/tst/bundle_context_services_test.cpp
index 6fa1204..ec7b92d 100644
--- a/framework/tst/bundle_context_services_test.cpp
+++ b/framework/tst/bundle_context_services_test.cpp
@@ -21,9 +21,6 @@
 #include <iostream>
 #include <mutex>
 #include <condition_variable>
-
-#include <CppUTest/TestHarness.h>
-#include <CppUTest/CommandLineTestRunner.h>
 #include <zconf.h>
 #include <string.h>
 #include <map>
@@ -35,6 +32,11 @@
 #include "celix_service_factory.h"
 
 
+#include <CppUTest/TestHarness.h>
+#include <CppUTest/CommandLineTestRunner.h>
+
+
+
 TEST_GROUP(CelixBundleContextServicesTests) {
     framework_t* fw = NULL;
     bundle_context_t *ctx = NULL;
@@ -601,7 +603,7 @@ TEST(CelixBundleContextServicesTests, serviceFactoryTest) {
     fac.getService = [](void *handle, const celix_bundle_t *, const celix_properties_t *) -> void* {
         auto *c = (int *)handle;
         *c += 1;
-        static struct calc svc{}; //normally a service per bundle
+        static struct calc svc; //normally a service per bundle
         svc.calc = [](int arg) { return arg * 42; };
         return &svc;
     };

http://git-wip-us.apache.org/repos/asf/celix/blob/3ba41cad/utils/include/array_list.h
----------------------------------------------------------------------
diff --git a/utils/include/array_list.h b/utils/include/array_list.h
index fa8602b..7003501 100644
--- a/utils/include/array_list.h
+++ b/utils/include/array_list.h
@@ -155,6 +155,11 @@ void celix_arrayList_addSize(celix_array_list_t *list, size_t val);
 
 int celix_arrayList_indexOf(celix_array_list_t *list, celix_array_list_entry_t entry);
 void celix_arrayList_remove(celix_array_list_t *list, int index);
+
+/**
+ * Remove entry from array list. To use this first memset the entry to null to ensure it completely initialized or
+ * ensure that the array list is created with a custom equals which matches the used entry.
+ */
 void celix_arrayList_removeEntry(celix_array_list_t *list, celix_array_list_entry_t entry);
 
 #ifdef __cplusplus

http://git-wip-us.apache.org/repos/asf/celix/blob/3ba41cad/utils/src/array_list.c
----------------------------------------------------------------------
diff --git a/utils/src/array_list.c b/utils/src/array_list.c
index ca12798..6a48c7a 100644
--- a/utils/src/array_list.c
+++ b/utils/src/array_list.c
@@ -122,7 +122,9 @@ int arrayList_indexOf(array_list_pt list, void * element) {
 	} else {
 		unsigned int i = 0;
 		for (i = 0; i < list->size; i++) {
-			celix_array_list_entry_t entry = { .voidPtrVal = element };
+			celix_array_list_entry_t entry;
+			memset(&entry, 0, sizeof(entry));
+			entry.voidPtrVal = element;
 			bool equals = celix_arrayList_equalsForElement(list, entry, list->elementData[i]);
 			if (equals) {
 				return i;
@@ -145,8 +147,9 @@ int arrayList_lastIndexOf(array_list_pt list, void * element) {
 		int i = 0;
 		int size = (int)list->size;
 		for (i = size - 1; i >= 0; i--) {
-			celix_array_list_entry_t entry = { .voidPtrVal = element };
-
+			celix_array_list_entry_t entry;
+			memset(&entry, 0, sizeof(entry));
+			entry.voidPtrVal = element;
 			bool equals = celix_arrayList_equalsForElement(list, entry, list->elementData[i]);
 			if (equals) {
 				return (int)i;
@@ -235,6 +238,7 @@ bool arrayList_removeElement(array_list_pt list, void * element) {
 		unsigned int i = 0;
 		for (i = 0; i < list->size; i++) {
 			celix_array_list_entry_t entry;
+			memset(&entry, 0, sizeof(entry));
 			entry.voidPtrVal = element;
 			bool equals = celix_arrayList_equalsForElement(list, entry, list->elementData[i]);
 			if (equals) {


[04/12] celix git commit: CELIX-446: Adds an initial implementation of a service factory which does not use the service_registration pointer and adds some documentation for the service example

Posted by pn...@apache.org.
CELIX-446: Adds an initial implementation of a service factory which does not use the service_registration pointer and adds some documentation for the service example


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

Branch: refs/heads/feature/CELIX-426-cxx-api
Commit: 626687fea7a0095e384a1a692af6a3984b06ca94
Parents: a4a1f50
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Thu May 10 21:36:53 2018 +0200
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Thu May 10 21:36:53 2018 +0200

----------------------------------------------------------------------
 .../services_example_c/CMakeLists.txt           |  30 ++-
 .../celix-examples/services_example_c/README.md |  58 ++++++
 .../services_example_c/api/example_calc.h       |   1 +
 .../services_example_c/src/consumer_example.c   | 184 ------------------
 .../src/dynamic_consumer_example.c              | 189 +++++++++++++++++++
 .../src/dynamic_provider_example.c              | 134 +++++++++++++
 .../services_example_c/src/provider_example.c   | 134 -------------
 .../src/simple_consumer_example.c               |  85 +++++++++
 .../src/simple_provider_example.c               |  73 +++++++
 framework/include/bundle_context.h              |  61 +++++-
 framework/include/celix_service_factory.h       |  43 +++++
 framework/include/celix_types.h                 |   2 +
 framework/include/service_factory.h             |  22 +--
 framework/include/service_registry.h            |  14 +-
 framework/private/mock/bundle_context_mock.c    |  21 +++
 framework/private/mock/framework_mock.c         |  10 +-
 .../private/mock/service_registration_mock.c    |  17 ++
 framework/private/mock/service_registry_mock.c  |  18 ++
 .../private/test/service_registration_test.cpp  |   9 +-
 framework/src/bundle_context.c                  |  39 +++-
 framework/src/framework.c                       |  18 ++
 framework/src/framework_private.h               |   3 +-
 framework/src/service_registration.c            |  61 +++---
 framework/src/service_registration_private.h    |  22 ++-
 framework/src/service_registry.c                |  25 ++-
 framework/src/service_registry_private.h        |   2 +-
 framework/tst/bundle_context_services_test.cpp  |  46 +++++
 27 files changed, 922 insertions(+), 399 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/626687fe/examples/celix-examples/services_example_c/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/celix-examples/services_example_c/CMakeLists.txt b/examples/celix-examples/services_example_c/CMakeLists.txt
index f56ddd8..43b88b2 100644
--- a/examples/celix-examples/services_example_c/CMakeLists.txt
+++ b/examples/celix-examples/services_example_c/CMakeLists.txt
@@ -21,24 +21,48 @@ target_include_directories(services_example_c_api INTERFACE api)
 
 add_celix_bundle(provider_example
         VERSION 1.0.0
-        SOURCES src/provider_example.c
+        SOURCES src/simple_provider_example.c
 )
 target_link_libraries(provider_example PRIVATE services_example_c_api)
 
 add_celix_bundle(consumer_example
         VERSION 1.0.0
-        SOURCES src/consumer_example.c
+        SOURCES src/simple_consumer_example.c
         )
 target_link_libraries(consumer_example PRIVATE services_example_c_api)
 
+
+
+add_celix_bundle(dynamic_provider_example
+        VERSION 1.0.0
+        SOURCES src/dynamic_provider_example.c
+)
+target_link_libraries(dynamic_provider_example PRIVATE services_example_c_api)
+
+add_celix_bundle(dynamic_consumer_example
+        VERSION 1.0.0
+        SOURCES src/dynamic_consumer_example.c
+)
+target_link_libraries(dynamic_consumer_example PRIVATE services_example_c_api)
+
 if ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")
-  target_compile_definitions(consumer_example PRIVATE USE_NESTED_FUNCTION_EXAMPLE)
+  target_compile_definitions(dynamic_consumer_example PRIVATE USE_NESTED_FUNCTION_EXAMPLE)
 endif()
 
 add_celix_container(services_example_c
+    GROUP services_example
     BUNDLES
         Celix::shell
         Celix::shell_tui
         provider_example
         consumer_example
 )
+
+add_celix_container(dynamic_services_example_c
+    GROUP services_example
+    BUNDLES
+      Celix::shell
+      Celix::shell_tui
+      dynamic_provider_example
+      dynamic_consumer_example
+)

http://git-wip-us.apache.org/repos/asf/celix/blob/626687fe/examples/celix-examples/services_example_c/README.md
----------------------------------------------------------------------
diff --git a/examples/celix-examples/services_example_c/README.md b/examples/celix-examples/services_example_c/README.md
new file mode 100644
index 0000000..a4f50ba
--- /dev/null
+++ b/examples/celix-examples/services_example_c/README.md
@@ -0,0 +1,58 @@
+<!--
+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.
+-->
+
+# Intro
+
+This example show how services can be provided and consumer by bundles.
+
+The example uses the `celix_bundleContext_registerService` to provide
+services and uses a combination of `celix_bundleContext_useService`,
+ `celix_bundleContext_useServices` and `celix_bundleContext_trackServices`
+ to consume services.
+
+ TODO intro bundle context
+
+ See the `bundle_context.h` for documentation about these - and other -functions
+
+# Simple Service Provider & Consumer Example
+
+The simple provider/consumer example can be executed by launching the
+`services_example_c` executable target
+(build in `${CMAKE_BUILD_DIR}/deploy/services_example/services_example_c`)
+
+In this example the provide bundle only register one calc service. And
+the consumer bundle tries to use this during startup and registerd
+a service tracker for the calc service.
+
+Try stopping/starting the provider / consumer bundles (respectively bundle id 3 & 4)
+to see how this work runtime. E.g. use `stop 3`, `stop 4`, `start 3`, `start 4` in different combinations.
+
+
+# Dynamic Service Provider & Consumer Example
+
+The dynamic provider/consumer example can be executed by launching the
+`dynamic_services_example_c` executable target
+(build in `${CMAKE_BUILD_DIR}/deploy/services_example/dynamic_services_example_c`)
+
+The dynamic service provide / consumer example show how the framework copes
+with the dynamic behaviour of services.
+
+This this example the provided dynammically register more and less calc services in a thread.
+The consumer bundle uses these services in a every 5 seconds and print some info.
+
+Hopefully this example will give an idea how services can be safely used and tracked in a dynamic environment.
+

http://git-wip-us.apache.org/repos/asf/celix/blob/626687fe/examples/celix-examples/services_example_c/api/example_calc.h
----------------------------------------------------------------------
diff --git a/examples/celix-examples/services_example_c/api/example_calc.h b/examples/celix-examples/services_example_c/api/example_calc.h
index 89481fa..8afe6c3 100644
--- a/examples/celix-examples/services_example_c/api/example_calc.h
+++ b/examples/celix-examples/services_example_c/api/example_calc.h
@@ -21,6 +21,7 @@
 #define CELIX_EXAMPLE_CALC_H
 
 #define EXAMPLE_CALC_NAME "example_calc"
+#define EXAMPLE_CALC_VERSION "1.0.0"
 
 struct example_calc {
     void *handle;

http://git-wip-us.apache.org/repos/asf/celix/blob/626687fe/examples/celix-examples/services_example_c/src/consumer_example.c
----------------------------------------------------------------------
diff --git a/examples/celix-examples/services_example_c/src/consumer_example.c b/examples/celix-examples/services_example_c/src/consumer_example.c
deleted file mode 100644
index 899cb57..0000000
--- a/examples/celix-examples/services_example_c/src/consumer_example.c
+++ /dev/null
@@ -1,184 +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 <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <constants.h>
-
-#include "example_calc.h"
-#include "bundle_activator.h"
-
-typedef struct activator_data {
-    celix_bundle_context_t *ctx;
-    pthread_t thread;
-
-    pthread_mutex_t mutex; //protects running
-    bool running;
-    int trackCount;
-} activator_data_t;
-
-static bool isRunning(activator_data_t *data) {
-    bool result = false;
-    pthread_mutex_lock(&data->mutex);
-    result = data->running;
-    pthread_mutex_unlock(&data->mutex);
-    return result;
-}
-
-static void setRunning(activator_data_t *data, bool val) {
-    pthread_mutex_lock(&data->mutex);
-    data->running = val;
-    pthread_mutex_unlock(&data->mutex);
-}
-
-struct info {
-    int result;
-    int count;
-};
-
-static void useCalc(void *handle, void *svc) {
-    struct info *i = handle;
-    example_calc_t *calc = svc;
-    i->result += calc->calc(calc->handle, 1);
-    i->count += 1;
-}
-
-static void gccExample(activator_data_t *data) {
-#ifdef USE_NESTED_FUNCTION_EXAMPLE
-
-    int result = 0;
-    long rank = 0;
-    long svcId = 0;
-
-    void use(void *handle, void *svc, const celix_properties_t *props) {
-        example_calc_t *calc = svc;
-        rank = celix_properties_getAsLong(props, OSGI_FRAMEWORK_SERVICE_RANKING, -1L);
-        svcId = celix_properties_getAsLong(props, OSGI_FRAMEWORK_SERVICE_ID, -1L);
-        result = calc->calc(calc->handle, 1);
-    }
-
-    celix_service_use_options_t opts;
-    memset(&opts, 0, sizeof(opts));
-
-    opts.serviceName = EXAMPLE_CALC_NAME;
-    opts.callbackHandle = NULL; //can be null for trampolines
-    opts.useWithProperties = use;
-    bool called = celix_bundleContext_useServiceWithOptions(data->ctx, &opts);
-
-    printf("Called func %s. Result is %i, rank is %li and svc id is %li\n", called ? "called" : "not called", result, rank, svcId);
-
-#endif
-}
-
-static void addSvc(activator_data_t *data, void *svc __attribute__((unused))) {
-    pthread_mutex_lock(&data->mutex);
-    data->trackCount += 1;
-    pthread_mutex_unlock(&data->mutex);
-}
-
-static void removeSvc(activator_data_t *data, void *svc __attribute__((unused))) {
-    pthread_mutex_lock(&data->mutex);
-    data->trackCount -= 1;
-    pthread_mutex_unlock(&data->mutex);
-}
-
-static void useHighest(activator_data_t *data __attribute__((unused)), example_calc_t *svc, const celix_properties_t *props) {
-    int result = svc->calc(svc->handle, 2);
-    long svcId = celix_properties_getAsLong(props, OSGI_FRAMEWORK_SERVICE_ID, -1L);
-    long rank = celix_properties_getAsLong(props, OSGI_FRAMEWORK_SERVICE_RANKING, -1L);
-    printf("Called highest ranking service. Result is %i, svc id is %li, svc ranking is %li\n", result, svcId, rank);
-}
-
-
-void * run(void *handle) {
-    activator_data_t *data = handle;
-
-    printf("starting consumer thread\n");
-    long trkId = celix_bundleContext_trackServices(data->ctx, EXAMPLE_CALC_NAME, data, (void*)addSvc, (void*)removeSvc);
-
-    while (isRunning(data)) {
-        struct info info;
-        info.result = 0;
-        info.count = 0;
-        celix_bundleContext_useServices(data->ctx, EXAMPLE_CALC_NAME, &info, useCalc);
-        printf("Called calc services %i times, total result is %i\n", info.count, info.result);
-
-        gccExample(data); //gcc trampolines example (nested functions)
-
-        celix_service_use_options_t opts;
-        memset(&opts, 0, sizeof(opts));
-
-        opts.serviceName = EXAMPLE_CALC_NAME;
-        opts.callbackHandle = data;
-        opts.useWithProperties = (void*)useHighest;
-        celix_bundleContext_useServiceWithOptions(data->ctx, &opts);
-
-        pthread_mutex_lock(&data->mutex);
-        int count = data->trackCount;
-        pthread_mutex_unlock(&data->mutex);
-        printf("Current tracking count is %i\n", count);
-
-        sleep(5);
-    }
-
-    celix_bundleContext_stopTracker(data->ctx, trkId);
-    printf("exiting consumer thread\n");
-
-    pthread_exit(NULL);
-    return NULL;
-}
-
-celix_status_t bundleActivator_create(celix_bundle_context_t *ctx, void **out) {
-	celix_status_t status = CELIX_SUCCESS;
-    activator_data_t *data = calloc(1, sizeof(*data));
-    if (data != NULL) {
-       data->ctx = ctx;
-       data->trackCount = 0;
-       data->running = true;
-       pthread_mutex_init(&data->mutex, NULL);
-       *out = data;
-	} else {
-		status = CELIX_ENOMEM;
-	}
-	return status;
-}
-
-celix_status_t bundleActivator_start(void * handle, celix_bundle_context_t *ctx) {
-    activator_data_t *data = handle;
-    pthread_create(&data->thread, NULL, run, data);
-	return CELIX_SUCCESS;
-}
-
-celix_status_t bundleActivator_stop(void * handle, celix_bundle_context_t *ctx) {
-    activator_data_t *data = handle;
-    setRunning(data, false);
-    pthread_join(data->thread, NULL);
-    return CELIX_SUCCESS;
-}
-
-celix_status_t bundleActivator_destroy(void * handle, celix_bundle_context_t *ctx) {
-    activator_data_t *data = handle;
-    if (data != NULL) {
-        pthread_mutex_destroy(&data->mutex);
-        free(data);
-    }
-	return CELIX_SUCCESS;
-}

http://git-wip-us.apache.org/repos/asf/celix/blob/626687fe/examples/celix-examples/services_example_c/src/dynamic_consumer_example.c
----------------------------------------------------------------------
diff --git a/examples/celix-examples/services_example_c/src/dynamic_consumer_example.c b/examples/celix-examples/services_example_c/src/dynamic_consumer_example.c
new file mode 100644
index 0000000..5a676d6
--- /dev/null
+++ b/examples/celix-examples/services_example_c/src/dynamic_consumer_example.c
@@ -0,0 +1,189 @@
+/**
+ *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 <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <constants.h>
+
+#include "example_calc.h"
+#include "bundle_activator.h"
+
+typedef struct activator_data {
+    celix_bundle_context_t *ctx;
+    pthread_t thread;
+
+    pthread_mutex_t mutex; //protects running
+    bool running;
+    int trackCount;
+} activator_data_t;
+
+static bool isRunning(activator_data_t *data) {
+    bool result = false;
+    pthread_mutex_lock(&data->mutex);
+    result = data->running;
+    pthread_mutex_unlock(&data->mutex);
+    return result;
+}
+
+static void setRunning(activator_data_t *data, bool val) {
+    pthread_mutex_lock(&data->mutex);
+    data->running = val;
+    pthread_mutex_unlock(&data->mutex);
+}
+
+struct info {
+    int result;
+    int count;
+};
+
+static void useCalc(void *handle, void *svc) {
+    struct info *i = handle;
+    example_calc_t *calc = svc;
+    i->result += calc->calc(calc->handle, 1);
+    i->count += 1;
+}
+
+static void gccExample(activator_data_t *data) {
+#ifdef USE_NESTED_FUNCTION_EXAMPLE
+
+    int result = 0;
+    long rank = 0;
+    long svcId = 0;
+
+    void use(void *handle, void *svc, const celix_properties_t *props) {
+        example_calc_t *calc = svc;
+        rank = celix_properties_getAsLong(props, OSGI_FRAMEWORK_SERVICE_RANKING, -1L);
+        svcId = celix_properties_getAsLong(props, OSGI_FRAMEWORK_SERVICE_ID, -1L);
+        result = calc->calc(calc->handle, 1);
+    }
+
+    celix_service_use_options_t opts;
+    memset(&opts, 0, sizeof(opts));
+
+    opts.serviceName = EXAMPLE_CALC_NAME;
+    opts.callbackHandle = NULL; //can be null for trampolines
+    opts.useWithProperties = use;
+    bool called = celix_bundleContext_useServiceWithOptions(data->ctx, &opts);
+
+    printf("Called func %s. Result is %i, rank is %li and svc id is %li\n", called ? "called" : "not called", result, rank, svcId);
+
+#endif
+}
+
+static void addSvc(activator_data_t *data, void *svc __attribute__((unused))) {
+    pthread_mutex_lock(&data->mutex);
+    data->trackCount += 1;
+    pthread_mutex_unlock(&data->mutex);
+}
+
+static void removeSvc(activator_data_t *data, void *svc __attribute__((unused))) {
+    pthread_mutex_lock(&data->mutex);
+    data->trackCount -= 1;
+    pthread_mutex_unlock(&data->mutex);
+}
+
+static void useHighest(activator_data_t *data __attribute__((unused)), example_calc_t *svc, const celix_properties_t *props) {
+    int result = svc->calc(svc->handle, 2);
+    long svcId = celix_properties_getAsLong(props, OSGI_FRAMEWORK_SERVICE_ID, -1L);
+    long rank = celix_properties_getAsLong(props, OSGI_FRAMEWORK_SERVICE_RANKING, -1L);
+    printf("Called highest ranking service. Result is %i, svc id is %li, svc ranking is %li\n", result, svcId, rank);
+}
+
+
+void * run(void *handle) {
+    activator_data_t *data = handle;
+
+    printf("starting consumer thread\n");
+    celix_service_tracking_options_t opts;
+    opts.serviceName = EXAMPLE_CALC_NAME;
+    opts.callbackHandle = data;
+    opts.addWithProperties = (void*)addSvc;
+    opts.removeWithProperties = (void*)removeSvc;
+    long trkId = celix_bundleContext_trackServicesWithOptions(data->ctx, &opts);
+
+    while (isRunning(data)) {
+        struct info info;
+        info.result = 0;
+        info.count = 0;
+        celix_bundleContext_useServices(data->ctx, EXAMPLE_CALC_NAME, &info, useCalc);
+        printf("Called calc services %i times, total result is %i\n", info.count, info.result);
+
+        gccExample(data); //gcc trampolines example (nested functions)
+
+        celix_service_use_options_t opts;
+        memset(&opts, 0, sizeof(opts));
+
+        opts.serviceName = EXAMPLE_CALC_NAME;
+        opts.callbackHandle = data;
+        opts.useWithProperties = (void*)useHighest;
+        celix_bundleContext_useServiceWithOptions(data->ctx, &opts);
+
+        pthread_mutex_lock(&data->mutex);
+        int count = data->trackCount;
+        pthread_mutex_unlock(&data->mutex);
+        printf("Current tracking count is %i\n", count);
+
+        sleep(5);
+    }
+
+    celix_bundleContext_stopTracker(data->ctx, trkId);
+    printf("exiting consumer thread\n");
+
+    pthread_exit(NULL);
+    return NULL;
+}
+
+celix_status_t bundleActivator_create(celix_bundle_context_t *ctx, void **out) {
+	celix_status_t status = CELIX_SUCCESS;
+    activator_data_t *data = calloc(1, sizeof(*data));
+    if (data != NULL) {
+       data->ctx = ctx;
+       data->trackCount = 0;
+       data->running = true;
+       pthread_mutex_init(&data->mutex, NULL);
+       *out = data;
+	} else {
+		status = CELIX_ENOMEM;
+	}
+	return status;
+}
+
+celix_status_t bundleActivator_start(void * handle, celix_bundle_context_t *ctx) {
+    activator_data_t *data = handle;
+    pthread_create(&data->thread, NULL, run, data);
+	return CELIX_SUCCESS;
+}
+
+celix_status_t bundleActivator_stop(void * handle, celix_bundle_context_t *ctx) {
+    activator_data_t *data = handle;
+    setRunning(data, false);
+    pthread_join(data->thread, NULL);
+    return CELIX_SUCCESS;
+}
+
+celix_status_t bundleActivator_destroy(void * handle, celix_bundle_context_t *ctx) {
+    activator_data_t *data = handle;
+    if (data != NULL) {
+        pthread_mutex_destroy(&data->mutex);
+        free(data);
+    }
+	return CELIX_SUCCESS;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/626687fe/examples/celix-examples/services_example_c/src/dynamic_provider_example.c
----------------------------------------------------------------------
diff --git a/examples/celix-examples/services_example_c/src/dynamic_provider_example.c b/examples/celix-examples/services_example_c/src/dynamic_provider_example.c
new file mode 100644
index 0000000..f322303
--- /dev/null
+++ b/examples/celix-examples/services_example_c/src/dynamic_provider_example.c
@@ -0,0 +1,134 @@
+/**
+ *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 <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "example_calc.h"
+#include "bundle_activator.h"
+#include "constants.h"
+
+typedef struct activator_data {
+    long svcIds[100];
+    example_calc_t svc;
+    celix_bundle_context_t *ctx;
+    pthread_t thread;
+
+    pthread_mutex_t mutex; //protects running
+    bool running;
+} activator_data_t;
+
+
+static int calc(void *handle __attribute__((unused)), int input) {
+    return 42 * input;
+}
+
+static bool isRunning(activator_data_t *data) {
+    bool result = false;
+    pthread_mutex_lock(&data->mutex);
+    result = data->running;
+    pthread_mutex_unlock(&data->mutex);
+    return result;
+}
+
+static void setRunning(activator_data_t *data, bool val) {
+    pthread_mutex_lock(&data->mutex);
+    data->running = val;
+    pthread_mutex_unlock(&data->mutex);
+}
+
+void * run(void *handle) {
+    activator_data_t *data = handle;
+
+    printf("starting service register thread\n");
+
+    int i = 0;
+    bool up = true;
+    while (isRunning(data)) {
+        if (up) {
+            properties_t *props = properties_create();
+            celix_properties_setLong(props, OSGI_FRAMEWORK_SERVICE_RANKING, rand());
+            data->svcIds[i++] = celix_bundleContext_registerService(data->ctx, EXAMPLE_CALC_NAME, &data->svc, NULL, props);
+        } else { //down
+            celix_bundleContext_unregisterService(data->ctx, data->svcIds[i--]);
+        }
+        if (i == 99) {
+            up = false;
+        } else if (i == 0) {
+            up = true;
+        }
+        usleep(100000);
+    }
+
+    for (int i = 0; i < 100; ++i) {
+        long id = data->svcIds[i];
+        if (id >=0 ) {
+            celix_bundleContext_unregisterService(data->ctx, id);
+        }
+    }
+
+    printf("exiting service register thread\n");
+
+    pthread_exit(NULL);
+    return NULL;
+}
+
+celix_status_t bundleActivator_create(celix_bundle_context_t *ctx, void **out) {
+	celix_status_t status = CELIX_SUCCESS;
+    activator_data_t *data = calloc(1, sizeof(*data));
+    if (data != NULL) {
+       data->svc.handle = data;
+       data->svc.calc = calc;
+       data->ctx = ctx;
+       data->running = true;
+       pthread_mutex_init(&data->mutex, NULL);
+
+       for (int i = 0; i < 100; ++i) {
+           data->svcIds[i] = -1L;
+       }
+
+       *out = data;
+	} else {
+		status = CELIX_ENOMEM;
+	}
+	return status;
+}
+
+celix_status_t bundleActivator_start(void * handle, celix_bundle_context_t *ctx) {
+    activator_data_t *data = handle;
+    pthread_create(&data->thread, NULL, run ,data);
+	return CELIX_SUCCESS;
+}
+
+celix_status_t bundleActivator_stop(void * handle, celix_bundle_context_t *ctx) {
+    activator_data_t *data = handle;
+    setRunning(data, false);
+    pthread_join(data->thread, NULL);
+    return CELIX_SUCCESS;
+}
+
+celix_status_t bundleActivator_destroy(void * handle, celix_bundle_context_t *ctx) {
+    activator_data_t *data = handle;
+    if (data != NULL) {
+        pthread_mutex_destroy(&data->mutex);
+        free(data);
+    }
+	return CELIX_SUCCESS;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/626687fe/examples/celix-examples/services_example_c/src/provider_example.c
----------------------------------------------------------------------
diff --git a/examples/celix-examples/services_example_c/src/provider_example.c b/examples/celix-examples/services_example_c/src/provider_example.c
deleted file mode 100644
index f322303..0000000
--- a/examples/celix-examples/services_example_c/src/provider_example.c
+++ /dev/null
@@ -1,134 +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 <unistd.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "example_calc.h"
-#include "bundle_activator.h"
-#include "constants.h"
-
-typedef struct activator_data {
-    long svcIds[100];
-    example_calc_t svc;
-    celix_bundle_context_t *ctx;
-    pthread_t thread;
-
-    pthread_mutex_t mutex; //protects running
-    bool running;
-} activator_data_t;
-
-
-static int calc(void *handle __attribute__((unused)), int input) {
-    return 42 * input;
-}
-
-static bool isRunning(activator_data_t *data) {
-    bool result = false;
-    pthread_mutex_lock(&data->mutex);
-    result = data->running;
-    pthread_mutex_unlock(&data->mutex);
-    return result;
-}
-
-static void setRunning(activator_data_t *data, bool val) {
-    pthread_mutex_lock(&data->mutex);
-    data->running = val;
-    pthread_mutex_unlock(&data->mutex);
-}
-
-void * run(void *handle) {
-    activator_data_t *data = handle;
-
-    printf("starting service register thread\n");
-
-    int i = 0;
-    bool up = true;
-    while (isRunning(data)) {
-        if (up) {
-            properties_t *props = properties_create();
-            celix_properties_setLong(props, OSGI_FRAMEWORK_SERVICE_RANKING, rand());
-            data->svcIds[i++] = celix_bundleContext_registerService(data->ctx, EXAMPLE_CALC_NAME, &data->svc, NULL, props);
-        } else { //down
-            celix_bundleContext_unregisterService(data->ctx, data->svcIds[i--]);
-        }
-        if (i == 99) {
-            up = false;
-        } else if (i == 0) {
-            up = true;
-        }
-        usleep(100000);
-    }
-
-    for (int i = 0; i < 100; ++i) {
-        long id = data->svcIds[i];
-        if (id >=0 ) {
-            celix_bundleContext_unregisterService(data->ctx, id);
-        }
-    }
-
-    printf("exiting service register thread\n");
-
-    pthread_exit(NULL);
-    return NULL;
-}
-
-celix_status_t bundleActivator_create(celix_bundle_context_t *ctx, void **out) {
-	celix_status_t status = CELIX_SUCCESS;
-    activator_data_t *data = calloc(1, sizeof(*data));
-    if (data != NULL) {
-       data->svc.handle = data;
-       data->svc.calc = calc;
-       data->ctx = ctx;
-       data->running = true;
-       pthread_mutex_init(&data->mutex, NULL);
-
-       for (int i = 0; i < 100; ++i) {
-           data->svcIds[i] = -1L;
-       }
-
-       *out = data;
-	} else {
-		status = CELIX_ENOMEM;
-	}
-	return status;
-}
-
-celix_status_t bundleActivator_start(void * handle, celix_bundle_context_t *ctx) {
-    activator_data_t *data = handle;
-    pthread_create(&data->thread, NULL, run ,data);
-	return CELIX_SUCCESS;
-}
-
-celix_status_t bundleActivator_stop(void * handle, celix_bundle_context_t *ctx) {
-    activator_data_t *data = handle;
-    setRunning(data, false);
-    pthread_join(data->thread, NULL);
-    return CELIX_SUCCESS;
-}
-
-celix_status_t bundleActivator_destroy(void * handle, celix_bundle_context_t *ctx) {
-    activator_data_t *data = handle;
-    if (data != NULL) {
-        pthread_mutex_destroy(&data->mutex);
-        free(data);
-    }
-	return CELIX_SUCCESS;
-}

http://git-wip-us.apache.org/repos/asf/celix/blob/626687fe/examples/celix-examples/services_example_c/src/simple_consumer_example.c
----------------------------------------------------------------------
diff --git a/examples/celix-examples/services_example_c/src/simple_consumer_example.c b/examples/celix-examples/services_example_c/src/simple_consumer_example.c
new file mode 100644
index 0000000..edf88c6
--- /dev/null
+++ b/examples/celix-examples/services_example_c/src/simple_consumer_example.c
@@ -0,0 +1,85 @@
+/**
+ *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 <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <constants.h>
+
+#include "example_calc.h"
+#include "bundle_activator.h"
+
+typedef struct activator_data {
+    celix_bundle_context_t *ctx;
+    long trkId;
+} activator_data_t;
+
+
+static void addSvc(activator_data_t *data __attribute__((unused)), example_calc_t *calc) {
+    int result = calc->calc(calc->handle, 2);
+    printf("Added calc service, result is %i\n", result);
+}
+
+static void removeSvc(activator_data_t *data __attribute__((unused)), example_calc_t *calc) {
+    int result = calc->calc(calc->handle, 3);
+    printf("Removing calc service, result is %i\n", result);
+}
+
+static void useCalc(activator_data_t *data __attribute__((unused)), example_calc_t *calc) {
+    int result = calc->calc(calc->handle, 2);
+    printf("Called highest ranking service. Result is %i\n", result);
+}
+
+celix_status_t bundleActivator_create(celix_bundle_context_t *ctx, void **out) {
+	celix_status_t status = CELIX_SUCCESS;
+    activator_data_t *data = calloc(1, sizeof(*data));
+    if (data != NULL) {
+       data->ctx = ctx;
+       data->trkId = -1L;
+       *out = data;
+	} else {
+		status = CELIX_ENOMEM;
+	}
+	return status;
+}
+
+celix_status_t bundleActivator_start(void * handle, celix_bundle_context_t *ctx) {
+    activator_data_t *data = handle;
+
+    printf("Starting service tracker\n");
+    data->trkId = celix_bundleContext_trackServices(data->ctx, EXAMPLE_CALC_NAME, data, (void*)addSvc, (void*)removeSvc);
+
+    printf("Trying to use calc service\n");
+    celix_bundleContext_useService(data->ctx, EXAMPLE_CALC_NAME, data, (void*)useCalc);
+
+	return CELIX_SUCCESS;
+}
+
+celix_status_t bundleActivator_stop(void * handle, celix_bundle_context_t *ctx) {
+    activator_data_t *data = handle;
+    celix_bundleContext_stopTracker(data->ctx, data->trkId);
+    return CELIX_SUCCESS;
+}
+
+celix_status_t bundleActivator_destroy(void * handle, celix_bundle_context_t *ctx) {
+    activator_data_t *data = handle;
+    free(data);
+	return CELIX_SUCCESS;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/626687fe/examples/celix-examples/services_example_c/src/simple_provider_example.c
----------------------------------------------------------------------
diff --git a/examples/celix-examples/services_example_c/src/simple_provider_example.c b/examples/celix-examples/services_example_c/src/simple_provider_example.c
new file mode 100644
index 0000000..765a49e
--- /dev/null
+++ b/examples/celix-examples/services_example_c/src/simple_provider_example.c
@@ -0,0 +1,73 @@
+/**
+ *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 <stdio.h>
+#include <stdlib.h>
+
+#include "example_calc.h"
+#include "bundle_activator.h"
+#include "constants.h"
+
+typedef struct activator_data {
+    celix_bundle_context_t *ctx;
+    example_calc_t svc;
+    int seed;
+    long svcId;
+} activator_data_t;
+
+
+static int calc(activator_data_t *data, int input) {
+    return data->seed * input;
+}
+
+celix_status_t bundleActivator_create(celix_bundle_context_t *ctx, void **out) {
+	celix_status_t status = CELIX_SUCCESS;
+    activator_data_t *data = calloc(1, sizeof(*data));
+    if (data != NULL) {
+       data->svc.handle = data;
+       data->svc.calc = (void*)calc;
+       data->ctx = ctx;
+       data->seed = 42;
+       data->svcId = -1L;
+       *out = data;
+	} else {
+		status = CELIX_ENOMEM;
+	}
+	return status;
+}
+
+celix_status_t bundleActivator_start(void * handle, celix_bundle_context_t *ctx) {
+    activator_data_t *data = handle;
+    data->svcId = celix_bundleContext_registerService(data->ctx, EXAMPLE_CALC_NAME, &data->svc, EXAMPLE_CALC_VERSION, NULL);
+    printf("Registered calc service with service id %li\n", data->svcId);
+	return CELIX_SUCCESS;
+}
+
+celix_status_t bundleActivator_stop(void * handle, celix_bundle_context_t *ctx) {
+    activator_data_t *data = handle;
+    celix_bundleContext_unregisterService(data->ctx, data->svcId);
+    printf("Unregistered calc service with service id %li\n", data->svcId);
+    return CELIX_SUCCESS;
+}
+
+celix_status_t bundleActivator_destroy(void * handle, celix_bundle_context_t *ctx) {
+    activator_data_t *data = handle;
+    free(data);
+	return CELIX_SUCCESS;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/626687fe/framework/include/bundle_context.h
----------------------------------------------------------------------
diff --git a/framework/include/bundle_context.h b/framework/include/bundle_context.h
index ec974fa..44cca39 100644
--- a/framework/include/bundle_context.h
+++ b/framework/include/bundle_context.h
@@ -29,6 +29,7 @@
 #include "celix_types.h"
 
 #include "service_factory.h"
+#include "celix_service_factory.h"
 #include "service_listener.h"
 #include "bundle_listener.h"
 #include "framework_listener.h"
@@ -201,7 +202,8 @@ dm_dependency_manager_t* celix_bundleContext_getDependencyManager(celix_bundle_c
  * @param ctx The bundle context
  * @param serviceName the service name, cannot be NULL
  * @param svc the service object. Normally a pointer to a service struct (e.g. a struct with function pointers)
- * @param properties The meta properties assiated with the service. The service registration will take ownership of the properties (e.g. no destroy needed)
+ * @param serviceVersion The optional service version.
+ * @param properties The meta properties associated with the service. The service registration will take ownership of the properties (e.g. no destroy needed)
  * @return The serviceId, which should be >= 0. If < 0 then the registration was unsuccessful.
  */
 long celix_bundleContext_registerService(celix_bundle_context_t *ctx, const char *serviceName, void *svc, const char *serviceVersion, celix_properties_t *properties);
@@ -211,17 +213,56 @@ long celix_bundleContext_registerService(celix_bundle_context_t *ctx, const char
 *
 * @param ctx The bundle context
 * @param serviceName the service name, cannot be NULL
-* @param svc the service object. Normally a pointer to a service struct (e.g. a struct with function pointers)
-* @param properties The meta properties assiated with the service. The service registration will take ownership of the properties
+* @param svc Pointer to the service. Normally a pointer to a service struct (e.g. a struct with function pointers)
+* @param serviceVersion The optional service version.
+* @param lang The service language. Will be set to CELIX_FRAMEWORK_SERVICE_LANGUAGE_C if NULL is provided.
+* @param properties The meta properties associated with the service. The service registration will take ownership of the properties
 * @return The serviceId, which should >= 0. If < 0 then the registration was unsuccessful.
 */
 long celix_bundleContext_registerServiceForLang(celix_bundle_context_t *ctx, const char *serviceName, void *svc, const char *serviceVersion, const char* lang, celix_properties_t *properties);
 
-//TODO register service factory
+/**
+ * Register a service factory in the framework (for the C language).
+ * THe service factory will be called for every bundle requesting/de-requesting a service. This gives the provider the
+ * option to create bundle specific service instances.
+ *
+ * When a service is requested for a bundle the getService of the factory service will be called. This function must
+ * return a valid pointer to a service conform the registered service name or NULL.
+ * When a service in no longer needed for a bundle (e.g. ending the useService(s) calls when a service tacker is stopped)
+ * the ungetService function of the service factory will be called.
+ *
+ * @param ctx The bundle context
+ * @param serviceName The required service name of the services this factory will produce.
+ * @param factory The pointer to the factory service.
+ * @param serviceVersion The optional service version.
+ * @param properties The optional service factory properties. For a service consumer this will be seen as the service properties.
+ * @return The service id of the service factory or < 0 if the registration was unsuccessful.
+ */
+long celix_bundleContext_registerServiceFactory(celix_bundle_context_t *ctx, const char *serviceName, celix_service_factory_t *factory, const char *serviceVersion, celix_properties_t *properties);
+
+/**
+ * Register a service factory in the framework.
+ * THe service factory will be called for every bundle requesting/de-requesting a service. This gives the provider the
+ * option to create bundle specific service instances.
+ *
+ * When a service is requested for a bundle the getService of the factory service will be called. This function must
+ * return a valid pointer to a service conform the registered service name or NULL.
+ * When a service in no longer needed for a bundle (e.g. ending the useService(s) calls when a service tacker is stopped)
+ * the ungetService function of the service factory will be called.
+ *
+ * @param ctx The bundle context
+ * @param serviceName The required service name of the services this factory will produce.
+ * @param factory The pointer to the factory service.
+ * @param serviceVersion The optional service version.
+ * @param lang The d service language. Will be set to CELIX_FRAMEWORK_SERVICE_LANGUAGE_C if NULL is provided.
+ * @param properties The optional service factory properties. For a service consumer this will be seen as the service properties.
+ * @return The service id of the service factory or < 0 if the registration was unsuccessful.
+ */
+long celix_bundleContext_registerServiceFactorForLang(celix_bundle_context_t *ctx, const char *serviceName, celix_service_factory_t *factory, const char *serviceVersion, const char *lang, celix_properties_t *properties);
 
 /**
- * Unregister the service with service id. The service will only be unregistered if the bundle of the bundle context
- * is the owner of the service.
+ * Unregister the service or service factory with service id.
+ * The service will only be unregistered if the bundle of the bundle context is the owner of the service.
  *
  * Will log an error if service id is unknown. Will silently ignore services ids < 0.
  *
@@ -557,10 +598,12 @@ void celix_bundleContext_useBundle(
         void (*use)(void *handle, const celix_bundle_t *bundle)
 );
 
-//TODO add useBundleWithState (bit wise or?)
+//TODO add useBundleWithOptions (e.g. which state)
+
+
+//TODO findBundles
 
 
-//TODO except framework & own bundle
 /**
  * Use the currently active (started) bundles.
  * The provided callback will be called for all the currently started bundles.
@@ -577,7 +620,7 @@ void celix_bundleContext_useBundles(
 );
 
 
-//TODO trackerServiceTracker
+//TODO trackServiceTracker
 
 /**
  * Stop the tracker with the provided track id.

http://git-wip-us.apache.org/repos/asf/celix/blob/626687fe/framework/include/celix_service_factory.h
----------------------------------------------------------------------
diff --git a/framework/include/celix_service_factory.h b/framework/include/celix_service_factory.h
new file mode 100644
index 0000000..4373db6
--- /dev/null
+++ b/framework/include/celix_service_factory.h
@@ -0,0 +1,43 @@
+/**
+ *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.
+ */
+#ifndef CELIX_SERVICE_FACTORY_H_
+#define CELIX_SERVICE_FACTORY_H_
+
+#include "properties.h"
+#include "bundle.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct celix_service_factory celix_service_factory_t;
+
+struct celix_service_factory {
+    void *handle;
+
+    void* (*getService)(void *handle, const celix_bundle_t *requestingBundle, const celix_properties_t *svcProperties);
+
+    void (*ungetService)(void *handle, const celix_bundle_t *requestingBundle, const celix_properties_t *svcProperties);
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CELIX_SERVICE_FACTORY_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/626687fe/framework/include/celix_types.h
----------------------------------------------------------------------
diff --git a/framework/include/celix_types.h b/framework/include/celix_types.h
index 7846c1c..6e02c63 100644
--- a/framework/include/celix_types.h
+++ b/framework/include/celix_types.h
@@ -48,4 +48,6 @@ typedef struct dm_component_struct dm_component_t;
 typedef struct dm_service_dependency *dm_service_dependency_pt;
 typedef struct dm_service_dependency dm_service_dependency_t;
 
+typedef struct service_factory *service_factory_pt; //deprecated
+
 #endif //CELIX_CELIX_TYPES_H

http://git-wip-us.apache.org/repos/asf/celix/blob/626687fe/framework/include/service_factory.h
----------------------------------------------------------------------
diff --git a/framework/include/service_factory.h b/framework/include/service_factory.h
index 84e383a..80230d1 100644
--- a/framework/include/service_factory.h
+++ b/framework/include/service_factory.h
@@ -16,26 +16,10 @@
  *specific language governing permissions and limitations
  *under the License.
  */
-/*
- * service_factory.h
- *
- *  \date       Jun 26, 2011
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
-
 #ifndef SERVICE_FACTORY_H_
 #define SERVICE_FACTORY_H_
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct service_factory service_factory_t;
-typedef service_factory_t *service_factory_pt;
-#ifdef __cplusplus
-}
-#endif
 
+#include "celix_types.h"
 #include "celix_errno.h"
 #include "service_registration.h"
 #include "bundle.h"
@@ -47,10 +31,10 @@ extern "C" {
 struct service_factory {
     void *handle;
 
-    celix_status_t (*getService)(void *handle, bundle_pt bundle, service_registration_pt registration, void **service);
+    celix_status_t (*getService)(void *handle, celix_bundle_t *bnd, service_registration_pt registration, void **service);
 
     celix_status_t
-    (*ungetService)(void *handle, bundle_pt bundle, service_registration_pt registration, void **service);
+    (*ungetService)(void *handle, celix_bundle_t *bnd, service_registration_pt registration, void **service);
 };
 
 #ifdef __cplusplus

http://git-wip-us.apache.org/repos/asf/celix/blob/626687fe/framework/include/service_registry.h
----------------------------------------------------------------------
diff --git a/framework/include/service_registry.h b/framework/include/service_registry.h
index 9a2ec48..9ca4a59 100644
--- a/framework/include/service_registry.h
+++ b/framework/include/service_registry.h
@@ -27,7 +27,8 @@
 #ifndef SERVICE_REGISTRY_H_
 #define SERVICE_REGISTRY_H_
 
-typedef struct serviceRegistry * service_registry_pt;
+typedef struct celix_serviceRegistry * service_registry_pt;
+typedef struct celix_serviceRegistry celix_service_registry_t;
 
 #include "properties.h"
 #include "filter.h"
@@ -35,6 +36,8 @@ typedef struct serviceRegistry * service_registry_pt;
 #include "service_event.h"
 #include "array_list.h"
 #include "service_registration.h"
+#include "celix_service_factory.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -96,6 +99,15 @@ celix_status_t
 serviceRegistry_servicePropertiesModified(service_registry_pt registry, service_registration_pt registration,
                                           properties_pt oldprops);
 
+celix_status_t
+celix_serviceRegistry_registerServiceFactory(
+        celix_service_registry_t *reg,
+        const celix_bundle_t *bnd,
+        const char *serviceName,
+        celix_service_factory_t *factory,
+        celix_properties_t* props,
+        service_registration_t **registration);
+
 #ifdef __cplusplus
 }
 #endif

http://git-wip-us.apache.org/repos/asf/celix/blob/626687fe/framework/private/mock/bundle_context_mock.c
----------------------------------------------------------------------
diff --git a/framework/private/mock/bundle_context_mock.c b/framework/private/mock/bundle_context_mock.c
index 8225580..749e3ca 100644
--- a/framework/private/mock/bundle_context_mock.c
+++ b/framework/private/mock/bundle_context_mock.c
@@ -326,3 +326,24 @@ void celix_bundleContext_useServicesWithOptions(
 			->withPointerParameters("ctx", ctx)
 			->withConstPointerParameters("opts", opts);
 }
+
+long celix_bundleContext_registerServiceFactory(celix_bundle_context_t *ctx, const char *serviceName, celix_service_factory_t *factory, const char *serviceVersion, celix_properties_t *props) {
+	mock_c()->actualCall("celix_bundleContext_registerServiceFactory")
+			->withPointerParameters("ctx", ctx)
+			->withStringParameters("serviceName", serviceName)
+			->withPointerParameters("factory", factory)
+			->withStringParameters("serviceVersion", serviceVersion)
+			->withPointerParameters("props", props);
+	return mock_c()->returnValue().value.longIntValue;
+}
+
+long celix_bundleContext_registerServiceFactorForLang(celix_bundle_context_t *ctx, const char *serviceName, celix_service_factory_t *factory, const char *serviceVersion, const char *lang, celix_properties_t *props) {
+	mock_c()->actualCall("celix_bundleContext_registerServiceFactorForLang")
+			->withPointerParameters("ctx", ctx)
+			->withStringParameters("serviceName", serviceName)
+			->withPointerParameters("factory", factory)
+			->withStringParameters("serviceVersion", serviceVersion)
+			->withStringParameters("lang", lang)
+			->withPointerParameters("props", props);
+	return mock_c()->returnValue().value.longIntValue;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/626687fe/framework/private/mock/framework_mock.c
----------------------------------------------------------------------
diff --git a/framework/private/mock/framework_mock.c b/framework/private/mock/framework_mock.c
index d718ade..7bbd752 100644
--- a/framework/private/mock/framework_mock.c
+++ b/framework/private/mock/framework_mock.c
@@ -335,4 +335,12 @@ void celix_framework_useBundle(framework_t *fw, long bundleId, void *callbackHan
 			->withPointerParameters("use", use);
 }
 
-
+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) {
+	mock_c()->actualCall("celix_framework_registerServiceFactory")
+			->withPointerParameters("fw", fw)
+			->withConstPointerParameters("bnd", bnd)
+			->withStringParameters("serviceName", serviceName)
+			->withPointerParameters("factory", factory)
+			->withPointerParameters("properties", properties);
+	return mock_c()->returnValue().value.pointerValue;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/626687fe/framework/private/mock/service_registration_mock.c
----------------------------------------------------------------------
diff --git a/framework/private/mock/service_registration_mock.c b/framework/private/mock/service_registration_mock.c
index 4bbf0c8..69be7eb 100644
--- a/framework/private/mock/service_registration_mock.c
+++ b/framework/private/mock/service_registration_mock.c
@@ -145,3 +145,20 @@ long serviceRegistration_getServiceId(service_registration_t *registration) {
 	return mock_c()->returnValue().value.longIntValue;
 }
 
+service_registration_t* celix_serviceRegistration_createServiceFactory(
+		registry_callback_t callback,
+		const celix_bundle_t *bnd,
+		const char *serviceName,
+		long svcId,
+		celix_service_factory_t* factory,
+		celix_properties_t *props) {
+	mock_c()->actualCall("celix_serviceRegistration_createServiceFactory")
+			->withParameterOfType("registry_callback_t", "callback", &callback)
+			->withConstPointerParameters("bnd", bnd)
+			->withStringParameters("serviceName", serviceName)
+			->withUnsignedLongIntParameters("svcId", svcId)
+			->withPointerParameters("factory", (void*) factory)
+			->withPointerParameters("props", props);
+	return mock_c()->returnValue().value.pointerValue;
+}
+

http://git-wip-us.apache.org/repos/asf/celix/blob/626687fe/framework/private/mock/service_registry_mock.c
----------------------------------------------------------------------
diff --git a/framework/private/mock/service_registry_mock.c b/framework/private/mock/service_registry_mock.c
index 60b8032..9942818 100644
--- a/framework/private/mock/service_registry_mock.c
+++ b/framework/private/mock/service_registry_mock.c
@@ -164,3 +164,21 @@ celix_status_t serviceRegistry_clearServiceRegistrations(service_registry_pt reg
 			->withPointerParameters("bundle", bundle);
 	return mock_c()->returnValue().value.intValue;
 }
+
+celix_status_t
+celix_serviceRegistry_registerServiceFactory(
+		celix_service_registry_t *reg,
+		const celix_bundle_t *bnd,
+		const char *serviceName,
+		celix_service_factory_t *factory,
+		celix_properties_t* props,
+		service_registration_t **registration) {
+	mock_c()->actualCall("celix_serviceRegistry_registerServiceFactory")
+			->withPointerParameters("reg", reg)
+			->withConstPointerParameters("bnd", bnd)
+			->withStringParameters("serviceName", serviceName)
+			->withPointerParameters("factory", factory)
+			->withPointerParameters("props", props)
+			->withOutputParameter("registration", registration);
+	return mock_c()->returnValue().value.intValue;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/626687fe/framework/private/test/service_registration_test.cpp
----------------------------------------------------------------------
diff --git a/framework/private/test/service_registration_test.cpp b/framework/private/test/service_registration_test.cpp
index da4420d..68986bf 100644
--- a/framework/private/test/service_registration_test.cpp
+++ b/framework/private/test/service_registration_test.cpp
@@ -111,8 +111,9 @@ TEST(service_registration, create) {
 	UNSIGNED_LONGS_EQUAL(serviceId, registration->serviceId);
 
 	LONGS_EQUAL(0, registration->isUnregistering);
-	LONGS_EQUAL(0, registration->isServiceFactory);
-	POINTERS_EQUAL(NULL, registration->serviceFactory);
+	LONGS_EQUAL(CELIX_PLAIN_SERVICE, registration->svcType);
+	POINTERS_EQUAL(NULL, registration->deprecatedFactory);
+	POINTERS_EQUAL(NULL, registration->factory);
 	POINTERS_EQUAL(NULL, registration->services);
 	LONGS_EQUAL(0, registration->nrOfServices);
 
@@ -143,8 +144,8 @@ TEST(service_registration, createServiceFactory) {
 	POINTERS_EQUAL(service, registration->svcObj);
 	UNSIGNED_LONGS_EQUAL(serviceId, registration->serviceId);
 	LONGS_EQUAL(0, registration->isUnregistering);
-	LONGS_EQUAL(1, registration->isServiceFactory);
-	POINTERS_EQUAL(service, registration->serviceFactory);
+	LONGS_EQUAL(CELIX_DEPRECATED_FACTORY_SERVICE, registration->svcType);
+	POINTERS_EQUAL(service, registration->deprecatedFactory);
 	POINTERS_EQUAL(NULL, registration->services);
 	LONGS_EQUAL(0, registration->nrOfServices);
 

http://git-wip-us.apache.org/repos/asf/celix/blob/626687fe/framework/src/bundle_context.c
----------------------------------------------------------------------
diff --git a/framework/src/bundle_context.c b/framework/src/bundle_context.c
index 5a9bbd1..7d5dea9 100644
--- a/framework/src/bundle_context.c
+++ b/framework/src/bundle_context.c
@@ -426,30 +426,25 @@ celix_status_t bundleContext_getPropertyWithDefault(bundle_context_pt context, c
 
 
 long celix_bundleContext_registerService(bundle_context_t *ctx, const char *serviceName, void *svc, const char *serviceVersion, properties_t *properties) {
-    return celix_bundleContext_registerServiceForLang(ctx, serviceName, svc, serviceVersion, CELIX_FRAMEWORK_SERVICE_C_LANGUAGE, properties);
+    return celix_bundleContext_registerServiceForLang(ctx, serviceName, svc, serviceVersion, NULL, properties);
 }
 
 
 long celix_bundleContext_registerServiceForLang(bundle_context_t *ctx, const char *serviceName, void *svc, const char *serviceVersion, const char* lang, properties_t *properties) {
     long svcId = -1;
+    service_registration_t *reg = NULL;
     if (properties == NULL) {
         properties = properties_create();
     }
-    service_registration_t *reg = NULL;
     if (serviceVersion != NULL) {
         properties_set(properties, CELIX_FRAMEWORK_SERVICE_VERSION, serviceVersion);
     }
-    if (serviceName != NULL && lang != NULL) {
-        properties_set(properties, CELIX_FRAMEWORK_SERVICE_LANGUAGE, lang);
+    if (serviceName != NULL) {
+        properties_set(properties, CELIX_FRAMEWORK_SERVICE_LANGUAGE, lang == NULL ? CELIX_FRAMEWORK_SERVICE_C_LANGUAGE : lang);
         bundleContext_registerService(ctx, serviceName, svc, properties, &reg);
         svcId = serviceRegistration_getServiceId(reg); //save to call with NULL
     } else {
-        if (serviceName == NULL) {
-            framework_logIfError(logger, CELIX_ILLEGAL_ARGUMENT, NULL, "Required serviceName argument is NULL");
-        }
-        if (lang == NULL) {
-            framework_logIfError(logger, CELIX_ILLEGAL_ARGUMENT, NULL, "Required lang argument is NULL");
-        }
+        framework_logIfError(logger, CELIX_ILLEGAL_ARGUMENT, NULL, "Required serviceName argument is NULL");
     }
     if (svcId < 0) {
         properties_destroy(properties);
@@ -812,4 +807,28 @@ long celix_bundleContext_trackServicesWithOptions(bundle_context_t *ctx, const c
         celixThreadMutex_unlock(&ctx->mutex);
     }
     return trackerId;
+}
+
+long celix_bundleContext_registerServiceFactory(celix_bundle_context_t *ctx, const char *serviceName, celix_service_factory_t *factory, const char *serviceVersion, celix_properties_t *props) {
+    return celix_bundleContext_registerServiceFactorForLang(ctx, serviceName, factory, serviceVersion, NULL, props);
+}
+
+long celix_bundleContext_registerServiceFactorForLang(celix_bundle_context_t *ctx, const char *serviceName, celix_service_factory_t *factory, const char *serviceVersion, const char *lang, celix_properties_t *props) {
+    if (props == NULL) {
+        props = celix_properties_create();
+    }
+    if (serviceVersion != NULL) {
+        celix_properties_set(props, CELIX_FRAMEWORK_SERVICE_VERSION, serviceVersion);
+    }
+    celix_properties_set(props, CELIX_FRAMEWORK_SERVICE_LANGUAGE, lang == NULL ? CELIX_FRAMEWORK_SERVICE_C_LANGUAGE : lang);
+    service_registration_t *reg = celix_framework_registerServiceFactory(ctx->framework, ctx->bundle, serviceName, factory, props);
+    long facId = serviceRegistration_getServiceId(reg); //save to call with NULL
+    if (facId < 0) {
+        properties_destroy(props);
+    } else {
+        celixThreadMutex_lock(&ctx->mutex);
+        arrayList_add(ctx->svcRegistrations, reg);
+        celixThreadMutex_unlock(&ctx->mutex);
+    }
+    return facId;
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/626687fe/framework/src/framework.c
----------------------------------------------------------------------
diff --git a/framework/src/framework.c b/framework/src/framework.c
index b6cb825..952392c 100644
--- a/framework/src/framework.c
+++ b/framework/src/framework.c
@@ -2781,4 +2781,22 @@ void celix_framework_useBundle(framework_t *fw, long bundleId, void *callbackHan
         }
         //TODO unlock
     }
+}
+
+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) {
+    const char *error = NULL;
+    celix_status_t status = CELIX_SUCCESS;
+    service_registration_t *reg = NULL;
+    if (serviceName != NULL && factory != NULL) {
+        status = framework_acquireBundleLock(fw, (celix_bundle_t*)bnd, OSGI_FRAMEWORK_BUNDLE_STARTING|OSGI_FRAMEWORK_BUNDLE_ACTIVE);
+        status = CELIX_DO_IF(status, celix_serviceRegistry_registerServiceFactory(fw->registry, bnd, serviceName, factory, properties, &reg));
+        if (!framework_releaseBundleLock(fw, (celix_bundle_t*)bnd)) {
+            status = CELIX_ILLEGAL_STATE;
+            error = "Could not release bundle lock";
+        }
+    }
+
+    framework_logIfError(fw->logger, status, error, "Cannot register service factory: %s", serviceName);
+
+    return reg;
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/626687fe/framework/src/framework_private.h
----------------------------------------------------------------------
diff --git a/framework/src/framework_private.h b/framework/src/framework_private.h
index 66c1125..ab0a940 100644
--- a/framework/src/framework_private.h
+++ b/framework/src/framework_private.h
@@ -65,7 +65,7 @@ struct framework {
     celix_thread_mutex_t bundleListenerLock;
 
     long nextBundleId;
-    struct serviceRegistry * registry;
+    celix_service_registry_t *registry;
     bundle_cache_pt cache;
 
     celix_thread_cond_t shutdownGate;
@@ -158,5 +158,6 @@ 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));
+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_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/626687fe/framework/src/service_registration.c
----------------------------------------------------------------------
diff --git a/framework/src/service_registration.c b/framework/src/service_registration.c
index fe25214..b3f45b2 100644
--- a/framework/src/service_registration.c
+++ b/framework/src/service_registration.c
@@ -33,7 +33,7 @@
 
 static celix_status_t serviceRegistration_initializeProperties(service_registration_pt registration, properties_pt properties);
 static celix_status_t serviceRegistration_createInternal(registry_callback_t callback, bundle_pt bundle, const char* serviceName, unsigned long serviceId,
-        const void * serviceObject, properties_pt dictionary, bool isFactory, service_registration_pt *registration);
+        const void * serviceObject, properties_pt dictionary, enum celix_service_type svcType, service_registration_pt *registration);
 static celix_status_t serviceRegistration_destroy(service_registration_pt registration);
 
 service_registration_pt serviceRegistration_create(registry_callback_t callback, bundle_pt bundle, const char* serviceName, unsigned long serviceId, const void * serviceObject, properties_pt dictionary) {
@@ -49,25 +49,25 @@ service_registration_pt serviceRegistration_createServiceFactory(registry_callba
 }
 
 static celix_status_t serviceRegistration_createInternal(registry_callback_t callback, bundle_pt bundle, const char* serviceName, unsigned long serviceId,
-        const void * serviceObject, properties_pt dictionary, bool isFactory, service_registration_pt *out) {
-    celix_status_t status = CELIX_SUCCESS;
+                                                         const void * serviceObject, properties_pt dictionary, enum celix_service_type svcType, service_registration_pt *out) {
 
+    celix_status_t status = CELIX_SUCCESS;
 	service_registration_pt  reg = calloc(1, sizeof(*reg));
     if (reg) {
         reg->callback = callback;
         reg->services = NULL;
         reg->nrOfServices = 0;
-		reg->isServiceFactory = isFactory;
+		reg->svcType = svcType;
 		reg->className = strndup(serviceName, 1024*10);
 		reg->bundle = bundle;
 		reg->refCount = 1;
-
 		reg->serviceId = serviceId;
-	reg->svcObj = serviceObject;
-		if (isFactory) {
-			reg->serviceFactory = (service_factory_pt) reg->svcObj;
-		} else {
-			reg->serviceFactory = NULL;
+	    reg->svcObj = serviceObject;
+
+		if (svcType == CELIX_DEPRECATED_FACTORY_SERVICE) {
+			reg->deprecatedFactory = (service_factory_pt) reg->svcObj;
+		} else if (svcType == CELIX_FACTORY_SERVICE) {
+			reg->factory = (celix_service_factory_t*) reg->svcObj;
 		}
 
 		reg->isUnregistering = false;
@@ -190,29 +190,29 @@ celix_status_t serviceRegistration_unregister(service_registration_pt registrati
 }
 
 celix_status_t serviceRegistration_getService(service_registration_pt registration, bundle_pt bundle, const void** service) {
-	int status = CELIX_SUCCESS;
     celixThreadRwlock_readLock(&registration->lock);
-    if (registration->isServiceFactory) {
-        service_factory_pt factory = (void*) registration->serviceFactory;
-        /*NOTE the service argument of the service_factory should be const void**.
-          To ensure backwards compatability a cast is made instead.
-        */
-        status = factory->getService(factory->handle, bundle, registration, (void**) service);
-    } else {
+    if (registration->svcType == CELIX_DEPRECATED_FACTORY_SERVICE) {
+        service_factory_pt factory = registration->deprecatedFactory;
+        factory->getService(factory->handle, bundle, registration, (void **) service);
+    } else if (registration->svcType == CELIX_FACTORY_SERVICE) {
+        celix_service_factory_t *fac = registration->factory;
+        *service = fac->getService(fac->handle, bundle, registration->properties);
+    } else { //plain service
         (*service) = registration->svcObj;
     }
     celixThreadRwlock_unlock(&registration->lock);
-    return status;
+
+    return CELIX_SUCCESS;
 }
 
 celix_status_t serviceRegistration_ungetService(service_registration_pt registration, bundle_pt bundle, const void** service) {
     celixThreadRwlock_readLock(&registration->lock);
-    if (registration->isServiceFactory) {
-        service_factory_pt factory = (void*) registration->serviceFactory;
-        /*NOTE the service argument of the service_factory should be const void**.
-          To ensure backwards compatibility a cast is made instead.
-        */
+    if (registration->svcType == CELIX_DEPRECATED_FACTORY_SERVICE) {
+        service_factory_pt factory = registration->deprecatedFactory;
         factory->ungetService(factory->handle, bundle, registration, (void**) service);
+    } else if (registration->svcType == CELIX_FACTORY_SERVICE) {
+        celix_service_factory_t *fac = registration->factory;
+        fac->ungetService(fac->handle, bundle, registration->properties);
     }
     celixThreadRwlock_unlock(&registration->lock);
     return CELIX_SUCCESS;
@@ -299,3 +299,16 @@ long serviceRegistration_getServiceId(service_registration_t *registration) {
     }
     return svcId;
 }
+
+
+service_registration_t* celix_serviceRegistration_createServiceFactory(
+        registry_callback_t callback,
+        const celix_bundle_t *bnd,
+        const char *serviceName,
+        long svcId,
+        celix_service_factory_t* factory,
+        celix_properties_t *props) {
+    service_registration_pt registration = NULL;
+    serviceRegistration_createInternal(callback, (celix_bundle_t*)bnd, serviceName, svcId, factory, props, CELIX_FACTORY_SERVICE, &registration);
+    return registration;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/626687fe/framework/src/service_registration_private.h
----------------------------------------------------------------------
diff --git a/framework/src/service_registration_private.h b/framework/src/service_registration_private.h
index ca0cb67..598e4c9 100644
--- a/framework/src/service_registration_private.h
+++ b/framework/src/service_registration_private.h
@@ -31,19 +31,26 @@
 #include "registry_callback_private.h"
 #include "service_registration.h"
 
+enum celix_service_type {
+	CELIX_PLAIN_SERVICE,
+	CELIX_FACTORY_SERVICE,
+	CELIX_DEPRECATED_FACTORY_SERVICE
+};
+
 struct serviceRegistration {
     registry_callback_t callback;
 
 	char * className;
 	bundle_pt bundle;
 	properties_pt properties;
-	const void * svcObj;
 	unsigned long serviceId;
 
 	bool isUnregistering;
 
-	bool isServiceFactory;
-	const void *serviceFactory;
+	enum celix_service_type svcType;
+	const void * svcObj;
+	service_factory_pt deprecatedFactory;
+	celix_service_factory_t *factory;
 
 	struct service *services;
 	int nrOfServices;
@@ -68,4 +75,13 @@ celix_status_t serviceRegistration_ungetService(service_registration_pt registra
 celix_status_t serviceRegistration_getBundle(service_registration_pt registration, bundle_pt *bundle);
 celix_status_t serviceRegistration_getServiceName(service_registration_pt registration, const char **serviceName);
 
+
+service_registration_t* celix_serviceRegistration_createServiceFactory(
+		registry_callback_t callback,
+		const celix_bundle_t *bnd,
+		const char *serviceName,
+		long svcId,
+		celix_service_factory_t* factory,
+		celix_properties_t *props);
+
 #endif /* SERVICE_REGISTRATION_PRIVATE_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/626687fe/framework/src/service_registry.c
----------------------------------------------------------------------
diff --git a/framework/src/service_registry.c b/framework/src/service_registry.c
index 65c1914..1493525 100644
--- a/framework/src/service_registry.c
+++ b/framework/src/service_registry.c
@@ -41,7 +41,7 @@
 #define CHECK_DELETED_REFERENCES false
 #endif
 
-static celix_status_t serviceRegistry_registerServiceInternal(service_registry_pt registry, bundle_pt bundle, const char* serviceName, const void * serviceObject, properties_pt dictionary, bool isFactory, service_registration_pt *registration);
+static celix_status_t serviceRegistry_registerServiceInternal(service_registry_pt registry, bundle_pt bundle, const char* serviceName, const void * serviceObject, properties_pt dictionary, enum celix_service_type svcType, service_registration_pt *registration);
 static celix_status_t serviceRegistry_addHooks(service_registry_pt registry, const char* serviceName, const void *serviceObject, service_registration_pt registration);
 static celix_status_t serviceRegistry_removeHook(service_registry_pt registry, service_registration_pt registration);
 static void serviceRegistry_logWarningServiceReferenceUsageCount(service_registry_pt registry, bundle_pt bundle, service_reference_pt ref, size_t usageCount, size_t refCount);
@@ -154,12 +154,16 @@ celix_status_t serviceRegistry_registerServiceFactory(service_registry_pt regist
     return serviceRegistry_registerServiceInternal(registry, bundle, serviceName, (const void *) factory, dictionary, true, registration);
 }
 
-static celix_status_t serviceRegistry_registerServiceInternal(service_registry_pt registry, bundle_pt bundle, const char* serviceName, const void* serviceObject, properties_pt dictionary, bool isFactory, service_registration_pt *registration) {
+static celix_status_t serviceRegistry_registerServiceInternal(service_registry_pt registry, bundle_pt bundle, const char* serviceName, const void * serviceObject, properties_pt dictionary, enum celix_service_type svcType, service_registration_pt *registration) {
 	array_list_pt regs;
 
-	if (isFactory) {
-	    *registration = serviceRegistration_createServiceFactory(registry->callback, bundle, serviceName, ++registry->currentServiceId, serviceObject, dictionary);
-	} else {
+	if (svcType == CELIX_DEPRECATED_FACTORY_SERVICE) {
+        *registration = serviceRegistration_createServiceFactory(registry->callback, bundle, serviceName,
+                                                                 ++registry->currentServiceId, serviceObject,
+                                                                 dictionary);
+    } else if (svcType == CELIX_FACTORY_SERVICE) {
+        *registration = celix_serviceRegistration_createServiceFactory(registry->callback, bundle, serviceName, ++registry->currentServiceId, (celix_service_factory_t*)serviceObject, dictionary);
+	} else { //plain
 	    *registration = serviceRegistration_create(registry->callback, bundle, serviceName, ++registry->currentServiceId, serviceObject, dictionary);
 	}
 
@@ -800,3 +804,14 @@ static celix_status_t serviceRegistry_getUsingBundles(service_registry_pt regist
 
     return status;
 }
+
+celix_status_t
+celix_serviceRegistry_registerServiceFactory(
+        celix_service_registry_t *reg,
+        const celix_bundle_t *bnd,
+        const char *serviceName,
+        celix_service_factory_t *factory,
+        celix_properties_t* props,
+        service_registration_t **registration) {
+    return serviceRegistry_registerServiceInternal(reg, (celix_bundle_t*)bnd, serviceName, (const void *) factory, props, CELIX_FACTORY_SERVICE, registration);
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/celix/blob/626687fe/framework/src/service_registry_private.h
----------------------------------------------------------------------
diff --git a/framework/src/service_registry_private.h b/framework/src/service_registry_private.h
index d68fe11..1bd0066 100644
--- a/framework/src/service_registry_private.h
+++ b/framework/src/service_registry_private.h
@@ -31,7 +31,7 @@
 #include "registry_callback_private.h"
 #include "service_registry.h"
 
-struct serviceRegistry {
+struct celix_serviceRegistry {
 	framework_pt framework;
 	registry_callback_t callback;
 

http://git-wip-us.apache.org/repos/asf/celix/blob/626687fe/framework/tst/bundle_context_services_test.cpp
----------------------------------------------------------------------
diff --git a/framework/tst/bundle_context_services_test.cpp b/framework/tst/bundle_context_services_test.cpp
index 790cbd2..2597ece 100644
--- a/framework/tst/bundle_context_services_test.cpp
+++ b/framework/tst/bundle_context_services_test.cpp
@@ -26,11 +26,13 @@
 #include <CppUTest/CommandLineTestRunner.h>
 #include <zconf.h>
 #include <string.h>
+#include <map>
 
 #include "constants.h"
 #include "bundle.h"
 #include "properties.h"
 #include "celix_framework_factory.h"
+#include "celix_service_factory.h"
 
 
 TEST_GROUP(CelixBundleContextServicesTests) {
@@ -582,3 +584,47 @@ TEST(CelixBundleContextServicesTests, servicesTrackerSetTest) {
 }
 
 //TODO test tracker with options for properties & service owners
+
+
+TEST(CelixBundleContextServicesTests, serviceFactoryTest) {
+    struct calc {
+        int (*calc)(int);
+    };
+    auto name = "CALC";
+    auto version = "1.0.0";
+
+
+    int count = 0;
+    celix_service_factory_t fac;
+    memset(&fac, 0, sizeof(fac));
+    fac.handle = (void*)&count;
+    fac.getService = [](void *handle, const celix_bundle_t *, const celix_properties_t *) -> void* {
+        auto *c = (int *)handle;
+        *c += 1;
+        static struct calc svc{}; //normally a service per bundle
+        svc.calc = [](int arg) { return arg * 42; };
+        return &svc;
+    };
+    fac.ungetService = [](void *handle, const celix_bundle_t *, const celix_properties_t *) {
+        auto *c = (int *)handle;
+        *c += 1;
+    };
+
+    long facId = celix_bundleContext_registerServiceFactory(ctx, name, &fac, version, NULL);
+    CHECK_TRUE(facId >= 0);
+
+
+    int result = -1;
+    bool called = celix_bundleContext_useService(ctx, name, &result, [](void *handle, void* svc) {
+        auto *r = (int *)(handle);
+        auto *calc = (struct calc*)svc;
+        *r = calc->calc(2);
+    });
+    CHECK_TRUE(called);
+    CHECK_EQUAL(84, result);
+    CHECK_EQUAL(2, count); //expecting getService & unGetService to be called during the useService call.
+
+
+    celix_bundleContext_unregisterService(ctx, facId);
+}
+


[05/12] celix git commit: CELIX-446: Fixes a bug in the service_registry/registration

Posted by pn...@apache.org.
CELIX-446: Fixes a bug in the service_registry/registration


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

Branch: refs/heads/feature/CELIX-426-cxx-api
Commit: ae09682152db94204a12a2abd138e95e83af49ee
Parents: 626687f
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Fri May 11 11:47:09 2018 +0200
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Fri May 11 11:47:09 2018 +0200

----------------------------------------------------------------------
 framework/src/service_registration.c | 4 ++--
 framework/src/service_registry.c     | 4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/ae096821/framework/src/service_registration.c
----------------------------------------------------------------------
diff --git a/framework/src/service_registration.c b/framework/src/service_registration.c
index b3f45b2..91fa62c 100644
--- a/framework/src/service_registration.c
+++ b/framework/src/service_registration.c
@@ -38,13 +38,13 @@ static celix_status_t serviceRegistration_destroy(service_registration_pt regist
 
 service_registration_pt serviceRegistration_create(registry_callback_t callback, bundle_pt bundle, const char* serviceName, unsigned long serviceId, const void * serviceObject, properties_pt dictionary) {
     service_registration_pt registration = NULL;
-	serviceRegistration_createInternal(callback, bundle, serviceName, serviceId, serviceObject, dictionary, false, &registration);
+	serviceRegistration_createInternal(callback, bundle, serviceName, serviceId, serviceObject, dictionary, CELIX_PLAIN_SERVICE, &registration);
 	return registration;
 }
 
 service_registration_pt serviceRegistration_createServiceFactory(registry_callback_t callback, bundle_pt bundle, const char* serviceName, unsigned long serviceId, const void * serviceObject, properties_pt dictionary) {
     service_registration_pt registration = NULL;
-    serviceRegistration_createInternal(callback, bundle, serviceName, serviceId, serviceObject, dictionary, true, &registration);
+    serviceRegistration_createInternal(callback, bundle, serviceName, serviceId, serviceObject, dictionary, CELIX_DEPRECATED_FACTORY_SERVICE, &registration);
     return registration;
 }
 

http://git-wip-us.apache.org/repos/asf/celix/blob/ae096821/framework/src/service_registry.c
----------------------------------------------------------------------
diff --git a/framework/src/service_registry.c b/framework/src/service_registry.c
index 1493525..026c252 100644
--- a/framework/src/service_registry.c
+++ b/framework/src/service_registry.c
@@ -147,11 +147,11 @@ celix_status_t serviceRegistry_getRegisteredServices(service_registry_pt registr
 }
 
 celix_status_t serviceRegistry_registerService(service_registry_pt registry, bundle_pt bundle, const char* serviceName, const void* serviceObject, properties_pt dictionary, service_registration_pt *registration) {
-    return serviceRegistry_registerServiceInternal(registry, bundle, serviceName, serviceObject, dictionary, false, registration);
+    return serviceRegistry_registerServiceInternal(registry, bundle, serviceName, serviceObject, dictionary, CELIX_PLAIN_SERVICE, registration);
 }
 
 celix_status_t serviceRegistry_registerServiceFactory(service_registry_pt registry, bundle_pt bundle, const char* serviceName, service_factory_pt factory, properties_pt dictionary, service_registration_pt *registration) {
-    return serviceRegistry_registerServiceInternal(registry, bundle, serviceName, (const void *) factory, dictionary, true, registration);
+    return serviceRegistry_registerServiceInternal(registry, bundle, serviceName, (const void *) factory, dictionary, CELIX_DEPRECATED_FACTORY_SERVICE, registration);
 }
 
 static celix_status_t serviceRegistry_registerServiceInternal(service_registry_pt registry, bundle_pt bundle, const char* serviceName, const void * serviceObject, properties_pt dictionary, enum celix_service_type svcType, service_registration_pt *registration) {


[11/12] celix git commit: Merge branch 'develop' into feature/CELIX-426-cxx-api

Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/8464f3d5/framework/src/framework.c
----------------------------------------------------------------------
diff --cc framework/src/framework.c
index 0566572,2460434..c87eaf4
--- a/framework/src/framework.c
+++ b/framework/src/framework.c
@@@ -53,12 -54,12 +54,12 @@@ typedef celix_status_t (*dm_destroy_fp)
  
  struct activator {
      void * userData;
--
++    
      create_function_fp create;
      start_function_fp start;
      stop_function_fp stop;
      destroy_function_fp destroy;
--
++    
      dm_create_fp dmCreate;
      dm_init_fp dmInit;
      dm_destroy_fp dmDestroy;
@@@ -114,47 -115,47 +115,47 @@@ celix_status_t fw_refreshHelper_restart
  celix_status_t fw_refreshHelper_stop(struct fw_refreshHelper * refreshHelper);
  
  struct fw_serviceListener {
--	bundle_pt bundle;
--	service_listener_pt listener;
--	filter_pt filter;
++    bundle_pt bundle;
++    service_listener_pt listener;
++    filter_pt filter;
      array_list_pt retainedReferences;
  };
  
  typedef struct fw_serviceListener * fw_service_listener_pt;
  
  struct fw_bundleListener {
--	bundle_pt bundle;
--	bundle_listener_pt listener;
++    bundle_pt bundle;
++    bundle_listener_pt listener;
  };
  
  typedef struct fw_bundleListener * fw_bundle_listener_pt;
  
  struct fw_frameworkListener {
--	bundle_pt bundle;
--	framework_listener_pt listener;
++    bundle_pt bundle;
++    framework_listener_pt listener;
  };
  
  typedef struct fw_frameworkListener * fw_framework_listener_pt;
  
  enum event_type {
--	FRAMEWORK_EVENT_TYPE,
--	BUNDLE_EVENT_TYPE,
--	EVENT_TYPE_SERVICE,
++    FRAMEWORK_EVENT_TYPE,
++    BUNDLE_EVENT_TYPE,
++    EVENT_TYPE_SERVICE,
  };
  
  typedef enum event_type event_type_e;
  
  struct request {
--	event_type_e type;
--	array_list_pt listeners;
--
--	int eventType;
--	long bundleId;
--	char* bundleSymbolicName;
--	celix_status_t errorCode;
--	char *error;
--
--	char *filter;
++    event_type_e type;
++    array_list_pt listeners;
++    
++    int eventType;
++    long bundleId;
++    char* bundleSymbolicName;
++    celix_status_t errorCode;
++    char *error;
++    
++    char *filter;
  };
  
  typedef struct request *request_pt;
@@@ -180,45 -181,45 +181,45 @@@ static void framework_loggerInit(void) 
   * Refer to dlopen manpage for additional details about libraries dynamic loading.
   */
  #ifdef _WIN32
--    #define handle_t HMODULE
--    #define fw_openLibrary(path) LoadLibrary(path)
--    #define fw_closeLibrary(handle) FreeLibrary(handle)
++#define handle_t HMODULE
++#define fw_openLibrary(path) LoadLibrary(path)
++#define fw_closeLibrary(handle) FreeLibrary(handle)
  
--    #define fw_getSymbol(handle, name) GetProcAddress(handle, name)
++#define fw_getSymbol(handle, name) GetProcAddress(handle, name)
  
--    #define fw_getLastError() GetLastError()
++#define fw_getLastError() GetLastError()
  
--    HMODULE fw_getCurrentModule() {
--        HMODULE hModule = NULL;
--        GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCTSTR)fw_getCurrentModule, &hModule);
--        return hModule;
--    }
++HMODULE fw_getCurrentModule() {
++    HMODULE hModule = NULL;
++    GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCTSTR)fw_getCurrentModule, &hModule);
++    return hModule;
++}
++#else
++#define handle_t void *
++#if defined(DEBUG) && !defined(ANDROID)
++#define fw_openLibrary(path) dlopen(path, RTLD_LAZY|RTLD_LOCAL|RTLD_NODELETE)
  #else
--    #define handle_t void *
--    #if defined(DEBUG) && !defined(ANDROID)
--	#define fw_openLibrary(path) dlopen(path, RTLD_LAZY|RTLD_LOCAL|RTLD_NODELETE)
--    #else
--	#define fw_openLibrary(path) dlopen(path, RTLD_LAZY|RTLD_LOCAL)
--    #endif
--    #define fw_closeLibrary(handle) dlclose(handle)
--    #define fw_getSymbol(handle, name) dlsym(handle, name)
--    #define fw_getLastError() dlerror()
++#define fw_openLibrary(path) dlopen(path, RTLD_LAZY|RTLD_LOCAL)
++#endif
++#define fw_closeLibrary(handle) dlclose(handle)
++#define fw_getSymbol(handle, name) dlsym(handle, name)
++#define fw_getLastError() dlerror()
  #endif
  
  celix_status_t framework_create(framework_pt *framework, properties_pt config) {
      celix_status_t status = CELIX_SUCCESS;
--
++    
      logger = hashMap_get(config, "logger");
      if (logger == NULL) {
          celixThread_once(&loggerInit, framework_loggerInit);
      }
--
++    
      *framework = (framework_pt) malloc(sizeof(**framework));
      if (*framework != NULL) {
          celix_thread_mutexattr_t attr;
          celixThreadMutexAttr_create(&attr);
          celixThreadMutexAttr_settype(&attr, CELIX_THREAD_MUTEX_RECURSIVE);
--
++        
          status = CELIX_DO_IF(status, celixThreadCondition_init(&(*framework)->condition, NULL));
          status = CELIX_DO_IF(status, celixThreadMutex_create(&(*framework)->mutex, NULL));
          status = CELIX_DO_IF(status, celixThreadMutex_create(&(*framework)->installedBundleMapLock, NULL));
@@@ -247,12 -248,8 +248,8 @@@
              (*framework)->requests = NULL;
              (*framework)->configurationMap = config;
              (*framework)->logger = logger;
--
-             //gen uuid
-             uuid_t uuid;
-             uuid_generate(uuid);
-             uuid_unparse(uuid, (*framework)->uuid);
--
++            
++            
              status = CELIX_DO_IF(status, bundle_create(&(*framework)->bundle));
              status = CELIX_DO_IF(status, arrayList_create(&(*framework)->globalLockWaitersList));
              status = CELIX_DO_IF(status, bundle_setFramework((*framework)->bundle, (*framework)));
@@@ -270,14 -267,14 +267,14 @@@
          status = CELIX_FRAMEWORK_EXCEPTION;
          fw_logCode(logger, OSGI_FRAMEWORK_LOG_ERROR, CELIX_ENOMEM, "Could not create framework");
      }
--
++    
      return status;
  }
  
  celix_status_t framework_destroy(framework_pt framework) {
      celix_status_t status = CELIX_SUCCESS;
      celixThreadMutex_lock(&framework->installedBundleMapLock);
--
++    
      if (framework->installedBundleMap != NULL) {
          hash_map_iterator_pt iterator = hashMapIterator_create(framework->installedBundleMap);
          while (hashMapIterator_hasNext(iterator)) {
@@@ -285,7 -282,7 +282,7 @@@
              bundle_pt bundle = (bundle_pt) hashMapEntry_getValue(entry);
              char * key = hashMapEntry_getKey(entry);
              bundle_archive_pt archive = NULL;
--
++            
              bool systemBundle = false;
              bundle_isSystemBundle(bundle, &systemBundle);
              if (systemBundle) {
@@@ -293,7 -290,7 +290,7 @@@
                  bundle_getContext(framework->bundle, &context);
                  bundleContext_destroy(context);
              }
--
++            
              if (bundle_getArchive(bundle, &archive) == CELIX_SUCCESS) {
                  if (!systemBundle) {
                      bundle_revision_pt revision = NULL;
@@@ -307,7 -304,7 +304,7 @@@
                          }
                      }
                  }
--
++                
                  bundleArchive_destroy(archive);
              }
              bundle_destroy(bundle);
@@@ -316,15 -313,15 +313,15 @@@
          }
          hashMapIterator_destroy(iterator);
      }
--
++    
      celixThreadMutex_unlock(&framework->installedBundleMapLock);
--
--	hashMap_destroy(framework->installRequestMap, false, false);
--
--	serviceRegistry_destroy(framework->registry);
--
--	arrayList_destroy(framework->globalLockWaitersList);
--
++    
++    hashMap_destroy(framework->installRequestMap, false, false);
++    
++    serviceRegistry_destroy(framework->registry);
++    
++    arrayList_destroy(framework->globalLockWaitersList);
++    
      if (framework->serviceListeners != NULL) {
          arrayList_destroy(framework->serviceListeners);
      }
@@@ -334,81 -331,89 +331,89 @@@
      if (framework->frameworkListeners) {
          arrayList_destroy(framework->frameworkListeners);
      }
--
--	if(framework->requests){
--	    int i;
--	    for (i = 0; i < arrayList_size(framework->requests); i++) {
--	        request_pt request = arrayList_get(framework->requests, i);
--	        free(request);
--	    }
--	    arrayList_destroy(framework->requests);
--	}
--	if(framework->installedBundleMap!=NULL){
--		hashMap_destroy(framework->installedBundleMap, true, false);
--	}
--
--	bundleCache_destroy(&framework->cache);
--
--	celixThreadCondition_destroy(&framework->dispatcher);
++    
++    if(framework->requests){
++        int i;
++        for (i = 0; i < arrayList_size(framework->requests); i++) {
++            request_pt request = arrayList_get(framework->requests, i);
++            free(request);
++        }
++        arrayList_destroy(framework->requests);
++    }
++    if(framework->installedBundleMap!=NULL){
++        hashMap_destroy(framework->installedBundleMap, true, false);
++    }
++    
++    bundleCache_destroy(&framework->cache);
++    
++    celixThreadCondition_destroy(&framework->dispatcher);
      celixThreadMutex_destroy(&framework->serviceListenersLock);
      celixThreadMutex_destroy(&framework->frameworkListenersLock);
--	celixThreadMutex_destroy(&framework->bundleListenerLock);
--	celixThreadMutex_destroy(&framework->dispatcherLock);
--	celixThreadMutex_destroy(&framework->installRequestLock);
--	celixThreadMutex_destroy(&framework->bundleLock);
--	celixThreadMutex_destroy(&framework->installedBundleMapLock);
--	celixThreadMutex_destroy(&framework->mutex);
--	celixThreadCondition_destroy(&framework->condition);
--
++    celixThreadMutex_destroy(&framework->bundleListenerLock);
++    celixThreadMutex_destroy(&framework->dispatcherLock);
++    celixThreadMutex_destroy(&framework->installRequestLock);
++    celixThreadMutex_destroy(&framework->bundleLock);
++    celixThreadMutex_destroy(&framework->installedBundleMapLock);
++    celixThreadMutex_destroy(&framework->mutex);
++    celixThreadCondition_destroy(&framework->condition);
++    
      logger = hashMap_get(framework->configurationMap, "logger");
      if (logger == NULL) {
          free(framework->logger);
      }
--
++    
      properties_destroy(framework->configurationMap);
--
++    
      free(framework);
--
--	return status;
++    
++    return status;
  }
  
  celix_status_t fw_init(framework_pt framework) {
--	bundle_state_e state;
--	const char *location = NULL;
--	module_pt module = NULL;
--	linked_list_pt wires = NULL;
--	array_list_pt archives = NULL;
--	bundle_archive_pt archive = NULL;
--
--	celix_status_t status = CELIX_SUCCESS;
--	status = CELIX_DO_IF(status, framework_acquireBundleLock(framework, framework->bundle, OSGI_FRAMEWORK_BUNDLE_INSTALLED|OSGI_FRAMEWORK_BUNDLE_RESOLVED|OSGI_FRAMEWORK_BUNDLE_STARTING|OSGI_FRAMEWORK_BUNDLE_ACTIVE));
--	status = CELIX_DO_IF(status, arrayList_create(&framework->serviceListeners));
--	status = CELIX_DO_IF(status, arrayList_create(&framework->bundleListeners));
--	status = CELIX_DO_IF(status, arrayList_create(&framework->frameworkListeners));
--	status = CELIX_DO_IF(status, arrayList_create(&framework->requests));
--	status = CELIX_DO_IF(status, celixThread_create(&framework->dispatcherThread, NULL, fw_eventDispatcher, framework));
--	status = CELIX_DO_IF(status, bundle_getState(framework->bundle, &state));
--	if (status == CELIX_SUCCESS) {
--	    if ((state == OSGI_FRAMEWORK_BUNDLE_INSTALLED) || (state == OSGI_FRAMEWORK_BUNDLE_RESOLVED)) {
--	        bundle_state_e state;
--	        status = CELIX_DO_IF(status, bundleCache_create(framework->configurationMap,&framework->cache));
--	        status = CELIX_DO_IF(status, bundle_getState(framework->bundle, &state));
--	        if (status == CELIX_SUCCESS) {
--	            if (state == OSGI_FRAMEWORK_BUNDLE_INSTALLED) {
--	                const char *clean = properties_get(framework->configurationMap, OSGI_FRAMEWORK_FRAMEWORK_STORAGE_CLEAN);
--	                if (clean != NULL && (strcmp(clean, OSGI_FRAMEWORK_FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT) == 0)) {
--	                    bundleCache_delete(framework->cache);
--	                }
--	            }
++    bundle_state_e state;
++    const char *location = NULL;
++    module_pt module = NULL;
++    linked_list_pt wires = NULL;
++    array_list_pt archives = NULL;
++    bundle_archive_pt archive = NULL;
++    
++    celix_status_t status = CELIX_SUCCESS;
++    status = CELIX_DO_IF(status, framework_acquireBundleLock(framework, framework->bundle, OSGI_FRAMEWORK_BUNDLE_INSTALLED|OSGI_FRAMEWORK_BUNDLE_RESOLVED|OSGI_FRAMEWORK_BUNDLE_STARTING|OSGI_FRAMEWORK_BUNDLE_ACTIVE));
++    status = CELIX_DO_IF(status, arrayList_create(&framework->serviceListeners));
++    status = CELIX_DO_IF(status, arrayList_create(&framework->bundleListeners));
++    status = CELIX_DO_IF(status, arrayList_create(&framework->frameworkListeners));
++    status = CELIX_DO_IF(status, arrayList_create(&framework->requests));
++    status = CELIX_DO_IF(status, celixThread_create(&framework->dispatcherThread, NULL, fw_eventDispatcher, framework));
++    status = CELIX_DO_IF(status, bundle_getState(framework->bundle, &state));
++    if (status == CELIX_SUCCESS) {
++        if ((state == OSGI_FRAMEWORK_BUNDLE_INSTALLED) || (state == OSGI_FRAMEWORK_BUNDLE_RESOLVED)) {
++            bundle_state_e state;
++            status = CELIX_DO_IF(status, bundleCache_create(framework->configurationMap,&framework->cache));
++            status = CELIX_DO_IF(status, bundle_getState(framework->bundle, &state));
++            if (status == CELIX_SUCCESS) {
++                if (state == OSGI_FRAMEWORK_BUNDLE_INSTALLED) {
++                    const char *clean = properties_get(framework->configurationMap, OSGI_FRAMEWORK_FRAMEWORK_STORAGE_CLEAN);
++                    if (clean != NULL && (strcmp(clean, OSGI_FRAMEWORK_FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT) == 0)) {
++                        bundleCache_delete(framework->cache);
++                    }
++                }
              }
          }
--	}
--
--	if (status == CELIX_SUCCESS) {
-         properties_set(framework->configurationMap, (char*) OSGI_FRAMEWORK_FRAMEWORK_UUID, framework->uuid);
++    }
++    
++    if (status == CELIX_SUCCESS) {
+         /*create and store framework uuid*/
+         char uuid[37];
 -
 -	    uuid_t uid;
++        
++        uuid_t uid;
+         uuid_generate(uid);
+         uuid_unparse(uid, uuid);
 -
++        
+         properties_set(framework->configurationMap, (char*) OSGI_FRAMEWORK_FRAMEWORK_UUID, uuid);
 -
++        
          framework->installedBundleMap = hashMap_create(utils_stringHash, NULL, utils_stringEquals, NULL);
--	}
--
++    }
++    
      status = CELIX_DO_IF(status, bundle_getArchive(framework->bundle, &archive));
      status = CELIX_DO_IF(status, bundleArchive_getLocation(archive, &location));
      if (status == CELIX_SUCCESS) {
@@@ -424,7 -429,7 +429,7 @@@
              fw_logCode(framework->logger, OSGI_FRAMEWORK_LOG_ERROR, status, "Unresolved constraints in System Bundle");
          }
      }
--
++    
      status = CELIX_DO_IF(status, bundleCache_getArchives(framework->cache, &archives));
      if (status == CELIX_SUCCESS) {
          unsigned int arcIdx;
@@@ -434,7 -439,7 +439,7 @@@
              bundle_state_e bundleState;
              bundleArchive_getId(archive1, &id);
              framework->nextBundleId = framework->nextBundleId > id + 1 ? framework->nextBundleId : id + 1;
--
++            
              bundleArchive_getPersistentState(archive1, &bundleState);
              if (bundleState == OSGI_FRAMEWORK_BUNDLE_UNINSTALLED) {
                  bundleArchive_closeAndDelete(archive1);
@@@ -447,11 -452,11 +452,11 @@@
          }
          arrayList_destroy(archives);
      }
--
++    
      status = CELIX_DO_IF(status, serviceRegistry_create(framework, fw_serviceChanged, &framework->registry));
      status = CELIX_DO_IF(status, framework_setBundleStateAndNotify(framework, framework->bundle, OSGI_FRAMEWORK_BUNDLE_STARTING));
      status = CELIX_DO_IF(status, celixThreadCondition_init(&framework->shutdownGate, NULL));
--
++    
      bundle_context_t *context = NULL;
      status = CELIX_DO_IF(status, bundleContext_create(framework, framework->logger, framework->bundle, &context));
      status = CELIX_DO_IF(status, bundle_setContext(framework->bundle, context));
@@@ -461,92 -466,84 +466,84 @@@
          if (activator != NULL) {
              bundle_context_t *context = NULL;
              void * userData = NULL;
--
--			//create_function_pt create = NULL;
--			start_function_fp start = (start_function_fp) frameworkActivator_start;
--			stop_function_fp stop = (stop_function_fp) frameworkActivator_stop;
--			destroy_function_fp destroy = (destroy_function_fp) frameworkActivator_destroy;
--
++            
++            //create_function_pt create = NULL;
++            start_function_fp start = (start_function_fp) frameworkActivator_start;
++            stop_function_fp stop = (stop_function_fp) frameworkActivator_stop;
++            destroy_function_fp destroy = (destroy_function_fp) frameworkActivator_destroy;
++            
              activator->start = start;
              activator->stop = stop;
              activator->destroy = destroy;
              status = CELIX_DO_IF(status, bundle_setActivator(framework->bundle, activator));
              status = CELIX_DO_IF(status, bundle_getContext(framework->bundle, &context));
--
++            
              if (status == CELIX_SUCCESS) {
                  /* This code part is in principle dead, but in future it may do something.
                   * That's why it's outcommented and not deleted
--		        if (create != NULL) {
--                    create(context, &userData);
--                }
--                */
++                 if (create != NULL) {
++                 create(context, &userData);
++                 }
++                 */
                  activator->userData = userData;
--
++                
                  if (start != NULL) {
                      start(userData, context);
                  }
              }
              else{
--            	free(activator);
++                free(activator);
              }
          } else {
              status = CELIX_ENOMEM;
          }
      }
--
++    
      if (status != CELIX_SUCCESS) {
--       fw_logCode(framework->logger, OSGI_FRAMEWORK_LOG_ERROR, status, "Could not init framework");
++        fw_logCode(framework->logger, OSGI_FRAMEWORK_LOG_ERROR, status, "Could not init framework");
      }
--
++    
      framework_releaseBundleLock(framework, framework->bundle);
--
--	return status;
- }
- 
- FRAMEWORK_EXPORT const char* framework_getUUID(framework_t *framework) {
-     const char *uuid = NULL;
-     if (framework != NULL) {
-         uuid = framework->uuid;
-     }
-     return uuid;
++    
++    return status;
  }
  
  celix_status_t framework_start(framework_pt framework) {
--	celix_status_t status = CELIX_SUCCESS;
--	bundle_state_e state = OSGI_FRAMEWORK_BUNDLE_UNKNOWN;
--
--	status = CELIX_DO_IF(status, framework_acquireBundleLock(framework, framework->bundle, OSGI_FRAMEWORK_BUNDLE_INSTALLED|OSGI_FRAMEWORK_BUNDLE_RESOLVED|OSGI_FRAMEWORK_BUNDLE_STARTING|OSGI_FRAMEWORK_BUNDLE_ACTIVE));
--	status = CELIX_DO_IF(status, bundle_getState(framework->bundle, &state));
--	if (status == CELIX_SUCCESS) {
--	    if ((state == OSGI_FRAMEWORK_BUNDLE_INSTALLED) || (state == OSGI_FRAMEWORK_BUNDLE_RESOLVED)) {
--	        status = CELIX_DO_IF(status, fw_init(framework));
++    celix_status_t status = CELIX_SUCCESS;
++    bundle_state_e state = OSGI_FRAMEWORK_BUNDLE_UNKNOWN;
++    
++    status = CELIX_DO_IF(status, framework_acquireBundleLock(framework, framework->bundle, OSGI_FRAMEWORK_BUNDLE_INSTALLED|OSGI_FRAMEWORK_BUNDLE_RESOLVED|OSGI_FRAMEWORK_BUNDLE_STARTING|OSGI_FRAMEWORK_BUNDLE_ACTIVE));
++    status = CELIX_DO_IF(status, bundle_getState(framework->bundle, &state));
++    if (status == CELIX_SUCCESS) {
++        if ((state == OSGI_FRAMEWORK_BUNDLE_INSTALLED) || (state == OSGI_FRAMEWORK_BUNDLE_RESOLVED)) {
++            status = CELIX_DO_IF(status, fw_init(framework));
          }
--	}
--
--	status = CELIX_DO_IF(status, bundle_getState(framework->bundle, &state));
--	if (status == CELIX_SUCCESS) {
--	    if (state == OSGI_FRAMEWORK_BUNDLE_STARTING) {
--	        status = CELIX_DO_IF(status, framework_setBundleStateAndNotify(framework, framework->bundle, OSGI_FRAMEWORK_BUNDLE_ACTIVE));
--	    }
--
--	    framework_releaseBundleLock(framework, framework->bundle);
--	}
--
--	status = CELIX_DO_IF(status, fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_STARTED, framework->bundle));
--	status = CELIX_DO_IF(status, fw_fireFrameworkEvent(framework, OSGI_FRAMEWORK_EVENT_STARTED, framework->bundle, 0));
--
--	if (status != CELIX_SUCCESS) {
--       status = CELIX_BUNDLE_EXCEPTION;
--       fw_logCode(framework->logger, OSGI_FRAMEWORK_LOG_ERROR, status, "Could not start framework");
--       fw_fireFrameworkEvent(framework, OSGI_FRAMEWORK_EVENT_ERROR, framework->bundle, status);
      }
--
++    
++    status = CELIX_DO_IF(status, bundle_getState(framework->bundle, &state));
++    if (status == CELIX_SUCCESS) {
++        if (state == OSGI_FRAMEWORK_BUNDLE_STARTING) {
++            status = CELIX_DO_IF(status, framework_setBundleStateAndNotify(framework, framework->bundle, OSGI_FRAMEWORK_BUNDLE_ACTIVE));
++        }
++        
++        framework_releaseBundleLock(framework, framework->bundle);
++    }
++    
++    status = CELIX_DO_IF(status, fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_STARTED, framework->bundle));
++    status = CELIX_DO_IF(status, fw_fireFrameworkEvent(framework, OSGI_FRAMEWORK_EVENT_STARTED, framework->bundle, 0));
++    
++    if (status != CELIX_SUCCESS) {
++        status = CELIX_BUNDLE_EXCEPTION;
++        fw_logCode(framework->logger, OSGI_FRAMEWORK_LOG_ERROR, status, "Could not start framework");
++        fw_fireFrameworkEvent(framework, OSGI_FRAMEWORK_EVENT_ERROR, framework->bundle, status);
++    }
++    
      bundle_context_t *fwCtx = framework_getContext(framework);
--	if (fwCtx != NULL) {
++    if (fwCtx != NULL) {
          framework_autoStartConfiguredBundles(fwCtx);
      }
--
--	return status;
++    
++    return status;
  }
  
  static void framework_autoStartConfiguredBundles(bundle_context_t *fwCtx) {
@@@ -572,7 -569,7 +569,7 @@@ static void framework_autoStartConfigur
      array_list_pt installed = NULL;
      char *autoStart = strndup(autoStartIn, 1024*1024*10);
      arrayList_create(&installed);
--
++    
      if (autoStart != NULL) {
          char *location = strtok_r(autoStart, delims, &save_ptr);
          while (location != NULL) {
@@@ -587,7 -584,7 +584,7 @@@
              location = strtok_r(NULL, delims, &save_ptr);
          }
      }
--
++    
      unsigned int i;
      for (i = 0; i < arrayList_size(installed); ++i) {
          long bndId = -1;
@@@ -598,89 -595,89 +595,89 @@@
              printf("Could not start bundle %li\n", bndId);
          }
      }
--
++    
      free(autoStart);
      arrayList_destroy(installed);
  }
  
  
  celix_status_t framework_stop(framework_pt framework) {
--	return fw_stopBundle(framework, framework->bundle, true);
++    return fw_stopBundle(framework, framework->bundle, true);
  }
  
  celix_status_t fw_getProperty(framework_pt framework, const char* name, const char* defaultValue, const char** value) {
--	celix_status_t status = CELIX_SUCCESS;
--
--	if (framework == NULL || name == NULL) {
--		status = CELIX_ILLEGAL_ARGUMENT;
--	} else {
--		if (framework->configurationMap != NULL) {
--			*value = properties_get(framework->configurationMap, name);
--		}
--		if (*value == NULL) {
--			*value = getenv(name);
--		}
++    celix_status_t status = CELIX_SUCCESS;
++    
++    if (framework == NULL || name == NULL) {
++        status = CELIX_ILLEGAL_ARGUMENT;
++    } else {
++        if (framework->configurationMap != NULL) {
++            *value = properties_get(framework->configurationMap, name);
++        }
++        if (*value == NULL) {
++            *value = getenv(name);
++        }
          if (*value == NULL) {
              *value = defaultValue;
          }
--	}
--
--	return status;
++    }
++    
++    return status;
  }
  
  celix_status_t fw_installBundle(framework_pt framework, bundle_pt * bundle, const char * location, const char *inputFile) {
--	return fw_installBundle2(framework, bundle, -1, location, inputFile, NULL);
++    return fw_installBundle2(framework, bundle, -1, location, inputFile, NULL);
  }
  
  celix_status_t fw_installBundle2(framework_pt framework, bundle_pt * bundle, long id, const char * location, const char *inputFile, bundle_archive_pt archive) {
      celix_status_t status = CELIX_SUCCESS;
--//    bundle_archive_pt bundle_archive = NULL;
++    //    bundle_archive_pt bundle_archive = NULL;
      bundle_state_e state = OSGI_FRAMEWORK_BUNDLE_UNKNOWN;
--  	bool locked;
--
--  	status = CELIX_DO_IF(status, framework_acquireInstallLock(framework, location));
--  	status = CELIX_DO_IF(status, bundle_getState(framework->bundle, &state));
--  	if (status == CELIX_SUCCESS) {
++    bool locked;
++    
++    status = CELIX_DO_IF(status, framework_acquireInstallLock(framework, location));
++    status = CELIX_DO_IF(status, bundle_getState(framework->bundle, &state));
++    if (status == CELIX_SUCCESS) {
          if (state == OSGI_FRAMEWORK_BUNDLE_STOPPING || state == OSGI_FRAMEWORK_BUNDLE_UNINSTALLED) {
              fw_log(framework->logger, OSGI_FRAMEWORK_LOG_INFO,  "The framework is being shutdown");
              status = CELIX_DO_IF(status, framework_releaseInstallLock(framework, location));
              status = CELIX_FRAMEWORK_SHUTDOWN;
          }
--  	}
--
++    }
++    
      if (status == CELIX_SUCCESS) {
          *bundle = framework_getBundle(framework, location);
          if (*bundle != NULL) {
              framework_releaseInstallLock(framework, location);
              return CELIX_SUCCESS;
          }
--
++        
          if (archive == NULL) {
              id = framework_getNextBundleId(framework);
--
++            
              status = CELIX_DO_IF(status, bundleCache_createArchive(framework->cache, id, location, inputFile, &archive));
--
++            
              if (status != CELIX_SUCCESS) {
--            	bundleArchive_destroy(archive);
++                bundleArchive_destroy(archive);
              }
          } else {
              // purge revision
              // multiple revisions not yet implemented
          }
--
++        
          if (status == CELIX_SUCCESS) {
              locked = framework_acquireGlobalLock(framework);
              if (!locked) {
                  status = CELIX_BUNDLE_EXCEPTION;
              } else {
                  status = CELIX_DO_IF(status, bundle_createFromArchive(bundle, framework, archive));
--
++                
                  framework_releaseGlobalLock(framework);
                  if (status == CELIX_SUCCESS) {
                      celixThreadMutex_lock(&framework->installedBundleMapLock);
                      hashMap_put(framework->installedBundleMap, strdup(location), *bundle);
                      celixThreadMutex_unlock(&framework->installedBundleMapLock);
--
++                    
                  } else {
                      status = CELIX_BUNDLE_EXCEPTION;
                      status = CELIX_DO_IF(status, bundleArchive_closeAndDelete(archive));
@@@ -688,26 -685,26 +685,26 @@@
              }
          }
      }
--
++    
      framework_releaseInstallLock(framework, location);
--
++    
      if (status != CELIX_SUCCESS) {
--    	fw_logCode(framework->logger, OSGI_FRAMEWORK_LOG_ERROR, status, "Could not install bundle");
++        fw_logCode(framework->logger, OSGI_FRAMEWORK_LOG_ERROR, status, "Could not install bundle");
      } else {
          status = CELIX_DO_IF(status, fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_INSTALLED, *bundle));
      }
--
--  	return status;
++    
++    return status;
  }
  
  celix_status_t framework_getBundleEntry(framework_pt framework, bundle_pt bundle, const char* name, char** entry) {
--	celix_status_t status = CELIX_SUCCESS;
--
--	bundle_revision_pt revision;
--	bundle_archive_pt archive = NULL;
++    celix_status_t status = CELIX_SUCCESS;
++    
++    bundle_revision_pt revision;
++    bundle_archive_pt archive = NULL;
      const char *root;
--
--	status = CELIX_DO_IF(status, bundle_getArchive(bundle, &archive));
++    
++    status = CELIX_DO_IF(status, bundle_getArchive(bundle, &archive));
      status = CELIX_DO_IF(status, bundleArchive_getCurrentRevision(archive, &revision));
      status = CELIX_DO_IF(status, bundleRevision_getRoot(revision, &root));
      if (status == CELIX_SUCCESS) {
@@@ -719,33 -716,33 +716,33 @@@
              strcat(e, "/");
              strcat(e, name);
          }
--
++        
          if (access(e, F_OK) == 0) {
-             (*entry) = strndup(e, 1024*1024*10);
+             (*entry) = strndup(e, 1024*10);
          } else {
              (*entry) = NULL;
          }
      }
--
--	return status;
++    
++    return status;
  }
  
  celix_status_t fw_startBundle(framework_pt framework, bundle_pt bundle, int options __attribute__((unused))) {
--	celix_status_t status = CELIX_SUCCESS;
--
--	linked_list_pt wires = NULL;
--	bundle_context_t *context = NULL;
--	bundle_state_e state;
--	module_pt module = NULL;
--	activator_pt activator = NULL;
--	char *error = NULL;
--	const char *name = NULL;
--
--	status = CELIX_DO_IF(status, framework_acquireBundleLock(framework, bundle, OSGI_FRAMEWORK_BUNDLE_INSTALLED|OSGI_FRAMEWORK_BUNDLE_RESOLVED|OSGI_FRAMEWORK_BUNDLE_STARTING|OSGI_FRAMEWORK_BUNDLE_ACTIVE));
--	status = CELIX_DO_IF(status, bundle_getState(bundle, &state));
--
--	if (status == CELIX_SUCCESS) {
--	    switch (state) {
++    celix_status_t status = CELIX_SUCCESS;
++    
++    linked_list_pt wires = NULL;
++    bundle_context_t *context = NULL;
++    bundle_state_e state;
++    module_pt module = NULL;
++    activator_pt activator = NULL;
++    char *error = NULL;
++    const char *name = NULL;
++    
++    status = CELIX_DO_IF(status, framework_acquireBundleLock(framework, bundle, OSGI_FRAMEWORK_BUNDLE_INSTALLED|OSGI_FRAMEWORK_BUNDLE_RESOLVED|OSGI_FRAMEWORK_BUNDLE_STARTING|OSGI_FRAMEWORK_BUNDLE_ACTIVE));
++    status = CELIX_DO_IF(status, bundle_getState(bundle, &state));
++    
++    if (status == CELIX_SUCCESS) {
++        switch (state) {
              case OSGI_FRAMEWORK_BUNDLE_UNKNOWN:
                  error = "state is unknown";
                  status = CELIX_ILLEGAL_STATE;
@@@ -774,7 -771,7 +771,7 @@@
                          return CELIX_BUNDLE_EXCEPTION;
                      }
                      framework_markResolvedModules(framework, wires);
--
++                    
                  }
                  /* no break */
              case OSGI_FRAMEWORK_BUNDLE_RESOLVED:
@@@ -784,7 -781,7 +781,7 @@@
                  module_getSymbolicName(module, &name);
                  status = CELIX_DO_IF(status, bundleContext_create(framework, framework->logger, bundle, &context));
                  status = CELIX_DO_IF(status, bundle_setContext(bundle, context));
--
++                
                  if (status == CELIX_SUCCESS) {
                      activator = (activator_pt) calloc(1,(sizeof(*activator)));
                      if (activator == NULL) {
@@@ -796,20 -793,20 +793,20 @@@
                          start_function_fp start = (start_function_fp) fw_getSymbol((handle_t) bundle_getHandle(bundle), OSGI_FRAMEWORK_BUNDLE_ACTIVATOR_START);
                          stop_function_fp stop = (stop_function_fp) fw_getSymbol((handle_t) bundle_getHandle(bundle), OSGI_FRAMEWORK_BUNDLE_ACTIVATOR_STOP);
                          destroy_function_fp destroy = (destroy_function_fp) fw_getSymbol((handle_t) bundle_getHandle(bundle), OSGI_FRAMEWORK_BUNDLE_ACTIVATOR_DESTROY);
--
++                        
                          dm_create_fp dmCreate = fw_getSymbol((handle_t)bundle_getHandle(bundle), OSGI_FRAMEWORK_BUNDLE_DM_ACTIVATOR_CREATE);
                          dm_init_fp dmInit = fw_getSymbol((handle_t)bundle_getHandle(bundle), OSGI_FRAMEWORK_BUNDLE_DM_ACTIVATOR_INIT);
                          dm_destroy_fp dmDestroy = fw_getSymbol((handle_t)bundle_getHandle(bundle), OSGI_FRAMEWORK_BUNDLE_DM_ACTIVATOR_DESTROY);
--
++                        
                          activator->create = create;
                          activator->start = start;
                          activator->stop = stop;
                          activator->destroy = destroy;
--
++                        
                          activator->dmCreate = dmCreate;
                          activator->dmInit = dmInit;
                          activator->dmDestroy = dmDestroy;
--
++                        
                          if (activator->dmCreate != NULL) {
                              //only allow one activator, if dm is used -> set other to NULL
                              activator->create = NULL;
@@@ -817,14 -814,14 +814,14 @@@
                              activator->stop = NULL;
                              activator->destroy = NULL;
                          }
--
++                        
                          status = CELIX_DO_IF(status, bundle_setActivator(bundle, activator));
--
++                        
                          status = CELIX_DO_IF(status, framework_setBundleStateAndNotify(framework, bundle, OSGI_FRAMEWORK_BUNDLE_STARTING));
                          status = CELIX_DO_IF(status, fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_STARTING, bundle));
--
++                        
                          status = CELIX_DO_IF(status, bundle_getContext(bundle, &context));
--
++                        
                          if (status == CELIX_SUCCESS) {
                              if (create != NULL) {
                                  status = CELIX_DO_IF(status, create(context, &userData));
@@@ -846,97 -843,97 +843,97 @@@
                                  status = CELIX_DO_IF(status, dmInit(userData, context, mng));
                              }
                          }
--
++                        
                          status = CELIX_DO_IF(status, framework_setBundleStateAndNotify(framework, bundle, OSGI_FRAMEWORK_BUNDLE_ACTIVE));
                          status = CELIX_DO_IF(status, fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_STARTED, bundle));
                      }
                  }
--
--            break;
++                
++                break;
          }
--	}
--
--	framework_releaseBundleLock(framework, bundle);
--
--	if (status != CELIX_SUCCESS) {
--	    module_pt module = NULL;
--	    const char *symbolicName = NULL;
--	    long id = 0;
--	    bundle_getCurrentModule(bundle, &module);
--	    module_getSymbolicName(module, &symbolicName);
--	    bundle_getBundleId(bundle, &id);
--	    if (error != NULL) {
--	        fw_logCode(framework->logger, OSGI_FRAMEWORK_LOG_ERROR, status, "Could not start bundle: %s [%ld]; cause: %s", symbolicName, id, error);
--	    } else {
--	        fw_logCode(framework->logger, OSGI_FRAMEWORK_LOG_ERROR, status, "Could not start bundle: %s [%ld]", symbolicName, id);
--	    }
--	    if(activator!=NULL){
--	    	free(activator);
--	    }
--	}
--
--	return status;
++    }
++    
++    framework_releaseBundleLock(framework, bundle);
++    
++    if (status != CELIX_SUCCESS) {
++        module_pt module = NULL;
++        const char *symbolicName = NULL;
++        long id = 0;
++        bundle_getCurrentModule(bundle, &module);
++        module_getSymbolicName(module, &symbolicName);
++        bundle_getBundleId(bundle, &id);
++        if (error != NULL) {
++            fw_logCode(framework->logger, OSGI_FRAMEWORK_LOG_ERROR, status, "Could not start bundle: %s [%ld]; cause: %s", symbolicName, id, error);
++        } else {
++            fw_logCode(framework->logger, OSGI_FRAMEWORK_LOG_ERROR, status, "Could not start bundle: %s [%ld]", symbolicName, id);
++        }
++        if(activator!=NULL){
++            free(activator);
++        }
++    }
++    
++    return status;
  }
  
  celix_status_t framework_updateBundle(framework_pt framework, bundle_pt bundle, const char *inputFile) {
--	celix_status_t status = CELIX_SUCCESS;
--	bundle_state_e oldState;
--	const char *location;
--	bundle_archive_pt archive = NULL;
--	char *error = NULL;
--
--	status = CELIX_DO_IF(status, framework_acquireBundleLock(framework, bundle, OSGI_FRAMEWORK_BUNDLE_INSTALLED|OSGI_FRAMEWORK_BUNDLE_RESOLVED|OSGI_FRAMEWORK_BUNDLE_ACTIVE));
--	status = CELIX_DO_IF(status, bundle_getState(bundle, &oldState));
--	if (status == CELIX_SUCCESS) {
++    celix_status_t status = CELIX_SUCCESS;
++    bundle_state_e oldState;
++    const char *location;
++    bundle_archive_pt archive = NULL;
++    char *error = NULL;
++    
++    status = CELIX_DO_IF(status, framework_acquireBundleLock(framework, bundle, OSGI_FRAMEWORK_BUNDLE_INSTALLED|OSGI_FRAMEWORK_BUNDLE_RESOLVED|OSGI_FRAMEWORK_BUNDLE_ACTIVE));
++    status = CELIX_DO_IF(status, bundle_getState(bundle, &oldState));
++    if (status == CELIX_SUCCESS) {
          if (oldState == OSGI_FRAMEWORK_BUNDLE_ACTIVE) {
              fw_stopBundle(framework, bundle, false);
          }
--	}
--	status = CELIX_DO_IF(status, bundle_getArchive(bundle, &archive));
--	status = CELIX_DO_IF(status, bundleArchive_getLocation(archive, &location));
--
--	if (status == CELIX_SUCCESS) {
--	    bool locked = framework_acquireGlobalLock(framework);
--	    if (!locked) {
--	        status = CELIX_BUNDLE_EXCEPTION;
--	        error = "Unable to acquire the global lock to update the bundle";
--	    }
--	}
--
--	status = CELIX_DO_IF(status, bundle_revise(bundle, location, inputFile));
--	status = CELIX_DO_IF(status, framework_releaseGlobalLock(framework));
--
--	status = CELIX_DO_IF(status, bundleArchive_setLastModified(archive, time(NULL)));
--	status = CELIX_DO_IF(status, framework_setBundleStateAndNotify(framework, bundle, OSGI_FRAMEWORK_BUNDLE_INSTALLED));
--
--	bundle_revision_pt revision = NULL;
--	array_list_pt handles = NULL;
--	status = CELIX_DO_IF(status, bundleArchive_getCurrentRevision(archive, &revision));
++    }
++    status = CELIX_DO_IF(status, bundle_getArchive(bundle, &archive));
++    status = CELIX_DO_IF(status, bundleArchive_getLocation(archive, &location));
++    
++    if (status == CELIX_SUCCESS) {
++        bool locked = framework_acquireGlobalLock(framework);
++        if (!locked) {
++            status = CELIX_BUNDLE_EXCEPTION;
++            error = "Unable to acquire the global lock to update the bundle";
++        }
++    }
++    
++    status = CELIX_DO_IF(status, bundle_revise(bundle, location, inputFile));
++    status = CELIX_DO_IF(status, framework_releaseGlobalLock(framework));
++    
++    status = CELIX_DO_IF(status, bundleArchive_setLastModified(archive, time(NULL)));
++    status = CELIX_DO_IF(status, framework_setBundleStateAndNotify(framework, bundle, OSGI_FRAMEWORK_BUNDLE_INSTALLED));
++    
++    bundle_revision_pt revision = NULL;
++    array_list_pt handles = NULL;
++    status = CELIX_DO_IF(status, bundleArchive_getCurrentRevision(archive, &revision));
      status = CELIX_DO_IF(status, bundleRevision_getHandles(revision, &handles));
      if (handles != NULL) {
          int i;
--	    for (i = arrayList_size(handles) - 1; i >= 0; i--) {
--	        void* handle = arrayList_get(handles, i);
--	        fw_closeLibrary(handle);
--	    }
++        for (i = arrayList_size(handles) - 1; i >= 0; i--) {
++            void* handle = arrayList_get(handles, i);
++            fw_closeLibrary(handle);
++        }
      }
--
--
--	status = CELIX_DO_IF(status, fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_UNRESOLVED, bundle));
--	status = CELIX_DO_IF(status, fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_UPDATED, bundle));
--
++    
++    
++    status = CELIX_DO_IF(status, fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_UNRESOLVED, bundle));
++    status = CELIX_DO_IF(status, fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_UPDATED, bundle));
++    
      // Refresh packages?
--
--	if (status == CELIX_SUCCESS) {
--	    if (oldState == OSGI_FRAMEWORK_BUNDLE_ACTIVE) {
--	        status = CELIX_DO_IF(status, fw_startBundle(framework, bundle, 1));
--	    }
--	}
--
--	framework_releaseBundleLock(framework, bundle);
--
--	if (status != CELIX_SUCCESS) {
--	    module_pt module = NULL;
++    
++    if (status == CELIX_SUCCESS) {
++        if (oldState == OSGI_FRAMEWORK_BUNDLE_ACTIVE) {
++            status = CELIX_DO_IF(status, fw_startBundle(framework, bundle, 1));
++        }
++    }
++    
++    framework_releaseBundleLock(framework, bundle);
++    
++    if (status != CELIX_SUCCESS) {
++        module_pt module = NULL;
          const char *symbolicName = NULL;
          long id = 0;
          bundle_getCurrentModule(bundle, &module);
@@@ -947,29 -944,29 +944,29 @@@
          } else {
              fw_logCode(framework->logger, OSGI_FRAMEWORK_LOG_ERROR, status, "Cannot update bundle: %s [%ld]", symbolicName, id);
          }
--	}
--
--	return status;
++    }
++    
++    return status;
  }
  
  celix_status_t fw_stopBundle(framework_pt framework, bundle_pt bundle, bool record) {
--	celix_status_t status = CELIX_SUCCESS;
--	bundle_state_e state;
++    celix_status_t status = CELIX_SUCCESS;
++    bundle_state_e state;
      activator_pt activator = NULL;
      bundle_context_t *context = NULL;
      bool wasActive = false;
      long id = 0;
      char *error = NULL;
--
--	status = CELIX_DO_IF(status, framework_acquireBundleLock(framework, bundle, OSGI_FRAMEWORK_BUNDLE_INSTALLED|OSGI_FRAMEWORK_BUNDLE_RESOLVED|OSGI_FRAMEWORK_BUNDLE_STARTING|OSGI_FRAMEWORK_BUNDLE_ACTIVE));
--
--	if (record) {
--	    status = CELIX_DO_IF(status, bundle_setPersistentStateInactive(bundle));
++    
++    status = CELIX_DO_IF(status, framework_acquireBundleLock(framework, bundle, OSGI_FRAMEWORK_BUNDLE_INSTALLED|OSGI_FRAMEWORK_BUNDLE_RESOLVED|OSGI_FRAMEWORK_BUNDLE_STARTING|OSGI_FRAMEWORK_BUNDLE_ACTIVE));
++    
++    if (record) {
++        status = CELIX_DO_IF(status, bundle_setPersistentStateInactive(bundle));
      }
--
--	status = CELIX_DO_IF(status, bundle_getState(bundle, &state));
--	if (status == CELIX_SUCCESS) {
--	    switch (state) {
++    
++    status = CELIX_DO_IF(status, bundle_getState(bundle, &state));
++    if (status == CELIX_SUCCESS) {
++        switch (state) {
              case OSGI_FRAMEWORK_BUNDLE_UNKNOWN:
                  status = CELIX_ILLEGAL_STATE;
                  error = "state is unknown";
@@@ -993,18 -990,18 +990,18 @@@
                  wasActive = true;
                  break;
          }
--	}
--
--
--	status = CELIX_DO_IF(status, framework_setBundleStateAndNotify(framework, bundle, OSGI_FRAMEWORK_BUNDLE_STOPPING));
--	status = CELIX_DO_IF(status, fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_STOPPING, bundle));
++    }
++    
++    
++    status = CELIX_DO_IF(status, framework_setBundleStateAndNotify(framework, bundle, OSGI_FRAMEWORK_BUNDLE_STOPPING));
++    status = CELIX_DO_IF(status, fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_STOPPING, bundle));
      status = CELIX_DO_IF(status, bundle_getBundleId(bundle, &id));
--	if (status == CELIX_SUCCESS) {
--	    if (wasActive || (id == 0)) {
--	        activator = bundle_getActivator(bundle);
--
--	        status = CELIX_DO_IF(status, bundle_getContext(bundle, &context));
--	        if (status == CELIX_SUCCESS) {
++    if (status == CELIX_SUCCESS) {
++        if (wasActive || (id == 0)) {
++            activator = bundle_getActivator(bundle);
++            
++            status = CELIX_DO_IF(status, bundle_getContext(bundle, &context));
++            if (status == CELIX_SUCCESS) {
                  if (activator->stop != NULL) {
                      status = CELIX_DO_IF(status, activator->stop(activator->userData, context));
                  } else if (activator->dmInit != NULL) {
@@@ -1012,7 -1009,7 +1009,7 @@@
                      dm_dependency_manager_t *mng = celix_bundleContext_getDependencyManager(context);
                      dependencyManager_removeAllComponents(mng);
                  }
--	        }
++            }
              if (status == CELIX_SUCCESS) {
                  if (activator->destroy != NULL) {
                      status = CELIX_DO_IF(status, activator->destroy(activator->userData, context));
@@@ -1020,8 -1017,8 +1017,8 @@@
                      dm_dependency_manager_t *mng = celix_bundleContext_getDependencyManager(context);
                      status = CELIX_DO_IF(status, activator->dmDestroy(activator->userData, context, mng));
                  }
--	        }
--
++            }
++            
              if (id != 0) {
                  status = CELIX_DO_IF(status, serviceRegistry_clearServiceRegistrations(framework->registry, bundle));
                  if (status == CELIX_SUCCESS) {
@@@ -1031,30 -1028,30 +1028,30 @@@
                      bundle_getCurrentModule(bundle, &module);
                      module_getSymbolicName(module, &symbolicName);
                      bundle_getBundleId(bundle, &id);
--
++                    
                      serviceRegistry_clearReferencesFor(framework->registry, bundle);
                  }
                  // #TODO remove listeners for bundle
--
++                
                  if (context != NULL) {
                      status = CELIX_DO_IF(status, bundleContext_destroy(context));
                      status = CELIX_DO_IF(status, bundle_setContext(bundle, NULL));
                  }
--
++                
                  status = CELIX_DO_IF(status, framework_setBundleStateAndNotify(framework, bundle, OSGI_FRAMEWORK_BUNDLE_RESOLVED));
              }
--	    }
--
--	    if (activator != NULL) {
--	        bundle_setActivator(bundle, NULL);
--	        free(activator);
--	    }
--	}
--
--	framework_releaseBundleLock(framework, bundle);
--
--	if (status != CELIX_SUCCESS) {
--	    module_pt module = NULL;
++        }
++        
++        if (activator != NULL) {
++            bundle_setActivator(bundle, NULL);
++            free(activator);
++        }
++    }
++    
++    framework_releaseBundleLock(framework, bundle);
++    
++    if (status != CELIX_SUCCESS) {
++        module_pt module = NULL;
          const char *symbolicName = NULL;
          long id = 0;
          bundle_getCurrentModule(bundle, &module);
@@@ -1065,11 -1062,11 +1062,11 @@@
          } else {
              fw_logCode(framework->logger, OSGI_FRAMEWORK_LOG_ERROR, status, "Cannot stop bundle: %s [%ld]", symbolicName, id);
          }
-- 	} else {
++    } else {
          fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_STOPPED, bundle);
-- 	}
--
--	return status;
++    }
++    
++    return status;
  }
  
  celix_status_t fw_uninstallBundle(framework_pt framework, bundle_pt bundle) {
@@@ -1079,7 -1076,7 +1076,7 @@@
      const char * location = NULL;
      bundle_pt target = NULL;
      char *error = NULL;
--
++    
      status = CELIX_DO_IF(status, framework_acquireBundleLock(framework, bundle, OSGI_FRAMEWORK_BUNDLE_INSTALLED|OSGI_FRAMEWORK_BUNDLE_RESOLVED|OSGI_FRAMEWORK_BUNDLE_STARTING|OSGI_FRAMEWORK_BUNDLE_ACTIVE|OSGI_FRAMEWORK_BUNDLE_STOPPING));
      status = CELIX_DO_IF(status, fw_stopBundle(framework, bundle, true));
      if (status == CELIX_SUCCESS) {
@@@ -1089,58 -1086,58 +1086,58 @@@
              error = "Unable to acquire the global lock to uninstall the bundle";
          }
      }
--
++    
      status = CELIX_DO_IF(status, bundle_getArchive(bundle, &archive));
      status = CELIX_DO_IF(status, bundleArchive_getLocation(archive, &location));
      if (status == CELIX_SUCCESS) {
--
++        
          celixThreadMutex_lock(&framework->installedBundleMapLock);
--
++        
          hash_map_entry_pt entry = hashMap_getEntry(framework->installedBundleMap, location);
          char* entryLocation = hashMapEntry_getKey(entry);
--
++        
          target = (bundle_pt) hashMap_remove(framework->installedBundleMap, location);
--
++        
          free(entryLocation);
          if (target != NULL) {
              status = CELIX_DO_IF(status, bundle_setPersistentStateUninstalled(target));
              // fw_rememberUninstalledBundle(framework, target);
          }
          celixThreadMutex_unlock(&framework->installedBundleMapLock);
--
++        
      }
--
++    
      framework_releaseGlobalLock(framework);
--
++    
      if (status == CELIX_SUCCESS) {
          if (target == NULL) {
              fw_log(framework->logger, OSGI_FRAMEWORK_LOG_ERROR, "Could not remove bundle from installed map");
          }
      }
--
++    
      status = CELIX_DO_IF(status, framework_setBundleStateAndNotify(framework, bundle, OSGI_FRAMEWORK_BUNDLE_INSTALLED));
--
++    
      // TODO Unload all libraries for transition to unresolved
      bundle_revision_pt revision = NULL;
--	array_list_pt handles = NULL;
--	status = CELIX_DO_IF(status, bundleArchive_getCurrentRevision(archive, &revision));
--	status = CELIX_DO_IF(status, bundleRevision_getHandles(revision, &handles));
--	if(handles != NULL){
--		for (int i = arrayList_size(handles) - 1; i >= 0; i--) {
--			void *handle = arrayList_get(handles, i);
--			fw_closeLibrary(handle);
--		}
--	}
--
++    array_list_pt handles = NULL;
++    status = CELIX_DO_IF(status, bundleArchive_getCurrentRevision(archive, &revision));
++    status = CELIX_DO_IF(status, bundleRevision_getHandles(revision, &handles));
++    if(handles != NULL){
++        for (int i = arrayList_size(handles) - 1; i >= 0; i--) {
++            void *handle = arrayList_get(handles, i);
++            fw_closeLibrary(handle);
++        }
++    }
++    
      status = CELIX_DO_IF(status, fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_UNRESOLVED, bundle));
--
++    
      status = CELIX_DO_IF(status, framework_setBundleStateAndNotify(framework, bundle, OSGI_FRAMEWORK_BUNDLE_UNINSTALLED));
      status = CELIX_DO_IF(status, bundleArchive_setLastModified(archive, time(NULL)));
--
++    
      framework_releaseBundleLock(framework, bundle);
--
++    
      status = CELIX_DO_IF(status, fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_UNINSTALLED, bundle));
--
++    
      if (status == CELIX_SUCCESS) {
          locked = framework_acquireGlobalLock(framework);
          if (locked) {
@@@ -1152,38 -1149,38 +1149,38 @@@
                  bundleArchive_destroy(archive);
                  status = CELIX_DO_IF(status, bundle_destroy(bundle));
              }
--
++            
              status = CELIX_DO_IF(status, framework_releaseGlobalLock(framework));
          }
      }
--
--
++    
++    
      if (status != CELIX_SUCCESS) {
--//        module_pt module = NULL;
--//        char *symbolicName = NULL;
--//        long id = 0;
--//        bundle_getCurrentModule(bundle, &module);
--//        module_getSymbolicName(module, &symbolicName);
--//        bundle_getBundleId(bundle, &id);
--
++        //        module_pt module = NULL;
++        //        char *symbolicName = NULL;
++        //        long id = 0;
++        //        bundle_getCurrentModule(bundle, &module);
++        //        module_getSymbolicName(module, &symbolicName);
++        //        bundle_getBundleId(bundle, &id);
++        
          framework_logIfError(framework->logger, status, error, "Cannot uninstall bundle");
      }
--
++    
      return status;
  }
  
  celix_status_t fw_refreshBundles(framework_pt framework, bundle_pt bundles[], int size) {
      celix_status_t status = CELIX_SUCCESS;
--
++    
      bool locked = framework_acquireGlobalLock(framework);
      if (!locked) {
          framework_releaseGlobalLock(framework);
          status = CELIX_ILLEGAL_STATE;
      } else {
--		hash_map_values_pt values;
++        hash_map_values_pt values;
          bundle_pt *newTargets;
          unsigned int nrofvalues;
--		bool restart = false;
++        bool restart = false;
          hash_map_pt map = hashMap_create(NULL, NULL, NULL, NULL);
          int targetIdx = 0;
          for (targetIdx = 0; targetIdx < size; targetIdx++) {
@@@ -1194,19 -1191,19 +1191,19 @@@
          values = hashMapValues_create(map);
          hashMapValues_toArray(values, (void ***) &newTargets, &nrofvalues);
          hashMapValues_destroy(values);
--
++        
          hashMap_destroy(map, false, false);
--
++        
          if (newTargets != NULL) {
              int i = 0;
--			struct fw_refreshHelper * helpers;
++            struct fw_refreshHelper * helpers;
              for (i = 0; i < nrofvalues && !restart; i++) {
                  bundle_pt bundle = (bundle_pt) newTargets[i];
                  if (framework->bundle == bundle) {
                      restart = true;
                  }
              }
--
++            
              helpers = (struct fw_refreshHelper * )malloc(nrofvalues * sizeof(struct fw_refreshHelper));
              for (i = 0; i < nrofvalues && !restart; i++) {
                  bundle_pt bundle = (bundle_pt) newTargets[i];
@@@ -1214,74 -1211,74 +1211,74 @@@
                  helpers[i].bundle = bundle;
                  helpers[i].oldState = OSGI_FRAMEWORK_BUNDLE_INSTALLED;
              }
--
++            
              for (i = 0; i < nrofvalues; i++) {
                  struct fw_refreshHelper helper = helpers[i];
                  fw_refreshHelper_stop(&helper);
                  fw_refreshHelper_refreshOrRemove(&helper);
              }
--
++            
              for (i = 0; i < nrofvalues; i++) {
                  struct fw_refreshHelper helper = helpers[i];
                  fw_refreshHelper_restart(&helper);
              }
--
++            
              if (restart) {
                  bundle_update(framework->bundle, NULL);
              }
--			free(helpers);
--			free(newTargets);
++            free(helpers);
++            free(newTargets);
          }
--
++        
          framework_releaseGlobalLock(framework);
      }
--
++    
      framework_logIfError(framework->logger, status, NULL, "Cannot refresh bundles");
--
++    
      return status;
  }
  
  celix_status_t fw_refreshBundle(framework_pt framework, bundle_pt bundle) {
      celix_status_t status = CELIX_SUCCESS;
      bundle_state_e state;
--
++    
      status = framework_acquireBundleLock(framework, bundle, OSGI_FRAMEWORK_BUNDLE_INSTALLED | OSGI_FRAMEWORK_BUNDLE_RESOLVED);
      if (status != CELIX_SUCCESS) {
          printf("Cannot refresh bundle");
          framework_releaseBundleLock(framework, bundle);
      } else {
--    	bool fire;
--		bundle_getState(bundle, &state);
++        bool fire;
++        bundle_getState(bundle, &state);
          fire = (state != OSGI_FRAMEWORK_BUNDLE_INSTALLED);
          bundle_refresh(bundle);
--
++        
          if (fire) {
              framework_setBundleStateAndNotify(framework, bundle, OSGI_FRAMEWORK_BUNDLE_INSTALLED);
              fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_UNRESOLVED, bundle);
          }
--
++        
          framework_releaseBundleLock(framework, bundle);
      }
--
++    
      framework_logIfError(framework->logger, status, NULL, "Cannot refresh bundle");
--
++    
      return status;
  }
  
  celix_status_t fw_refreshHelper_stop(struct fw_refreshHelper * refreshHelper) {
--	bundle_state_e state;
--	bundle_getState(refreshHelper->bundle, &state);
++    bundle_state_e state;
++    bundle_getState(refreshHelper->bundle, &state);
      if (state == OSGI_FRAMEWORK_BUNDLE_ACTIVE) {
          refreshHelper->oldState = OSGI_FRAMEWORK_BUNDLE_ACTIVE;
          fw_stopBundle(refreshHelper->framework, refreshHelper->bundle, false);
      }
--
++    
      return CELIX_SUCCESS;
  }
  
  celix_status_t fw_refreshHelper_refreshOrRemove(struct fw_refreshHelper * refreshHelper) {
--	bundle_state_e state;
--	bundle_getState(refreshHelper->bundle, &state);
++    bundle_state_e state;
++    bundle_getState(refreshHelper->bundle, &state);
      if (state == OSGI_FRAMEWORK_BUNDLE_UNINSTALLED) {
          bundle_closeAndDelete(refreshHelper->bundle);
          refreshHelper->bundle = NULL;
@@@ -1300,96 -1297,96 +1297,96 @@@ celix_status_t fw_refreshHelper_restart
  
  celix_status_t fw_getDependentBundles(framework_pt framework, bundle_pt exporter, array_list_pt *list) {
      celix_status_t status = CELIX_SUCCESS;
--
++    
      if (*list != NULL || exporter == NULL || framework == NULL) {
--	return CELIX_ILLEGAL_ARGUMENT;
--    }
--
--	 array_list_pt modules;
--	 unsigned int modIdx = 0;
--	 arrayList_create(list);
--
--	 modules = bundle_getModules(exporter);
--	 for (modIdx = 0; modIdx < arrayList_size(modules); modIdx++) {
--				module_pt module = (module_pt) arrayList_get(modules, modIdx);
--				array_list_pt dependents = module_getDependents(module);
--			if(dependents!=NULL){
--					unsigned int depIdx = 0;
--					for (depIdx = 0; depIdx < arrayList_size(dependents); depIdx++) {
--							  module_pt dependent = (module_pt) arrayList_get(dependents, depIdx);
--							  arrayList_add(*list, module_getBundle(dependent));
--					}
--					arrayList_destroy(dependents);
--				}
--	 }
--
++        return CELIX_ILLEGAL_ARGUMENT;
++    }
++    
++    array_list_pt modules;
++    unsigned int modIdx = 0;
++    arrayList_create(list);
++    
++    modules = bundle_getModules(exporter);
++    for (modIdx = 0; modIdx < arrayList_size(modules); modIdx++) {
++        module_pt module = (module_pt) arrayList_get(modules, modIdx);
++        array_list_pt dependents = module_getDependents(module);
++        if(dependents!=NULL){
++            unsigned int depIdx = 0;
++            for (depIdx = 0; depIdx < arrayList_size(dependents); depIdx++) {
++                module_pt dependent = (module_pt) arrayList_get(dependents, depIdx);
++                arrayList_add(*list, module_getBundle(dependent));
++            }
++            arrayList_destroy(dependents);
++        }
++    }
++    
      framework_logIfError(framework->logger, status, NULL, "Cannot get dependent bundles");
--
++    
      return status;
  }
  
  celix_status_t fw_populateDependentGraph(framework_pt framework, bundle_pt exporter, hash_map_pt *map) {
      celix_status_t status = CELIX_SUCCESS;
--
++    
      if(framework == NULL || exporter == NULL){
--	return CELIX_ILLEGAL_ARGUMENT;
++        return CELIX_ILLEGAL_ARGUMENT;
      }
--
++    
      array_list_pt dependents = NULL;
      if ((status = fw_getDependentBundles(framework, exporter, &dependents)) == CELIX_SUCCESS) {
--		  if(dependents!=NULL){
--         unsigned int depIdx = 0;
--		for (depIdx = 0; depIdx < arrayList_size(dependents); depIdx++) {
--		    if (!hashMap_containsKey(*map, arrayList_get(dependents, depIdx))) {
--		        hashMap_put(*map, arrayList_get(dependents, depIdx), arrayList_get(dependents, depIdx));
--		        fw_populateDependentGraph(framework, (bundle_pt) arrayList_get(dependents, depIdx), map);
--		    }
--		}
--		arrayList_destroy(dependents);
--		  }
++        if(dependents!=NULL){
++            unsigned int depIdx = 0;
++            for (depIdx = 0; depIdx < arrayList_size(dependents); depIdx++) {
++                if (!hashMap_containsKey(*map, arrayList_get(dependents, depIdx))) {
++                    hashMap_put(*map, arrayList_get(dependents, depIdx), arrayList_get(dependents, depIdx));
++                    fw_populateDependentGraph(framework, (bundle_pt) arrayList_get(dependents, depIdx), map);
++                }
++            }
++            arrayList_destroy(dependents);
++        }
      }
--
++    
      framework_logIfError(framework->logger, status, NULL, "Cannot populate dependent graph");
--
++    
      return status;
  }
  
  celix_status_t fw_registerService(framework_pt framework, service_registration_pt *registration, bundle_pt bundle, const char* serviceName, const void* svcObj, properties_pt properties) {
--	celix_status_t status = CELIX_SUCCESS;
--	char *error = NULL;
--	if (serviceName == NULL || svcObj == NULL) {
--	    status = CELIX_ILLEGAL_ARGUMENT;
--	    error = "ServiceName and SvcObj cannot be null";
--	}
--
--	status = CELIX_DO_IF(status, framework_acquireBundleLock(framework, bundle, OSGI_FRAMEWORK_BUNDLE_STARTING|OSGI_FRAMEWORK_BUNDLE_ACTIVE));
--	status = CELIX_DO_IF(status, serviceRegistry_registerService(framework->registry, bundle, serviceName, svcObj, properties, registration));
--	bool res = framework_releaseBundleLock(framework, bundle);
--	if (!res) {
--	    status = CELIX_ILLEGAL_STATE;
--	    error = "Could not release bundle lock";
--	}
--
--	if (status == CELIX_SUCCESS) {
--	    // If this is a listener hook, invoke the callback with all current listeners
++    celix_status_t status = CELIX_SUCCESS;
++    char *error = NULL;
++    if (serviceName == NULL || svcObj == NULL) {
++        status = CELIX_ILLEGAL_ARGUMENT;
++        error = "ServiceName and SvcObj cannot be null";
++    }
++    
++    status = CELIX_DO_IF(status, framework_acquireBundleLock(framework, bundle, OSGI_FRAMEWORK_BUNDLE_STARTING|OSGI_FRAMEWORK_BUNDLE_ACTIVE));
++    status = CELIX_DO_IF(status, serviceRegistry_registerService(framework->registry, bundle, serviceName, svcObj, properties, registration));
++    bool res = framework_releaseBundleLock(framework, bundle);
++    if (!res) {
++        status = CELIX_ILLEGAL_STATE;
++        error = "Could not release bundle lock";
++    }
++    
++    if (status == CELIX_SUCCESS) {
++        // If this is a listener hook, invoke the callback with all current listeners
          if (strcmp(serviceName, OSGI_FRAMEWORK_LISTENER_HOOK_SERVICE_NAME) == 0) {
              unsigned int i;
              array_list_pt infos = NULL;
              service_reference_pt ref = NULL;
              listener_hook_service_pt hook = NULL;
--
++            
              status = CELIX_DO_IF(status, arrayList_create(&infos));
--
++            
              if (status == CELIX_SUCCESS) {
                  celix_status_t subs = CELIX_SUCCESS;
--
++                
                  celixThreadMutex_lock(&framework->serviceListenersLock);
                  for (i = 0; i < arrayList_size(framework->serviceListeners); i++) {
                      fw_service_listener_pt listener =(fw_service_listener_pt) arrayList_get(framework->serviceListeners, i);
                      bundle_context_t *context = NULL;
                      listener_hook_info_pt info = NULL;
                      bundle_context_pt lContext = NULL;
--
++                    
                      subs = CELIX_DO_IF(subs, bundle_getContext(bundle, &context));
                      if (subs == CELIX_SUCCESS) {
                          info = (listener_hook_info_pt) malloc(sizeof(*info));
@@@ -1397,14 -1394,14 +1394,14 @@@
                              subs = CELIX_ENOMEM;
                          }
                      }
--
++                    
                      subs = CELIX_DO_IF(subs, bundle_getContext(listener->bundle, &lContext));
                      if (subs == CELIX_SUCCESS) {
                          info->context = lContext;
                          info->removed = false;
                      }
                      subs = CELIX_DO_IF(subs, filter_getString(listener->filter, &info->filter));
--
++                    
                      if (subs == CELIX_SUCCESS) {
                          arrayList_add(infos, info);
                      }
@@@ -1414,7 -1411,7 +1411,7 @@@
                      }
                  }
                  celixThreadMutex_unlock(&framework->serviceListenersLock);
--
++                
                  status = CELIX_DO_IF(status, serviceRegistry_getServiceReference(framework->registry, framework->bundle,
                                                                                   *registration, &ref));
                  status = CELIX_DO_IF(status, fw_getService(framework,framework->bundle, ref, (const void **) &hook));
@@@ -1423,59 -1420,59 +1420,59 @@@
                  }
                  status = CELIX_DO_IF(status, serviceRegistry_ungetService(framework->registry, framework->bundle, ref, NULL));
                  status = CELIX_DO_IF(status, serviceRegistry_ungetServiceReference(framework->registry, framework->bundle, ref));
--
++                
                  int i = 0;
                  for (i = 0; i < arrayList_size(infos); i++) {
                      listener_hook_info_pt info = arrayList_get(infos, i);
                      free(info);
                  }
                  arrayList_destroy(infos);
--             }
++            }
          }
--	}
--
++    }
++    
      framework_logIfError(framework->logger, status, error, "Cannot register service: %s", serviceName);
--
--	return status;
++    
++    return status;
  }
  
  celix_status_t fw_registerServiceFactory(framework_pt framework, service_registration_pt *registration, bundle_pt bundle, const char* serviceName, service_factory_pt factory, properties_pt properties) {
      celix_status_t status = CELIX_SUCCESS;
      char *error = NULL;
--	if (serviceName == NULL || factory == NULL) {
++    if (serviceName == NULL || factory == NULL) {
          status = CELIX_ILLEGAL_ARGUMENT;
          error = "Service name and factory cannot be null";
      }
--
--	status = CELIX_DO_IF(status, framework_acquireBundleLock(framework, bundle, OSGI_FRAMEWORK_BUNDLE_STARTING|OSGI_FRAMEWORK_BUNDLE_ACTIVE));
--	status = CELIX_DO_IF(status, serviceRegistry_registerServiceFactory(framework->registry, bundle, serviceName, factory, properties, registration));
++    
++    status = CELIX_DO_IF(status, framework_acquireBundleLock(framework, bundle, OSGI_FRAMEWORK_BUNDLE_STARTING|OSGI_FRAMEWORK_BUNDLE_ACTIVE));
++    status = CELIX_DO_IF(status, serviceRegistry_registerServiceFactory(framework->registry, bundle, serviceName, factory, properties, registration));
      if (!framework_releaseBundleLock(framework, bundle)) {
          status = CELIX_ILLEGAL_STATE;
          error = "Could not release bundle lock";
      }
--
++    
      framework_logIfError(framework->logger, status, error, "Cannot register service factory: %s", serviceName);
--
++    
      return CELIX_SUCCESS;
  }
  
  celix_status_t fw_getServiceReferences(framework_pt framework, array_list_pt *references, bundle_pt bundle, const char * serviceName, const char * sfilter) {
      celix_status_t status = CELIX_SUCCESS;
--
--	filter_pt filter = NULL;
--	unsigned int refIdx = 0;
--
++    
++    filter_pt filter = NULL;
++    unsigned int refIdx = 0;
++    
      if (sfilter != NULL) {
          filter = filter_create(sfilter);
--	}
--
--	status = CELIX_DO_IF(status, serviceRegistry_getServiceReferences(framework->registry, bundle, serviceName, filter, references));
--
--	if (filter != NULL) {
--		filter_destroy(filter);
--	}
--
--	if (status == CELIX_SUCCESS) {
++    }
++    
++    status = CELIX_DO_IF(status, serviceRegistry_getServiceReferences(framework->registry, bundle, serviceName, filter, references));
++    
++    if (filter != NULL) {
++        filter_destroy(filter);
++    }
++    
++    if (status == CELIX_SUCCESS) {
          for (refIdx = 0; (*references != NULL) && refIdx < arrayList_size(*references); refIdx++) {
              service_reference_pt ref = (service_reference_pt) arrayList_get(*references, refIdx);
              service_registration_pt reg = NULL;
@@@ -1491,11 -1488,11 +1488,11 @@@
                  }
              }
          }
--	}
--
--	framework_logIfError(framework->logger, status, NULL, "Failed to get service references");
--
--	return status;
++    }
++    
++    framework_logIfError(framework->logger, status, NULL, "Failed to get service references");
++    
++    return status;
  }
  
  celix_status_t framework_ungetServiceReference(framework_pt framework, bundle_pt bundle, service_reference_pt reference) {
@@@ -1503,78 -1500,78 +1500,78 @@@
  }
  
  celix_status_t fw_getService(framework_pt framework, bundle_pt bundle, service_reference_pt reference, const void **service) {
--	return serviceRegistry_getService(framework->registry, bundle, reference, service);
++    return serviceRegistry_getService(framework->registry, bundle, reference, service);
  }
  
  celix_status_t fw_getBundleRegisteredServices(framework_pt framework, bundle_pt bundle, array_list_pt *services) {
--	return serviceRegistry_getRegisteredServices(framework->registry, bundle, services);
++    return serviceRegistry_getRegisteredServices(framework->registry, bundle, services);
  }
  
  celix_status_t fw_getBundleServicesInUse(framework_pt framework, bundle_pt bundle, array_list_pt *services) {
--	celix_status_t status = CELIX_SUCCESS;
--	status = serviceRegistry_getServicesInUse(framework->registry, bundle, services);
--	return status;
++    celix_status_t status = CELIX_SUCCESS;
++    status = serviceRegistry_getServicesInUse(framework->registry, bundle, services);
++    return status;
  }
  
  celix_status_t framework_ungetService(framework_pt framework, bundle_pt bundle, service_reference_pt reference, bool *result) {
--	return serviceRegistry_ungetService(framework->registry, bundle, reference, result);
++    return serviceRegistry_ungetService(framework->registry, bundle, reference, result);
  }
  
  void fw_addServiceListener(framework_pt framework, bundle_pt bundle, service_listener_pt listener, const char* sfilter) {
--	array_list_pt listenerHooks = NULL;
--	unsigned int i;
--
--	fw_service_listener_pt fwListener = (fw_service_listener_pt) calloc(1, sizeof(*fwListener));
--	bundle_context_t *context = NULL;
--
--	fwListener->bundle = bundle;
++    array_list_pt listenerHooks = NULL;
++    unsigned int i;
++    
++    fw_service_listener_pt fwListener = (fw_service_listener_pt) calloc(1, sizeof(*fwListener));
++    bundle_context_t *context = NULL;
++    
++    fwListener->bundle = bundle;
      arrayList_create(&fwListener->retainedReferences);
--	if (sfilter != NULL) {
--		filter_pt filter = filter_create(sfilter);
--		fwListener->filter = filter;
--	} else {
--		fwListener->filter = NULL;
--	}
--	fwListener->listener = listener;
--
++    if (sfilter != NULL) {
++        filter_pt filter = filter_create(sfilter);
++        fwListener->filter = filter;
++    } else {
++        fwListener->filter = NULL;
++    }
++    fwListener->listener = listener;
++    
      celixThreadMutex_lock(&framework->serviceListenersLock);
--	arrayList_add(framework->serviceListeners, fwListener);
++    arrayList_add(framework->serviceListeners, fwListener);
      celixThreadMutex_unlock(&framework->serviceListenersLock);
--
--	serviceRegistry_getListenerHooks(framework->registry, framework->bundle, &listenerHooks);
--
++    
++    serviceRegistry_getListenerHooks(framework->registry, framework->bundle, &listenerHooks);
++    
      struct listener_hook_info info;
--
--	bundle_getContext(bundle, &context);
--	info.context = context;
--	info.removed = false;
--	info.filter = sfilter;
--
--	for (i = 0; i < arrayList_size(listenerHooks); i++) {
--		service_reference_pt ref = (service_reference_pt) arrayList_get(listenerHooks, i);
--		listener_hook_service_pt hook = NULL;
--		array_list_pt infos = NULL;
--		bool ungetResult = false;
--
--		fw_getService(framework, framework->bundle, ref, (const void **) &hook);
--
--		arrayList_create(&infos);
--		arrayList_add(infos, &info);
--		hook->added(hook->handle, infos);
--		serviceRegistry_ungetService(framework->registry, framework->bundle, ref, &ungetResult);
--		serviceRegistry_ungetServiceReference(framework->registry, framework->bundle, ref);
--		arrayList_destroy(infos);
--	}
--
--	arrayList_destroy(listenerHooks);
++    
++    bundle_getContext(bundle, &context);
++    info.context = context;
++    info.removed = false;
++    info.filter = sfilter;
++    
++    for (i = 0; i < arrayList_size(listenerHooks); i++) {
++        service_reference_pt ref = (service_reference_pt) arrayList_get(listenerHooks, i);
++        listener_hook_service_pt hook = NULL;
++        array_list_pt infos = NULL;
++        bool ungetResult = false;
++        
++        fw_getService(framework, framework->bundle, ref, (const void **) &hook);
++        
++        arrayList_create(&infos);
++        arrayList_add(infos, &info);
++        hook->added(hook->handle, infos);
++        serviceRegistry_ungetService(framework->registry, framework->bundle, ref, &ungetResult);
++        serviceRegistry_ungetServiceReference(framework->registry, framework->bundle, ref);
++        arrayList_destroy(infos);
++    }
++    
++    arrayList_destroy(listenerHooks);
  }
  
  void fw_removeServiceListener(framework_pt framework, bundle_pt bundle, service_listener_pt listener) {
--	fw_service_listener_pt match = NULL;
--
--	bundle_context_t *context;
--	bundle_getContext(bundle, &context);
--
++    fw_service_listener_pt match = NULL;
++    
++    bundle_context_t *context;
++    bundle_getContext(bundle, &context);
++    
      int i;
      celixThreadMutex_lock(&framework->serviceListenersLock);
      for (i = 0; i < arrayList_size(framework->serviceListeners); i++) {
@@@ -1586,19 -1583,19 +1583,19 @@@
          }
      }
      celixThreadMutex_unlock(&framework->serviceListenersLock);
--
--
++    
++    
      if (match != NULL) {
          //invoke listener hooks
--
++        
          bundle_context_pt lContext = NULL;
--
++        
          struct listener_hook_info info;
          bundle_getContext(match->bundle, &lContext);
          info.context = lContext;
          filter_getString(match->filter, &info.filter);
          info.removed = true;
--
++        
          array_list_pt listenerHooks = NULL;
          serviceRegistry_getListenerHooks(framework->registry, framework->bundle, &listenerHooks);
          for (i = 0; i < arrayList_size(listenerHooks); i++) {
@@@ -1606,9 -1603,9 +1603,9 @@@
              listener_hook_service_pt hook = NULL;
              array_list_pt infos = NULL;
              bool ungetResult;
--
++            
              fw_getService(framework, framework->bundle, ref, (const void **) &hook);
--
++            
              arrayList_create(&infos);
              arrayList_add(infos, &info);
              hook->removed(hook->handle, infos);
@@@ -1618,7 -1615,7 +1615,7 @@@
          }
          arrayList_destroy(listenerHooks);
      }
--
++    
      if (match != NULL) {
          //unregistering retained service references. For these refs a unregister event will not be triggered.
          int rSize = arrayList_size(match->retainedReferences);
@@@ -1628,129 -1625,129 +1625,129 @@@
                  serviceRegistry_ungetServiceReference(framework->registry, match->bundle, ref); // decrease retain counter
              }
          }
--
++        
          match->bundle = NULL;
          filter_destroy(match->filter);
          arrayList_destroy(match->retainedReferences);
          match->filter = NULL;
          match->listener = NULL;
          free(match);
--	}
++    }
  }
  
  celix_status_t fw_addBundleListener(framework_pt framework, bundle_pt bundle, bundle_listener_pt listener) {
--	celix_status_t status = CELIX_SUCCESS;
--	fw_bundle_listener_pt bundleListener = NULL;
--
--	bundleListener = (fw_bundle_listener_pt) malloc(sizeof(*bundleListener));
--	if (!bundleListener) {
--		status = CELIX_ENOMEM;
--	} else {
--		bundleListener->listener = listener;
--		bundleListener->bundle = bundle;
--
--		if (celixThreadMutex_lock(&framework->bundleListenerLock) != CELIX_SUCCESS) {
--			status = CELIX_FRAMEWORK_EXCEPTION;
--		} else {
--			arrayList_add(framework->bundleListeners, bundleListener);
--
--			if (celixThreadMutex_unlock(&framework->bundleListenerLock)) {
--				status = CELIX_FRAMEWORK_EXCEPTION;
--			}
--		}
--	}
--
--	framework_logIfError(framework->logger, status, NULL, "Failed to add bundle listener");
--
--	return status;
++    celix_status_t status = CELIX_SUCCESS;
++    fw_bundle_listener_pt bundleListener = NULL;
++    
++    bundleListener = (fw_bundle_listener_pt) malloc(sizeof(*bundleListener));
++    if (!bundleListener) {
++        status = CELIX_ENOMEM;
++    } else {
++        bundleListener->listener = listener;
++        bundleListener->bundle = bundle;
++        
++        if (celixThreadMutex_lock(&framework->bundleListenerLock) != CELIX_SUCCESS) {
++            status = CELIX_FRAMEWORK_EXCEPTION;
++        } else {
++            arrayList_add(framework->bundleListeners, bundleListener);
++            
++            if (celixThreadMutex_unlock(&framework->bundleListenerLock)) {
++                status = CELIX_FRAMEWORK_EXCEPTION;
++            }
++        }
++    }
++    
++    framework_logIfError(framework->logger, status, NULL, "Failed to add bundle listener");
++    
++    return status;
  }
  
  celix_status_t fw_removeBundleListener(framework_pt framework, bundle_pt bundle, bundle_listener_pt listener) {
--	celix_status_t status = CELIX_SUCCESS;
--
--	unsigned int i;
--	fw_bundle_listener_pt bundleListener;
--
--	if (celixThreadMutex_lock(&framework->bundleListenerLock) != CELIX_SUCCESS) {
--		status = CELIX_FRAMEWORK_EXCEPTION;
--	}
--	else {
--		for (i = 0; i < arrayList_size(framework->bundleListeners); i++) {
--			bundleListener = (fw_bundle_listener_pt) arrayList_get(framework->bundleListeners, i);
--			if (bundleListener->listener == listener && bundleListener->bundle == bundle) {
--				arrayList_remove(framework->bundleListeners, i);
--
--				bundleListener->bundle = NULL;
--				bundleListener->listener = NULL;
--				free(bundleListener);
--			}
--		}
--		if (celixThreadMutex_unlock(&framework->bundleListenerLock)) {
--			status = CELIX_FRAMEWORK_EXCEPTION;
--		}
--	}
--
--	framework_logIfError(framework->logger, status, NULL, "Failed to remove bundle listener");
--
--	return status;
++    celix_status_t status = CELIX_SUCCESS;
++    
++    unsigned int i;
++    fw_bundle_listener_pt bundleListener;
++    
++    if (celixThreadMutex_lock(&framework->bundleListenerLock) != CELIX_SUCCESS) {
++        status = CELIX_FRAMEWORK_EXCEPTION;
++    }
++    else {
++        for (i = 0; i < arrayList_size(framework->bundleListeners); i++) {
++            bundleListener = (fw_bundle_listener_pt) arrayList_get(framework->bundleListeners, i);
++            if (bundleListener->listener == listener && bundleListener->bundle == bundle) {
++                arrayList_remove(framework->bundleListeners, i);
++                
++                bundleListener->bundle = NULL;
++                bundleListener->listener = NULL;
++                free(bundleListener);
++            }
++        }
++        if (celixThreadMutex_unlock(&framework->bundleListenerLock)) {
++            status = CELIX_FRAMEWORK_EXCEPTION;
++        }
++    }
++    
++    framework_logIfError(framework->logger, status, NULL, "Failed to remove bundle listener");
++    
++    return status;
  }
  
  celix_status_t fw_addFrameworkListener(framework_pt framework, bundle_pt bundle, framework_listener_pt listener) {
--	celix_status_t status = CELIX_SUCCESS;
--	fw_framework_listener_pt frameworkListener = NULL;
--
--	frameworkListener = (fw_framework_listener_pt) malloc(sizeof(*frameworkListener));
--	if (!frameworkListener) {
--		status = CELIX_ENOMEM;
--	} else {
--		frameworkListener->listener = listener;
--		frameworkListener->bundle = bundle;
--
++    celix_status_t status = CELIX_SUCCESS;
++    fw_framework_listener_pt frameworkListener = NULL;
++    
++    frameworkListener = (fw_framework_listener_pt) malloc(sizeof(*frameworkListener));
++    if (!frameworkListener) {
++        status = CELIX_ENOMEM;
++    } else {
++        frameworkListener->listener = listener;
++        frameworkListener->bundle = bundle;
++        
          celixThreadMutex_lock(&framework->frameworkListenersLock);
--		arrayList_add(framework->frameworkListeners, frameworkListener);
++        arrayList_add(framework->frameworkListeners, frameworkListener);
          celixThreadMutex_unlock(&framework->frameworkListenersLock);
--	}
--
--	framework_logIfError(framework->logger, status, NULL, "Failed to add framework listener");
--
--	return status;
++    }
++    
++    framework_logIfError(framework->logger, status, NULL, "Failed to add framework listener");
++    
++    return status;
  }
  
  celix_status_t fw_removeFrameworkListener(framework_pt framework, bundle_pt bundle, framework_listener_pt listener) {
--	celix_status_t status = CELIX_SUCCESS;
--
--	unsigned int i;
--	fw_framework_listener_pt frameworkListener;
--
++    celix_status_t status = CELIX_SUCCESS;
++    
++    unsigned int i;
++    fw_framework_listener_pt frameworkListener;
++    
      celixThreadMutex_lock(&framework->frameworkListenersLock);
--	for (i = 0; i < arrayList_size(framework->frameworkListeners); i++) {
--		frameworkListener = (fw_framework_listener_pt) arrayList_get(framework->frameworkListeners, i);
--		if (frameworkListener->listener == listener && frameworkListener->bundle == bundle) {
--			arrayList_remove(framework->frameworkListeners, i);
--
--			frameworkListener->bundle = NULL;
++    for (i = 0; i < arrayList_size(framework->frameworkListeners); i++) {
++        frameworkListener = (fw_framework_listener_pt) arrayList_get(framework->frameworkListeners, i);
++        if (frameworkListener->listener == listener && frameworkListener->bundle == bundle) {
++            arrayList_remove(framework->frameworkListeners, i);
++            
++            frameworkListener->bundle = NULL;
              frameworkListener->listener = NULL;
              free(frameworkListener);
--		}
--	}
++        }
++    }
      celixThreadMutex_unlock(&framework->frameworkListenersLock);
--
--	framework_logIfError(framework->logger, status, NULL, "Failed to remove framework listener");
--
--	return status;
++    
++    framework_logIfError(framework->logger, status, NULL, "Failed to remove framework listener");
++    
++    return status;
  }
  
  void fw_serviceChanged(framework_pt framework, service_event_type_e eventType, service_registration_pt registration, properties_pt oldprops) {
      unsigned int i;
      fw_service_listener_pt element;
--
++    
      celixThreadMutex_lock(&framework->serviceListenersLock);
      if (arrayList_size(framework->serviceListeners) > 0) {
          for (i = 0; i < arrayList_size(framework->serviceListeners); i++) {
              int matched = 0;
              properties_pt props = NULL;
              bool matchResult = false;
--
++            
              element = (fw_service_listener_pt) arrayList_get(framework->serviceListeners, i);
              serviceRegistration_getProperties(registration, &props);
              if (element->filter != NULL) {
@@@ -1760,34 -1757,34 +1757,34 @@@
              if (matched) {
                  service_reference_pt reference = NULL;
                  service_event_pt event;
--
++                
                  event = (service_event_pt) malloc(sizeof (*event));
--
++                
                  serviceRegistry_getServiceReference(framework->registry, element->bundle, registration, &reference);
--
++                
                  //NOTE: that you are never sure that the UNREGISTERED event will by handle by an service_listener. listener could be gone
                  //Every reference retained is therefore stored and called when a service listener is removed from the framework.
                  if (eventType == OSGI_FRAMEWORK_SERVICE_EVENT_REGISTERED) {
                      serviceRegistry_retainServiceReference(framework->registry, element->bundle, reference);
                      arrayList_add(element->retainedReferences, reference); //TODO improve by using set (or hashmap) instead of list
                  }
--
++                
                  event->type = eventType;
                  event->reference = reference;
--
++                
                  element->listener->serviceChanged(element->listener, event);
--
++                
                  serviceRegistry_ungetServiceReference(framework->registry, element->bundle, reference);
--
++                
                  if (eventType == OSGI_FRAMEWORK_SERVICE_EVENT_UNREGISTERING) {
                      //if service listener was active when service was registered, release the retained reference
                      if (arrayList_removeElement(element->retainedReferences, reference)) {
                          serviceRegistry_ungetServiceReference(framework->registry, element->bundle, reference); // decrease retain counter
                      }
                  }
--
++                
                  free(event);
--
++                
              } else if (eventType == OSGI_FRAMEWORK_SERVICE_EVENT_MODIFIED) {
                  bool matchResult = false;
                  int matched = 0;
@@@ -1798,22 -1795,22 +1795,22 @@@
                  if (matched) {
                      service_reference_pt reference = NULL;
                      service_event_pt endmatch = (service_event_pt) malloc(sizeof (*endmatch));
--
++                    
                      serviceRegistry_getServiceReference(framework->registry, element->bundle, registration, &reference);
--
++                    
                      endmatch->reference = reference;
                      endmatch->type = OSGI_FRAMEWORK_SERVICE_EVENT_MODIFIED_ENDMATCH;
                      element->listener->serviceChanged(element->listener, endmatch);
--
++                    
                      serviceRegistry_ungetServiceReference(framework->registry, element->bundle, reference);
                      free(endmatch);
--
++                    
                  }
              }
          }
      }
      celixThreadMutex_unlock(&framework->serviceListenersLock);
--
++    
  }
  
  //celix_status_t fw_isServiceAssignable(framework_pt fw, bundle_pt requester, service_reference_pt reference, bool *assignable) {
@@@ -1833,110 -1830,110 +1830,110 @@@
  //}
  
  long framework_getNextBundleId(framework_pt framework) {
--	long id = framework->nextBundleId;
--	framework->nextBundleId++;
--	return id;
++    long id = framework->nextBundleId;
++    framework->nextBundleId++;
++    return id;
  }
  
  celix_status_t framework_markResolvedModules(framework_pt framework, linked_list_pt resolvedModuleWireMap) {
--	if (resolvedModuleWireMap != NULL) {
--		// hash_map_iterator_pt iterator = hashMapIterator_create(resolvedModuleWireMap);
--		linked_list_iterator_pt iterator = linkedListIterator_create(resolvedModuleWireMap, linkedList_size(resolvedModuleWireMap));
--		while (linkedListIterator_hasPrevious(iterator)) {
--		    importer_wires_pt iw = linkedListIterator_previous(iterator);
--			// hash_map_entry_pt entry = hashMapIterator_nextEntry(iterator);
--			module_pt module = iw->importer;
--
--//			bundle_pt bundle = module_getBundle(module);
--//			bundle_archive_pt archive = NULL;
--//			bundle_getArchive(bundle, &archive);
--//			bundle_revision_pt revision = NULL;
--//			bundleArchive_getCurrentRevision(archive, &revision);
--//			char *root = NULL;
--//			bundleRevision_getRoot(revision, &root);
--//			manifest_pt manifest = NULL;
--//			bundleRevision_getManifest(revision, &manifest);
--//
--//			char *private = manifest_getValue(manifest, OSGI_FRAMEWORK_PRIVATE_LIBRARY);
--//			char *export = manifest_getValue(manifest, OSGI_FRAMEWORK_EXPORT_LIBRARY);
--//
--//			printf("Root %s\n", root);
--
--			// for each library update the reference to the wires, if there are any
--
--			linked_list_pt wires = iw->wires;
--
--//			linked_list_iterator_pt wit = linkedListIterator_create(wires, 0);
--//			while (linkedListIterator_hasNext(wit)) {
--//			    wire_pt wire = linkedListIterator_next(wit);
--//			    module_pt importer = NULL;
--//			    requirement_pt requirement = NULL;
--//			    module_pt exporter = NULL;
--//                capability_pt capability = NULL;
--//			    wire_getImporter(wire, &importer);
--//			    wire_getRequirement(wire, &requirement);
--//
--//			    wire_getExporter(wire, &exporter);
--//			    wire_getCapability(wire, &capability);
--//
--//			    char *importerName = NULL;
--//			    module_getSymbolicName(importer, &importerName);
--//
--//			    char *exporterName = NULL;
--//                module_getSymbolicName(exporter, &exporterName);
--//
--//                version_pt version = NULL;
--//                char *name = NULL;
--//                capability_getServiceName(capability, &name);
--//                capability_getVersion(capability, &version);
--//                char *versionString = NULL;
--//                version_toString(version, framework->mp, &versionString);
--//
--//                printf("Module %s imports library %s:%s from %s\n", importerName, name, versionString, exporterName);
--//			}
--
--			module_setWires(module, wires);
--
--			module_setResolved(module);
--			resolver_moduleResolved(module);
--
--			const char *mname = NULL;
--			module_getSymbolicName(module, &mname);
--			framework_markBundleResolved(framework, module);
--			linkedListIterator_remove(iterator);
--			free(iw);
--		}
--		linkedListIterator_destroy(iterator);
--		linkedList_destroy(resolvedModuleWireMap);
--	}
--	return CELIX_SUCCESS;
++    if (resolvedModuleWireMap != NULL) {
++        // hash_map_iterator_pt iterator = hashMapIterator_create(resolvedModuleWireMap);
++        linked_lis

<TRUNCATED>
http://git-wip-us.apache.org/repos/asf/celix/blob/8464f3d5/framework/src/framework_private.h
----------------------------------------------------------------------


[10/12] celix git commit: CELIX-446: Moves updated API to celix_ headers (e.g. celix_bundle_context.h)

Posted by pn...@apache.org.
CELIX-446: Moves updated API to celix_ headers (e.g. celix_bundle_context.h)


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

Branch: refs/heads/feature/CELIX-426-cxx-api
Commit: 03df0edc9ccb53eb4c006ae71b84acf8330e5376
Parents: 3391d88
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Sun May 13 21:12:55 2018 +0200
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Sun May 13 21:12:55 2018 +0200

----------------------------------------------------------------------
 framework/include/bundle.h                     |  13 -
 framework/include/bundle_activator.h           |   1 +
 framework/include/bundle_context.h             | 553 ----------------
 framework/include/celix/dm/DependencyManager.h |   7 +-
 framework/include/celix_api.h                  |  13 +
 framework/include/celix_bundle.h               |  46 ++
 framework/include/celix_bundle_context.h       | 691 ++++++++++++++++++++
 framework/include/celix_service_factory.h      |   7 +-
 framework/include/service_tracker.h            |   1 +
 framework/private/mock/bundle_context_mock.c   |   3 +-
 framework/src/bundle.c                         |   8 +-
 framework/src/bundle_context.c                 |  10 +-
 framework/src/bundle_context_private.h         |   3 +-
 framework/src/bundle_private.h                 |   9 +-
 framework/src/framework.c                      |   1 +
 framework/src/service_tracker.c                |   3 +-
 framework/tst/bundle_context_bundles_tests.cpp |   4 +-
 framework/tst/bundle_context_services_test.cpp |   4 +-
 shell/src/dm_shell_list_command.c              |   2 +-
 utils/include/array_list.h                     |  52 --
 utils/include/celix_array_list.h               |  84 +++
 utils/include/celix_properties.h               |  78 +++
 utils/include/properties.h                     |  40 --
 utils/src/array_list.c                         |   1 +
 utils/src/properties.c                         |   1 +
 25 files changed, 943 insertions(+), 692 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/03df0edc/framework/include/bundle.h
----------------------------------------------------------------------
diff --git a/framework/include/bundle.h b/framework/include/bundle.h
index 9cccd0c..b105615 100644
--- a/framework/include/bundle.h
+++ b/framework/include/bundle.h
@@ -133,19 +133,6 @@ FRAMEWORK_EXPORT celix_status_t bundle_getFramework(bundle_pt bundle, framework_
 FRAMEWORK_EXPORT celix_status_t bundle_getBundleLocation(bundle_pt bundle, const char **location);
 
 
-
-/**********************************************************************************************************************
- **********************************************************************************************************************
- * Updated API
- **********************************************************************************************************************
- **********************************************************************************************************************/
-
-long celix_bundle_getId(const bundle_t *bnd);
-
-celix_bundle_state_e celix_bundle_getState(const bundle_t *bnd);
-
-
-
 #ifdef __cplusplus
 }
 #endif

http://git-wip-us.apache.org/repos/asf/celix/blob/03df0edc/framework/include/bundle_activator.h
----------------------------------------------------------------------
diff --git a/framework/include/bundle_activator.h b/framework/include/bundle_activator.h
index a03fbb1..8c91957 100644
--- a/framework/include/bundle_activator.h
+++ b/framework/include/bundle_activator.h
@@ -38,6 +38,7 @@
 #define BUNDLE_ACTIVATOR_H_
 
 #include "bundle_context.h"
+#include "celix_bundle_context.h"
 #include "framework_exports.h"
 
 #ifdef __cplusplus

http://git-wip-us.apache.org/repos/asf/celix/blob/03df0edc/framework/include/bundle_context.h
----------------------------------------------------------------------
diff --git a/framework/include/bundle_context.h b/framework/include/bundle_context.h
index 93840b7..cf42314 100644
--- a/framework/include/bundle_context.h
+++ b/framework/include/bundle_context.h
@@ -164,559 +164,6 @@ FRAMEWORK_EXPORT celix_status_t
 bundleContext_getPropertyWithDefault(bundle_context_pt context, const char *name, const char *defaultValue, const char **value);
 
 
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-/**********************************************************************************************************************
- **********************************************************************************************************************
- * Updated API
- **********************************************************************************************************************
- **********************************************************************************************************************/
-
-/**
- * Gets the dependency manager for this bundle context.
- *
- * @return the dependency manager or NULL if unsuccessful.
- */
-dm_dependency_manager_t* celix_bundleContext_getDependencyManager(celix_bundle_context_t *ctx);
-
-
-typedef struct celix_service_registration_options {
-    /**
-     * The service pointer. The actual pointer to the service. For C this is normally a pointer to a struct
-     * with function pointers, but theoretically this can be a pointer to anything (e.g. a pointer to a single function,
-     * or a pointer to a C++ interface implementation, or just a pointer to a data structure).
-     *
-     * The bundle is responsible to keep the service pointer valid as long as it is registered in the Celix framework.
-     */
-    void *svc;
-
-    /**
-     * The service factory pointer.
-     * Note if the factory service is set, the svc field will not be used.
-     *
-     * The service factory will be called for every bundle requesting/de-requesting a service. This gives the provider the
-     * option to create bundle specific service instances.
-     *
-     * When a service is requested for a bundle the getService of the factory service will be called. This function must
-     * return a valid pointer to a service conform the registered service name or NULL.
-     * When a service in no longer needed for a bundle (e.g. ending the useService(s) calls when a service tacker is stopped)
-     * the ungetService function of the service factory will be called.
-     *
-     * The bundle is responsible to keep the service factory pointer valid as long as it is registered in the Celix framework.
-     */
-    celix_service_factory_t *factory;
-
-    /**
-     * The required service name. This is used to identify the service. A fully qualified name with a namespace is
-     * advisable to prevent name collision. (e.g. EXAMPLE_PRESURE_SENSOR).
-     */
-    const char *serviceName;
-
-    /**
-     * The optional service properties. These contain meta information about the service in the
-     * form of string key/values. (e.g. the location of a pressure sensor: location=left-tire).
-     *
-     * When a service is registered the Celix framework will take ownership of the provided properties.
-     * If a registration fails, the properties will be destroyed (freed) by the Celix framework.
-     */
-     celix_properties_t *properties;
-
-     /**
-      * The optional service language. If this is NULL, CELIX_FRAMEWORK_SERVICE_LANGUAGE_C is used.
-      */
-      const char *serviceLanguage;
-
-      /**
-       * The optional service version (in the form of <MAJOR>.<MINOR>.<MICRO>.<QUALIFIER>).
-       * If present consumer of the service can specific which service version range of
-       * a specific service they are interested in. Note that it is the responsibility of the users to ensure that
-       * service in those version range are compatible (binary of source). It is advisable to use semantic versioning
-       * for this.
-       */
-      const char *serviceVersion;
-} celix_service_registration_options_t;
-
-#define CELIX_EMPTY_SERVICE_REGISTRATION_OPTIONS { .svc = NULL, \
-    .serviceName = NULL, \
-    .properties = NULL, \
-    .serviceLanguage = NULL, \
-    .serviceVersion = NULL }
-
-/**
- * Register a C lang service to the framework.
- *
- * @param ctx The bundle context
- * @param svc the service object. Normally a pointer to a service struct (e.g. a struct with function pointers)
- * @param serviceName the service name, cannot be NULL
- * @param properties The meta properties associated with the service. The service registration will take ownership of the properties (e.g. no destroy needed)
- * @return The serviceId, which should be >= 0. If < 0 then the registration was unsuccessful.
- */
-long celix_bundleContext_registerService(celix_bundle_context_t *ctx, void *svc, const char *serviceName, celix_properties_t *properties);
-
-/**
- * Register a service factory in the framework (for the C language).
- * The service factory will be called for every bundle requesting/de-requesting a service. This gives the provider the
- * option to create bundle specific service instances.
- *
- * When a service is requested for a bundle the getService of the factory service will be called. This function must
- * return a valid pointer to a service conform the registered service name or NULL.
- * When a service in no longer needed for a bundle (e.g. ending the useService(s) calls when a service tacker is stopped)
- * the ungetService function of the service factory will be called.
- *
- * @param ctx The bundle context
- * @param factory The pointer to the factory service.
- * @param serviceName The required service name of the services this factory will produce.
- * @param properties The optional service factory properties. For a service consumer this will be seen as the service properties.
- * @return The service id of the service factory or < 0 if the registration was unsuccessful.
- */
-long celix_bundleContext_registerServiceFactory(celix_bundle_context_t *ctx, celix_service_factory_t *factory, const char *serviceName, celix_properties_t *props);
-
-/**
-* Register a service Celix to the framework using the provded registration options.
-*
-* @param ctx The bundle context
-* @param opts The pointer to the registration options. The options are only in the during registration call.
-* @return The serviceId, which should >= 0. If < 0 then the registration was unsuccessful.
-*/
-long celix_bundleContext_registerServiceWithOptions(celix_bundle_context_t *ctx, const celix_service_registration_options_t *opts);
-
-
-/**
- * Unregister the service or service factory with service id.
- * The service will only be unregistered if the bundle of the bundle context is the owner of the service.
- *
- * Will log an error if service id is unknown. Will silently ignore services ids < 0.
- *
- * @param ctx The bundle context
- * @param serviceId The service id
- */
-void celix_bundleContext_unregisterService(celix_bundle_context_t *ctx, long serviceId);
-
-
-typedef struct celix_service_filter_options {
-    const char* serviceName; //REQUIRED
-    const char* versionRange;
-    const char* filter;
-    const char* lang; //NULL -> 'CELIX_LANG_C'
-} celix_service_filter_options_t;
-
-#define CELIX_EMPTY_SERVICE_FILTER_OPTIONS {.serviceName = NULL, .versionRange = NULL, .filter = NULL, .lang = NULL}
-
-
-/**
- * Finds the highest ranking service and returns the service id.
- *
- * @param ctx The bundle context
- * @param serviceName The required service name
- * @return If found a valid service id (>= 0) if not found -1.
- */
-long celix_bundleContext_findService(celix_bundle_context_t *ctx, const char *serviceName);
-
-/**
- * Finds the highest ranking service and returns the service id.
- *
- * @param ctx The bundle context
- * @param opts The pointer to the filter options.
- * @return If found a valid service id (>= 0) if not found -1.
- */
-long celix_bundleContext_findServiceWithOptions(celix_bundle_context_t *ctx, const celix_service_filter_options_t *opts);
-
-/**
- * Finds the services with the provided service name and returns a list of the found service ids.
- *
- * @param ctx The bundle context
- * @param serviceName The required service name
- * @return A array list with as value a long int.
- */
-celix_array_list_t* celix_bundleContext_findServices(celix_bundle_context_t *ctx, const char *serviceName);
-
-/**
- * Finds the services conform the provider filter options and returns a list of the found service ids.
- *
- * @param ctx The bundle context
- * @param opts The pointer to the filter options.
- * @return A array list with as value a long int.
- */
-celix_array_list_t* celix_bundleContext_findServicesWithOptions(celix_bundle_context_t *ctx, const celix_service_filter_options_t *opts);
-
-
-/**
- * track service for the provided serviceName and/or filter.
- * The highest ranking services will used for the callback.
- * If a new and higher ranking services the callback with be called again with the new service.
- * If a service is removed a the callback with be called with next highest ranking service or NULL as service.
- *
- * @param ctx The bundle context.
- * @param serviceName The required service name to track
- * @param serviceVersionRange Optional the service version range to track
- * @param filter Optional the LDAP filter to use
- * @param callbackHandle The data pointer, which will be used in the callbacks
- * @param set is a required callback, which will be called when a new highest ranking service is set.
- * @return the tracker id or < 0 if unsuccessful.
- */
-long celix_bundleContext_trackService(
-        celix_bundle_context_t* ctx,
-        const char* serviceName,
-        void* callbackHandle,
-        void (*set)(void* handle, void* svc)
-);
-
-/**
- * track services for the provided serviceName and/or filter.
- *
- * @param ctx The bundle context.
- * @param serviceName The required service name to track
- * @param serviceVersionRange Optional the service version range to track
- * @param filter Optional the LDAP filter to use
- * @param callbackHandle The data pointer, which will be used in the callbacks
- * @param add is a required callback, which will be called when a service is added and initially for the existing service.
- * @param remove is a required callback, which will be called when a service is removed
- * @return the tracker id or < 0 if unsuccessful.
- */
-long celix_bundleContext_trackServices(
-        celix_bundle_context_t* ctx,
-        const char* serviceName,
-        void* callbackHandle,
-        void (*add)(void* handle, void* svc),
-        void (*remove)(void* handle, void* svc)
-);
-
-typedef struct celix_service_tracker_options {
-    celix_service_filter_options_t filter;
-
-    //callback options
-    void* callbackHandle;
-
-    void (*set)(void *handle, void *svc); //highest ranking
-    void (*add)(void *handle, void *svc);
-    void (*remove)(void *handle, void *svc);
-
-    void (*setWithProperties)(void *handle, void *svc, const celix_properties_t *props); //highest ranking
-    void (*addWithProperties)(void *handle, void *svc, const celix_properties_t *props);
-    void (*removeWithProperties)(void *handle, void *svc, const celix_properties_t *props);
-
-    void (*setWithOwner)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *svcOwner); //highest ranking
-    void (*addWithOwner)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *svcOwner);
-    void (*removeWithOwner)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *svcOwner);
-} celix_service_tracking_options_t;
-
-#define CELIX_EMPTY_SERVICE_TRACKING_OPTIONS { .filter.serviceName = NULL, \
-    .filter.versionRange = NULL, \
-    .filter.filter = NULL, \
-    .filter.lang = NULL, \
-    .callbackHandle = NULL, \
-    .set = NULL, \
-    .add = NULL, \
-    .remove = NULL, \
-    .setWithProperties = NULL, \
-    .addWithProperties = NULL, \
-    .removeWithProperties = NULL, \
-    .setWithOwner = NULL, \
-    .addWithOwner = NULL, \
-    .removeWithOwner = NULL}
-
-/**
- * Tracks services using the provided tracker options.
- * The tracker options are only using during this call and can safely be freed/reused after this call returns.
- *
- * @param ctx The bundle context.
- * @param opts The pointer to the tracker options.
- * @return the tracker id or < 0 if unsuccessful.
- */
-long celix_bundleContext_trackServicesWithOptions(celix_bundle_context_t *ctx, const celix_service_tracking_options_t *opts);
-
-
-
-/**
- * Get and lock the service with the provided service id
- * Invokes the provided callback with the found service.
- * The svc, props and owner in the callback are only valid during the callback.
- * If no service is found the callback will not be invoked
- *
- * This function will block till the callback is finished. As result it is possible to provide callback data from the
- * stack.
- *
- * @param ctx The bundle context
- * @param serviceId the service id.
- * @param serviceName the service name of the service. Should match with the registered service name of the provided service id (sanity check)
- * @param callbackHandle The data pointer, which will be used in the callbacks
- * @param use The callback, which will be called when service is retrieved.
- * @param bool returns true if a service was found.
- */
-bool celix_bundleContext_useServiceWithId(
-        celix_bundle_context_t *ctx,
-        long serviceId,
-        const char *serviceName /*sanity check*/,
-        void *callbackHandle,
-        void (*use)(void *handle, void* svc)
-);
-
-/**
- * Get and lock the current highest ranking service conform serviceName, versionRange an filter.
- * Invokes the provided callback with the found service.
- * The svc, props and owner in the callback are only valid during the callback.
- * If no service is found the callback will not be invoked.
- *
- * This function will block till the callback is finished. As result it is possible to provide callback data from the
- * stack.
- *
- * @param   ctx The bundle context
- * @param   serviceName the required service name.
- * @param   callbackHandle The data pointer, which will be used in the callbacks
- * @param   use The callback, which will be called when service is retrieved.
- * @return  True if a service was found.
- */
-bool celix_bundleContext_useService(
-        celix_bundle_context_t *ctx,
-        const char* serviceName,
-        void *callbackHandle,
-        void (*use)(void *handle, void *svc)
-);
-
-/**
- * Get and lock the current services conform serviceName, versionRange an filter.
- * Invokes the provided callback with the found services.
- * The svc, props and owner in the callback are only valid during the callback.
- * If no services are found the callback will not be invoked.
- *
- * This function will block till the callback is finished. As result it is possible to provide callback data from the
- * stack.
- *
- * @param   ctx The bundle context
- * @param   serviceName the required service name.
- * @param   serviceRange the optional service version range (e.g. '[1.0.0,2.0.0)' )
- * @param   filter the optional filter.
- * @param   callbackHandle The data pointer, which will be used in the callbacks
- * @param   use The callback, which will be called for every service found.
- */
-void celix_bundleContext_useServices(
-        celix_bundle_context_t *ctx,
-        const char* serviceName,
-        void *callbackHandle,
-        void (*use)(void *handle, void *svc)
-);
-
-
-typedef struct celix_service_use_options {
-    celix_service_filter_options_t filter;
-
-    /**
-     * Callback info
-     */
-     void *callbackHandle;
-
-     void (*use)(void *handle, void *svc);
-     void (*useWithProperties)(void *handle, void *svc, const celix_properties_t *props);
-     void (*useWithOwner)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *svcOwner);
-} celix_service_use_options_t;
-
-#define CELIX_EMPTY_SERVICE_USE_OPTIONS {.filter.serviceName = NULL, \
-    .filter.versionRange = NULL, \
-    .filter.filter = NULL, \
-    .filter.lang = NULL, \
-    .callbackHandle = NULL, \
-    .use = NULL, \
-    .useWithProperties = NULL, \
-    .useWithOwner = NULL}
-
-/**
- * Get and lock the current highest ranking service conform the service filter info from the provided options.
- *
- * Invokes the provided callback with the found service.
- * The svc, props and owner in the callback are only valid during the callback.
- * If no service is found the callback will not be invoked.
- *
- * This function will block till the callback is finished. As result it is possible to provide callback data from the
- * stack.
- *
- * @param   ctx The bundle context.
- * @param   serviceName the required service name.
- * @param   opts The required options. Note that the serviceName is required.
- * @return  True if a service was found.
- */
-bool celix_bundleContext_useServiceWithOptions(
-        celix_bundle_context_t *ctx,
-        const celix_service_use_options_t *opts);
-
-
-/**
- * Get and lock the current services conform the service filter info from the provided options.
- *
- * Invokes the provided callback with the found services.
- * The svc, props and owner in the callback are only valid during the callback.
- * If no services are found the callback will not be invoked.
- * At least a serviceName needs to be provided, if not the callback is not invoked.
- *
- * This function will block till all the callbacks are finished. As result it is possible to provide callback data from the
- * stack.
- *
- * @param   ctx The bundle context.
- * @param   serviceName the required service name.
- * @param   opts The required options. Note that the serviceName is required.
- * @param   callbackHandle The data pointer, which will be used in the callbacks.
- * @param   use The callback, which will be called for every service found.
- */
-void celix_bundleContext_useServicesWithOptions(
-        celix_bundle_context_t *ctx,
-        const celix_service_use_options_t *opts);
-
-
-/**
- * Install and optional start a bundle.
- *
- * @param ctx The bundle context
- * @param bundleLoc The bundle location to the bundle zip file.
- * @param autoStart If the bundle should also be started.
- * @return the bundleId >= 0 or < 0 if the bundle could not be installed and possibly started.
- */
-long celix_bundleContext_installBundle(celix_bundle_context_t *ctx, const char *bundleLoc, bool autoStart);
-
-/**
- * Uninstall the bundle with the provided bundle id. If needed the bundle will be stopped first.
- *
- * @param ctx The bundle context
- * @param bundleId The bundle id to stop
- * @return true if the bundle is correctly uninstalled. False if not.
- */
-bool celix_bundleContext_uninstallBundle(celix_bundle_context_t *ctx, long bundleId);
-
-
-/**
- * Service tracker options. This struct can be used to fine grained tune the
- * requested bundle tracker ootions.
- */
-typedef struct celix_bundle_tracker_options {
-    /**
-     * Handle used in the tracker callbacks.
-     */
-    void* callbackHandle;
-
-    /**
-     * Tracker callback when a bundle is installed.
-     * @param handle    The handle, contains the value of the callbackHandle.
-     * @param bundle    The bundle which has been started.
-     *                  The bundle pointer is only guaranteed to be valid during the callback.
-     */
-    void (*onStarted)(void *handle, const celix_bundle_t *bundle); //highest ranking
-
-    /**
-     * Tracker callback when a bundle is removed.
-     * @param handle    The handle, contains the value of the callbackHandle.
-     * @param bundle    The bundle which has been started.
-     *                  The bundle pointer is only guaranteed to be valid during the callback.
-     */
-    void (*onStopped)(void *handle, const celix_bundle_t *bundle);
-
-    //TODO callback for on installed, resolved, uninstalled ??
-
-    /**
-     *
-     * @param handle    The handle, contains the value of the callbackHandle.
-     * @param event     The bundle event. Is only valid during the callback.
-     */
-    void (*onBundleEvent)(void *handle, const celix_bundle_event_t *event);
-} celix_bundle_tracker_options_t;
-
-/**
- * Tracks bundles using the provided bundle tracker options.
- * The tracker options are only using during this call and can safely be freed/reused after this call returns.
- * (i.e. can be on the stack)
- *
- * @param ctx   The bundle context.
- * @param opts  The pointer to the bundle tracker options.
- * @return      The bundle tracker id or < 0 if unsuccessful.
- */
-long celix_bundleContext_trackBundlesWithOptions(
-        celix_bundle_context_t* ctx,
-        const celix_bundle_tracker_options_t *opts
-);
-
-/**
- * track bundles
- * The add bundle callback will also be called for already installed bundles.
- *
- * @param ctx               The bundle context.
- * @param callbackHandle    The data pointer, which will be used in the callbacks
- * @param add               The callback which will be called for started bundles.
- * @param remove            The callback which will be called when bundles are stopped.
- * @return                  The bundle tracker id or < 0 if unsuccessful.
- */
-long celix_bundleContext_trackBundles(
-        celix_bundle_context_t* ctx,
-        void* callbackHandle,
-        void (*onStarted)(void* handle, const celix_bundle_t *bundle),
-        void (*onStopped)(void *handle, const celix_bundle_t *bundle)
-);
-
-/**
- * Use the bundle with the provided bundle id if it is in the active (started) state
- * The provided callback will be called if the bundle is found and in the active (started) state.
- *
- * @param ctx               The bundle context.
- * @param bundleId          The bundle id.
- * @param callbackHandle    The data pointer, which will be used in the callbacks
- * @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(
-        celix_bundle_context_t *ctx,
-        long bundleId,
-        void *callbackHandle,
-        void (*use)(void *handle, const celix_bundle_t *bundle)
-);
-
-//TODO add useBundleWithOptions (e.g. which state)
-
-
-//TODO findBundles
-
-
-/**
- * Use the currently active (started) bundles.
- * The provided callback will be called for all the currently started bundles.
- *
- * @param ctx               The bundle context.
- * @param callbackHandle    The data pointer, which will be used in the callbacks
- * @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_useBundles(
-        celix_bundle_context_t *ctx,
-        void *callbackHandle,
-        void (*use)(void *handle, const celix_bundle_t *bundle)
-);
-
-
-//TODO trackServiceTracker
-
-/**
- * Stop the tracker with the provided track id.
- * Could be a service tracker, bundle tracker or service tracker tracker.
- * Only works for the trackers owned by the bundle of the bundle context.
- *
- * Will log a error if the provided tracker id is unknown. Will silently ignore trackerId < 0.
- */
-void celix_bundleContext_stopTracker(celix_bundle_context_t *ctx, long trackerId);
-
-
-
 #ifdef __cplusplus
 }
 #endif

http://git-wip-us.apache.org/repos/asf/celix/blob/03df0edc/framework/include/celix/dm/DependencyManager.h
----------------------------------------------------------------------
diff --git a/framework/include/celix/dm/DependencyManager.h b/framework/include/celix/dm/DependencyManager.h
index 258a311..f90a03c 100644
--- a/framework/include/celix/dm/DependencyManager.h
+++ b/framework/include/celix/dm/DependencyManager.h
@@ -17,20 +17,21 @@
  * under the License.
  */
 
-#ifndef CELIX_DM_DEPENDENCYMANAGER_H
-#define CELIX_DM_DEPENDENCYMANAGER_H
-
 
 #include "celix/dm/types.h"
 #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>
 #include <mutex>
 
+#ifndef CELIX_DM_DEPENDENCYMANAGER_H
+#define CELIX_DM_DEPENDENCYMANAGER_H
+
 namespace celix { namespace dm {
 
     class DependencyManager {

http://git-wip-us.apache.org/repos/asf/celix/blob/03df0edc/framework/include/celix_api.h
----------------------------------------------------------------------
diff --git a/framework/include/celix_api.h b/framework/include/celix_api.h
index b770876..5129a65 100644
--- a/framework/include/celix_api.h
+++ b/framework/include/celix_api.h
@@ -20,15 +20,28 @@
 #ifndef CELIX_CELIX_API_H_
 #define CELIX_CELIX_API_H_
 
+#include "properties.h"
+
+#include "array_list.h"
+#include "celix_array_list.h"
+
+#include "constants.h"
+
 #include "celix_utils_api.h"
+
 #include "bundle.h"
+#include "celix_bundle.h"
+
 #include "bundle_context.h"
+#include "celix_bundle_context.h"
+
 #include "service_registration.h"
 #include "service_factory.h"
 #include "service_reference.h"
 #include "service_tracker.h"
 #include "service_tracker_customizer.h"
 #include "listener_hook_service.h"
+
 #include "framework.h"
 #include "celix_framework_factory.h"
 #include "celix_launcher.h"

http://git-wip-us.apache.org/repos/asf/celix/blob/03df0edc/framework/include/celix_bundle.h
----------------------------------------------------------------------
diff --git a/framework/include/celix_bundle.h b/framework/include/celix_bundle.h
new file mode 100644
index 0000000..74ea9bf
--- /dev/null
+++ b/framework/include/celix_bundle.h
@@ -0,0 +1,46 @@
+/**
+ *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_types.h"
+#include "bundle_state.h"
+
+#ifndef CELIX_BUNDLE_H_
+#define CELIX_BUNDLE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**********************************************************************************************************************
+ **********************************************************************************************************************
+ * Updated API
+ **********************************************************************************************************************
+ **********************************************************************************************************************/
+
+long celix_bundle_getId(const bundle_t *bnd);
+
+celix_bundle_state_e celix_bundle_getState(const bundle_t *bnd);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CELIX_BUNDLE_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/03df0edc/framework/include/celix_bundle_context.h
----------------------------------------------------------------------
diff --git a/framework/include/celix_bundle_context.h b/framework/include/celix_bundle_context.h
new file mode 100644
index 0000000..1e8dff5
--- /dev/null
+++ b/framework/include/celix_bundle_context.h
@@ -0,0 +1,691 @@
+/**
+ *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_types.h"
+#include "celix_service_factory.h"
+#include "celix_properties.h"
+#include "celix_array_list.h"
+
+#ifndef CELIX_BUNDLE_CONTEXT_H_
+#define CELIX_BUNDLE_CONTEXT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**********************************************************************************************************************
+ **********************************************************************************************************************
+ * Updated API
+ **********************************************************************************************************************
+ **********************************************************************************************************************/
+
+/**
+* Register a service to the Celix framework.
+*
+* @param ctx The bundle context
+* @param svc the service object. Normally a pointer to a service struct (i.e. a struct with function pointers)
+* @param serviceName the service name, cannot be NULL
+* @param properties The meta properties associated with the service. The service registration will take ownership of the properties (e.g. no destroy needed)
+* @return The serviceId (>= 0) or < 0 if the registration was unsuccessful.
+*/
+long celix_bundleContext_registerService(celix_bundle_context_t *ctx, void *svc, const char *serviceName, celix_properties_t *properties);
+
+/**
+ * Register a service factory in the framework (for the C language).
+ * The service factory will be called for every bundle requesting/de-requesting a service. This gives the provider the
+ * option to create bundle specific service instances.
+ *
+ * When a service is requested for a bundle the getService of the factory service will be called. This function must
+ * return a valid pointer to a service conform the registered service name or NULL.
+ * When a service in no longer needed for a bundle (e.g. ending the useService(s) calls when a service tacker is stopped)
+ * the ungetService function of the service factory will be called.
+ *
+ * @param ctx The bundle context
+ * @param factory The pointer to the factory service.
+ * @param serviceName The required service name of the services this factory will produce.
+ * @param properties The optional service factory properties. For a service consumer this will be seen as the service properties.
+ * @return The serviceId (>= 0) or < 0 if the registration was unsuccessful.
+ */
+long celix_bundleContext_registerServiceFactory(celix_bundle_context_t *ctx, celix_service_factory_t *factory, const char *serviceName, celix_properties_t *props);
+
+/**
+ * Service Registration Options when registering services to the Celix framework.
+ */
+typedef struct celix_service_registration_options {
+    /**
+     * The service pointer. The actual pointer to the service. For C this is normally a pointer to a struct
+     * with function pointers, but theoretically this can be a pointer to anything (e.g. a pointer to a single function,
+     * or a pointer to a C++ interface implementation, or just a pointer to a data structure).
+     *
+     * The bundle is responsible to keep the service pointer valid as long as it is registered in the Celix framework.
+     */
+    void *svc;
+
+    /**
+     * The service factory pointer.
+     * Note if the factory service is set, the svc field will not be used.
+     *
+     * The service factory will be called for every bundle requesting/de-requesting a service. This gives the provider the
+     * option to create bundle specific service instances.
+     *
+     * When a service is requested for a bundle the getService of the factory service will be called. This function must
+     * return a valid pointer to a service conform the registered service name or NULL.
+     * When a service in no longer needed for a bundle (e.g. ending the useService(s) calls when a service tacker is stopped)
+     * the ungetService function of the service factory will be called.
+     *
+     * The bundle is responsible to keep the service factory pointer valid as long as it is registered in the Celix framework.
+     */
+    celix_service_factory_t *factory;
+
+    /**
+     * The required service name. This is used to identify the service. A fully qualified name with a namespace is
+     * advisable to prevent name collision. (e.g. EXAMPLE_PRESURE_SENSOR).
+     */
+    const char *serviceName;
+
+    /**
+     * The optional service properties. These contain meta information about the service in the
+     * form of string key/values. (e.g. the location of a pressure sensor: location=left-tire).
+     *
+     * When a service is registered the Celix framework will take ownership of the provided properties.
+     * If a registration fails, the properties will be destroyed (freed) by the Celix framework.
+     */
+    celix_properties_t *properties;
+
+    /**
+     * The optional service language. If this is NULL, CELIX_FRAMEWORK_SERVICE_LANGUAGE_C is used.
+     */
+    const char *serviceLanguage;
+
+    /**
+     * The optional service version (in the form of <MAJOR>.<MINOR>.<MICRO>.<QUALIFIER>).
+     * If present consumer of the service can specific which service version range of
+     * a specific service they are interested in. Note that it is the responsibility of the users to ensure that
+     * service in those version range are compatible (binary of source). It is advisable to use semantic versioning
+     * for this.
+     */
+    const char *serviceVersion;
+} celix_service_registration_options_t;
+
+/**
+ * Macro to create a empty celix_service_registration_options_t type.
+ */
+#define CELIX_EMPTY_SERVICE_REGISTRATION_OPTIONS { .svc = NULL, \
+    .serviceName = NULL, \
+    .properties = NULL, \
+    .serviceLanguage = NULL, \
+    .serviceVersion = NULL }
+
+
+/**
+* Register a service to the Celix framework using the provided service registration options.
+*
+* @param ctx The bundle context
+* @param opts The pointer to the registration options. The options are only in the during registration call.
+* @return The serviceId (>= 0) or < 0 if the registration was unsuccessful.
+*/
+long celix_bundleContext_registerServiceWithOptions(celix_bundle_context_t *ctx, const celix_service_registration_options_t *opts);
+
+
+/**
+ * Unregister the service or service factory with service id.
+ * The service will only be unregistered if the bundle of the bundle context is the owner of the service.
+ *
+ * Will log an error if service id is unknown. Will silently ignore services ids < 0.
+ *
+ * @param ctx The bundle context
+ * @param serviceId The service id
+ */
+void celix_bundleContext_unregisterService(celix_bundle_context_t *ctx, long serviceId);
+
+
+
+
+
+
+
+
+/**
+ * Finds the highest ranking service and returns the service id.
+ *
+ * @param ctx The bundle context
+ * @param serviceName The required service name
+ * @return If found a valid service id (>= 0) if not found -1.
+ */
+long celix_bundleContext_findService(celix_bundle_context_t *ctx, const char *serviceName);
+
+/**
+ * Finds the services with the provided service name and returns a list of the found service ids.
+ *
+ * @param ctx The bundle context
+ * @param serviceName The required service name
+ * @return A array list with as value a long int.
+ */
+celix_array_list_t* celix_bundleContext_findServices(celix_bundle_context_t *ctx, const char *serviceName);
+
+/**
+ * Service filter options which can be used to query for certain services.
+ */
+typedef struct celix_service_filter_options {
+    /**
+     * The required service name.
+     */
+    const char* serviceName;
+
+    /**
+     * The optional version range. If service are registerd with a service version this attribute can be used to
+     * only select service with a version in the version range.
+     * It uses the maven version range format, e.g. [1.0.0,2.0.0) or [1.1.1], etc.
+     */
+    const char* versionRange;
+
+    /**
+     * LDAP filter to use for fine tuning the filtering, e.g. (|(location=middle)(location=front))
+     * The filter will be applied to all the user provided and framework provided service properties.
+     */
+    const char* filter;
+
+    /**
+     * The optional service language to filter for. If this is NULL or "" the C language will be used.
+     */
+    const char* serviceLanguage;
+} celix_service_filter_options_t;
+
+/**
+ * Macro to create a empty celix_service_filter_options_t type.
+ */
+#define CELIX_EMPTY_SERVICE_FILTER_OPTIONS {.serviceName = NULL, .versionRange = NULL, .filter = NULL, .serviceLanguage = NULL}
+
+
+/**
+ * Finds the highest ranking service and returns the service id.
+ *
+ * @param ctx The bundle context
+ * @param opts The pointer to the filter options.
+ * @return If found a valid service id (>= 0) if not found -1.
+ */
+long celix_bundleContext_findServiceWithOptions(celix_bundle_context_t *ctx, const celix_service_filter_options_t *opts);
+
+/**
+ * Finds the services conform the provider filter options and returns a list of the found service ids.
+ *
+ * @param ctx The bundle context
+ * @param opts The pointer to the filter options.
+ * @return A array list with as value a long int.
+ */
+celix_array_list_t* celix_bundleContext_findServicesWithOptions(celix_bundle_context_t *ctx, const celix_service_filter_options_t *opts);
+
+
+/**
+ * track the highest ranking service with the provided serviceName.
+ * The highest ranking services will used for the callback.
+ * If a new and higher ranking services the callback with be called again with the new service.
+ * If a service is removed a the callback with be called with next highest ranking service or NULL as service.
+ *
+ * @param ctx The bundle context.
+ * @param serviceName The required service name to track
+ * @param callbackHandle The data pointer, which will be used in the callbacks
+ * @param set is a required callback, which will be called when a new highest ranking service is set.
+ * @return the tracker id (>=0) or < 0 if unsuccessful.
+ */
+long celix_bundleContext_trackService(
+        celix_bundle_context_t* ctx,
+        const char* serviceName,
+        void* callbackHandle,
+        void (*set)(void* handle, void* svc)
+);
+
+/**
+ * track services with the provided serviceName.
+ *
+ * @param ctx The bundle context.
+ * @param serviceName The required service name to track
+ * @param callbackHandle The data pointer, which will be used in the callbacks
+ * @param add is a required callback, which will be called when a service is added and initially for the existing service.
+ * @param remove is a required callback, which will be called when a service is removed
+ * @return the tracker id (>=0) or < 0 if unsuccessful.
+ */
+long celix_bundleContext_trackServices(
+        celix_bundle_context_t* ctx,
+        const char* serviceName,
+        void* callbackHandle,
+        void (*add)(void* handle, void* svc),
+        void (*remove)(void* handle, void* svc)
+);
+
+/**
+ * Service Tracker Options used to fine tune which services to track and the callback to be used for the tracked services.
+ */
+typedef struct celix_service_tracker_options {
+    /**
+     * The service filter options, used to setup the filter for the service to track.
+     */
+    celix_service_filter_options_t filter;
+
+    /**
+     * The optional callback pointer used in all the provided callback function (set, add, remove, setWithProperties, etc).
+     */
+    void* callbackHandle;
+
+    /**
+     * The optional set callback will be called when a new highest ranking service is available conform the provided
+     * service filter options.
+     * @param handle The callbackHandle pointer as provided in the service tracker options.
+     * @param svc The service pointer of the highest ranking service.
+     */
+    void (*set)(void *handle, void *svc);
+
+    /**
+     * The optional setWithProperties callback is handled as the set callback, but with the addition that the service properties
+     * will also be provided to the callback.
+     */
+    void (*setWithProperties)(void *handle, void *svc, const celix_properties_t *props); //highest ranking
+
+    /**
+     * The optional setWithOwner callback is handled as the set callback, but with the addition that the service properties
+     * and the bundle owning the service will also be provided to the callback.
+     */
+    void (*setWithOwner)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *svcOwner); //highest ranking
+
+    /**
+     * The optional add callback will be called for every current and future service found conform the provided service filter
+     * options as long as the tracker is active.
+     * @param handle The callbackHandle pointer as provided in the service tracker options.
+     * @param svc The service pointer of a service matching the provided service filter options.
+     */
+    void (*add)(void *handle, void *svc);
+
+    /**
+     * The optional addWithProperties callback is handled as the add callback, but with the addition that the service properties
+     * will also be provided to the callback.
+     */
+    void (*addWithProperties)(void *handle, void *svc, const celix_properties_t *props);
+
+    /**
+     * The optional addWithOwner callback is handled as the add callback, but with the addition that the service properties
+     * and the bundle owning the service will also be provided to the callback.
+     */
+    void (*addWithOwner)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *svcOwner);
+
+    /**
+     * The optional remove callback will be called for every service conform the provided service filter options that is
+     * unregistered. When the remove call is finished the removed services should be considered invalid. This means
+     * that the callback provider should ensure that the removed service is not in use or going to be used after the
+     * remove callback is finished.
+     *
+     * @param handle The callbackHandle pointer as provided in the service tracker options.
+     * @param svc The service pointer of a service matching the provided service filter options.
+     */
+    void (*remove)(void *handle, void *svc);
+
+    /**
+     * The optional removeWithProperties callback is handled as the remove callback, but with the addition that the service properties
+     * will also be provided to the callback.
+     */
+    void (*removeWithProperties)(void *handle, void *svc, const celix_properties_t *props);
+
+    /**
+    * The optional removeWithOwner callback is handled as the remove callback, but with the addition that the service properties
+    * and the bundle owning the service will also be provided to the callback.
+    */
+    void (*removeWithOwner)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *svcOwner);
+} celix_service_tracking_options_t;
+
+/**
+ * Macro to create a empty celix_service_tracking_options_t type.
+ */
+#define CELIX_EMPTY_SERVICE_TRACKING_OPTIONS { .filter.serviceName = NULL, \
+    .filter.versionRange = NULL, \
+    .filter.filter = NULL, \
+    .filter.serviceLanguage = NULL, \
+    .callbackHandle = NULL, \
+    .set = NULL, \
+    .add = NULL, \
+    .remove = NULL, \
+    .setWithProperties = NULL, \
+    .addWithProperties = NULL, \
+    .removeWithProperties = NULL, \
+    .setWithOwner = NULL, \
+    .addWithOwner = NULL, \
+    .removeWithOwner = NULL}
+
+/**
+ * Tracks services using the provided tracker options.
+ * The tracker options are only using during this call and can safely be freed/reused after this call returns.
+ *
+ * @param ctx The bundle context.
+ * @param opts The pointer to the tracker options.
+ * @return the tracker id (>=0) or < 0 if unsuccessful.
+ */
+long celix_bundleContext_trackServicesWithOptions(celix_bundle_context_t *ctx, const celix_service_tracking_options_t *opts);
+
+/**
+ * Stop the tracker with the provided track id.
+ * Could be a service tracker, bundle tracker or service tracker tracker.
+ * Only works for the trackers owned by the bundle of the bundle context.
+ *
+ * Will log a error if the provided tracker id is unknown. Will silently ignore trackerId < 0.
+ */
+void celix_bundleContext_stopTracker(celix_bundle_context_t *ctx, long trackerId);
+
+
+
+
+
+
+/**
+ * Use the service with the provided service id using the provided callback. The Celix framework will ensure that
+ * the targeted service cannot be removed during the callback.
+ *
+ * The svc is should only be considered valid during the callback.
+ * If no service is found the callback will not be invoked.
+ *
+ * This function will block till the callback is finished. As result it is possible to provide callback data from the
+ * stack.
+ *
+ * @param ctx The bundle context
+ * @param serviceId the service id.
+ * @param serviceName the service name of the service. Should match with the registered service name of the provided service id (sanity check)
+ * @param callbackHandle The data pointer, which will be used in the callbacks
+ * @param use The callback, which will be called when service is retrieved.
+ * @param bool returns true if a service was found.
+ */
+bool celix_bundleContext_useServiceWithId(
+        celix_bundle_context_t *ctx,
+        long serviceId,
+        const char *serviceName /*sanity check*/,
+        void *callbackHandle,
+        void (*use)(void *handle, void* svc)
+);
+
+/**
+ * Use the highest ranking service with the provided service name using the provided callback. The Celix framework will
+ * ensure that the targeted service cannot be removed during the callback.
+ *
+ * The svc is should only be considered valid during the callback.
+ * If no service is found the callback will not be invoked.
+ *
+ * This function will block till the callback is finished. As result it is possible to provide callback data from the
+ * stack.
+ *
+ * @param   ctx The bundle context
+ * @param   serviceName the required service name.
+ * @param   callbackHandle The data pointer, which will be used in the callbacks
+ * @param   use The callback, which will be called when service is retrieved.
+ * @return  True if a service was found.
+ */
+bool celix_bundleContext_useService(
+        celix_bundle_context_t *ctx,
+        const char* serviceName,
+        void *callbackHandle,
+        void (*use)(void *handle, void *svc)
+);
+
+/**
+ * Use the services with the provided service name using the provided callback. The Celix framework will
+ * ensure that the targeted service cannot be removed during the callback.
+ *
+ * The svc is should only be considered valid during the callback.
+ * If no service is found the callback will not be invoked.
+ *
+ * This function will block till the callback is finished. As result it is possible to provide callback data from the
+ * stack.
+ *
+ * @param   ctx The bundle context
+ * @param   serviceName the required service name.
+ * @param   callbackHandle The data pointer, which will be used in the callbacks
+ * @param   use The callback, which will be called for every service found.
+ */
+void celix_bundleContext_useServices(
+        celix_bundle_context_t *ctx,
+        const char* serviceName,
+        void *callbackHandle,
+        void (*use)(void *handle, void *svc)
+);
+
+/**
+ * Service Use Options used to fine tune which services to use and which callbacks to use.
+ */
+typedef struct celix_service_use_options {
+    /**
+     * The service filter options, used to setup the filter for the service to track.
+     */
+    celix_service_filter_options_t filter;
+
+    /**
+     * The optional callback pointer used in all the provided callback function (set, add, remove, setWithProperties, etc).
+     */
+    void *callbackHandle;
+
+    /**
+     * The optional use callback will be called when for every services found conform the service filter options
+     * - in case of findServices - or only for the highest ranking service found - in case of findService -.
+     *
+     * @param handle The callbackHandle pointer as provided in the service tracker options.
+     * @param svc The service pointer of the highest ranking service.
+     */
+    void (*use)(void *handle, void *svc);
+
+    /**
+     * The optional useWithProperties callback is handled as the use callback, but with the addition that the service properties
+     * will also be provided to the callback.
+     */
+    void (*useWithProperties)(void *handle, void *svc, const celix_properties_t *props);
+
+    /**
+     * The optional useWithOwner callback is handled as the yse callback, but with the addition that the service properties
+     * and the bundle owning the service will also be provided to the callback.
+     */
+    void (*useWithOwner)(void *handle, void *svc, const celix_properties_t *props, const celix_bundle_t *svcOwner);
+} celix_service_use_options_t;
+
+/**
+ * Macro to create a empty celix_service_use_options_t type.
+ */
+#define CELIX_EMPTY_SERVICE_USE_OPTIONS {.filter.serviceName = NULL, \
+    .filter.versionRange = NULL, \
+    .filter.filter = NULL, \
+    .filter.serviceLanguage = NULL, \
+    .callbackHandle = NULL, \
+    .use = NULL, \
+    .useWithProperties = NULL, \
+    .useWithOwner = NULL}
+
+/**
+ * Use the services with the provided service filter optons using the provided callback. The Celix framework will
+ * ensure that the targeted service cannot be removed during the callback.
+ *
+ * The svc is should only be considered valid during the callback.
+ * If no service is found the callback will not be invoked.
+ *
+ * This function will block till the callback is finished. As result it is possible to provide callback data from the
+ * stack.
+ *
+ * @param   ctx The bundle context.
+ * @param   opts The required options. Note that the serviceName is required.
+ * @return  True if a service was found.
+ */
+bool celix_bundleContext_useServiceWithOptions(
+        celix_bundle_context_t *ctx,
+        const celix_service_use_options_t *opts);
+
+
+/**
+ * Use the services with the provided service filter optons using the provided callback. The Celix framework will
+ * ensure that the targeted service cannot be removed during the callback.
+ *
+ * The svc is should only be considered valid during the callback.
+ * If no service is found the callback will not be invoked.
+ *
+ * This function will block till the callback is finished. As result it is possible to provide callback data from the
+ * stack.
+ *
+ * @param   ctx The bundle context.
+ * @param   opts The required options. Note that the serviceName is required.
+ */
+void celix_bundleContext_useServicesWithOptions(
+        celix_bundle_context_t *ctx,
+        const celix_service_use_options_t *opts);
+
+
+
+
+
+
+
+/**
+ * Install and optional start a bundle.
+ *
+ * @param ctx The bundle context
+ * @param bundleLoc The bundle location to the bundle zip file.
+ * @param autoStart If the bundle should also be started.
+ * @return the bundleId (>= 0) or < 0 if the bundle could not be installed and possibly started.
+ */
+long celix_bundleContext_installBundle(celix_bundle_context_t *ctx, const char *bundleLoc, bool autoStart);
+
+/**
+ * Uninstall the bundle with the provided bundle id. If needed the bundle will be stopped first.
+ *
+ * @param ctx The bundle context
+ * @param bundleId The bundle id to stop
+ * @return true if the bundle is correctly uninstalled. False if not.
+ */
+bool celix_bundleContext_uninstallBundle(celix_bundle_context_t *ctx, long bundleId);
+
+/**
+ * track bundles
+ * The add bundle callback will also be called for already installed bundles.
+ *
+ * @param ctx               The bundle context.
+ * @param callbackHandle    The data pointer, which will be used in the callbacks
+ * @param add               The callback which will be called for started bundles.
+ * @param remove            The callback which will be called when bundles are stopped.
+ * @return                  The bundle tracker id or < 0 if unsuccessful.
+ */
+long celix_bundleContext_trackBundles(
+        celix_bundle_context_t* ctx,
+        void* callbackHandle,
+        void (*onStarted)(void* handle, const celix_bundle_t *bundle),
+        void (*onStopped)(void *handle, const celix_bundle_t *bundle)
+);
+
+
+/**
+ * The Service Bundle Tracking options can be used to fine tune the requested bundle tracker options.
+ */
+typedef struct celix_bundle_tracker_options {
+    /**
+     * The optional callback pointer used in all the provided callback function (set, add, remove, setWithProperties, etc).
+     */
+    void* callbackHandle;
+
+    /**
+     * Tracker callback when a bundle is installed.
+     * @param handle    The handle, contains the value of the callbackHandle.
+     * @param bundle    The bundle which has been started.
+     *                  The bundle pointer is only guaranteed to be valid during the callback.
+     */
+    void (*onStarted)(void *handle, const celix_bundle_t *bundle); //highest ranking
+
+    /**
+     * Tracker callback when a bundle is removed.
+     * @param handle    The handle, contains the value of the callbackHandle.
+     * @param bundle    The bundle which has been started.
+     *                  The bundle pointer is only guaranteed to be valid during the callback.
+     */
+    void (*onStopped)(void *handle, const celix_bundle_t *bundle);
+
+    //TODO callback for on installed, resolved, uninstalled ??
+
+    /**
+     *
+     * @param handle    The handle, contains the value of the callbackHandle.
+     * @param event     The bundle event. Is only valid during the callback.
+     */
+    void (*onBundleEvent)(void *handle, const celix_bundle_event_t *event);
+} celix_bundle_tracking_options_t;
+
+/**
+ * Macro to create a empty celix_service_filter_options_t type.
+ */
+#define CELIX_EMPTY_BUNDLE_TRACKING_OPTIONS {.callbackHandle = NULL, .onStarted = NULL, .onStopped = NULL, .onBundleEvent = NULL}
+
+/**
+ * Tracks bundles using the provided bundle tracker options.
+ * The tracker options are only using during this call and can safely be freed/reused after this call returns.
+ * (i.e. can be on the stack)
+ *
+ * @param ctx   The bundle context.
+ * @param opts  The pointer to the bundle tracker options.
+ * @return      The bundle tracker id (>=0) or < 0 if unsuccessful.
+ */
+long celix_bundleContext_trackBundlesWithOptions(
+        celix_bundle_context_t* ctx,
+        const celix_bundle_tracking_options_t *opts
+);
+
+/**
+ * Use the bundle with the provided bundle id if it is in the active (started) state
+ * The provided callback will be called if the bundle is found and in the active (started) state.
+ *
+ * @param ctx               The bundle context.
+ * @param bundleId          The bundle id.
+ * @param callbackHandle    The data pointer, which will be used in the callbacks
+ * @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(
+        celix_bundle_context_t *ctx,
+        long bundleId,
+        void *callbackHandle,
+        void (*use)(void *handle, const celix_bundle_t *bundle)
+);
+
+/**
+ * Use the currently active (started) bundles.
+ * The provided callback will be called for all the currently started bundles.
+ *
+ * @param ctx               The bundle context.
+ * @param callbackHandle    The data pointer, which will be used in the callbacks
+ * @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_useBundles(
+        celix_bundle_context_t *ctx,
+        void *callbackHandle,
+        void (*use)(void *handle, const celix_bundle_t *bundle)
+);
+
+
+//TODO add useBundleWithOptions (e.g. which state)
+//TODO findBundles
+//TODO trackServiceTracker
+
+/**
+ * Gets the dependency manager for this bundle context.
+ *
+ * @return the dependency manager or NULL if unsuccessful.
+ */
+dm_dependency_manager_t* celix_bundleContext_getDependencyManager(celix_bundle_context_t *ctx);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //CELIX_BUNDLE_CONTEXT_H_

http://git-wip-us.apache.org/repos/asf/celix/blob/03df0edc/framework/include/celix_service_factory.h
----------------------------------------------------------------------
diff --git a/framework/include/celix_service_factory.h b/framework/include/celix_service_factory.h
index 4373db6..90d2c73 100644
--- a/framework/include/celix_service_factory.h
+++ b/framework/include/celix_service_factory.h
@@ -16,12 +16,13 @@
  *specific language governing permissions and limitations
  *under the License.
  */
-#ifndef CELIX_SERVICE_FACTORY_H_
-#define CELIX_SERVICE_FACTORY_H_
 
-#include "properties.h"
+#include "celix_properties.h"
 #include "bundle.h"
 
+#ifndef CELIX_SERVICE_FACTORY_H_
+#define CELIX_SERVICE_FACTORY_H_
+
 #ifdef __cplusplus
 extern "C" {
 #endif

http://git-wip-us.apache.org/repos/asf/celix/blob/03df0edc/framework/include/service_tracker.h
----------------------------------------------------------------------
diff --git a/framework/include/service_tracker.h b/framework/include/service_tracker.h
index baf2a00..db65776 100644
--- a/framework/include/service_tracker.h
+++ b/framework/include/service_tracker.h
@@ -32,6 +32,7 @@
 #include "service_tracker_customizer.h"
 #include "framework_exports.h"
 #include "bundle_context.h"
+#include "celix_bundle_context.h"
 
 
 #ifdef __cplusplus

http://git-wip-us.apache.org/repos/asf/celix/blob/03df0edc/framework/private/mock/bundle_context_mock.c
----------------------------------------------------------------------
diff --git a/framework/private/mock/bundle_context_mock.c b/framework/private/mock/bundle_context_mock.c
index 9d3fe85..7c0b6e6 100644
--- a/framework/private/mock/bundle_context_mock.c
+++ b/framework/private/mock/bundle_context_mock.c
@@ -27,6 +27,7 @@
 #include "CppUTestExt/MockSupport_c.h"
 
 #include "bundle_context.h"
+#include "celix_bundle_context.h"
 
 celix_status_t bundleContext_create(framework_pt framework, framework_logger_pt logger, bundle_pt bundle, bundle_context_pt *bundle_context) {
 	mock_c()->actualCall("bundleContext_create")
@@ -239,7 +240,7 @@ dm_dependency_manager_t* celix_bundleContext_getDependencyManager(bundle_context
 
 long celix_bundleContext_trackBundlesWithOptions(
 		bundle_context_t* ctx,
-		const celix_bundle_tracker_options_t *opts) {
+		const celix_bundle_tracking_options_t *opts) {
 	mock_c()->actualCall("celix_bundleContext_trackBundlesWithOptions")
 			->withPointerParameters("ctx", ctx)
 			->withConstPointerParameters("opts", opts);

http://git-wip-us.apache.org/repos/asf/celix/blob/03df0edc/framework/src/bundle.c
----------------------------------------------------------------------
diff --git a/framework/src/bundle.c b/framework/src/bundle.c
index 5feb729..fc4cd08 100644
--- a/framework/src/bundle.c
+++ b/framework/src/bundle.c
@@ -16,13 +16,7 @@
  *specific language governing permissions and limitations
  *under the License.
  */
-/*
- * bundle.c
- *
- *  \date       Mar 23, 2010
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
+
 #include <stdlib.h>
 #include <string.h>
 

http://git-wip-us.apache.org/repos/asf/celix/blob/03df0edc/framework/src/bundle_context.c
----------------------------------------------------------------------
diff --git a/framework/src/bundle_context.c b/framework/src/bundle_context.c
index f79d101..2407e2d 100644
--- a/framework/src/bundle_context.c
+++ b/framework/src/bundle_context.c
@@ -26,9 +26,11 @@
 #include "bundle_context_private.h"
 #include "framework_private.h"
 #include "bundle.h"
+#include "celix_bundle.h"
 #include "celix_log.h"
 #include "service_tracker.h"
 #include "dm_dependency_manager.h"
+#include "celix_array_list.h"
 
 static celix_status_t bundleContext_bundleChanged(void *handle, bundle_event_t *event);
 static void bundleContext_cleanupBundleTracker(bundle_context_t *ct);
@@ -545,7 +547,7 @@ static celix_status_t bundleContext_bundleChanged(void *listenerSvc, bundle_even
 
 long celix_bundleContext_trackBundlesWithOptions(
         bundle_context_t* ctx,
-        const celix_bundle_tracker_options_t *opts) {
+        const celix_bundle_tracking_options_t *opts) {
     long trackId = -1;
     struct celix_bundle_context_bundle_tracker *tracker = calloc(1, sizeof(*tracker));
     if (tracker != NULL) {
@@ -580,7 +582,7 @@ long celix_bundleContext_trackBundles(
         void* callbackHandle,
         void (*onStarted)(void* handle, const bundle_t *bundle),
         void (*onStopped)(void *handle, const bundle_t *bundle)) {
-    celix_bundle_tracker_options_t opts;
+    celix_bundle_tracking_options_t opts;
     memset(&opts, 0, sizeof(opts));
     opts.callbackHandle = callbackHandle;
     opts.onStarted = onStarted;
@@ -739,7 +741,7 @@ bool celix_bundleContext_useServiceWithOptions(
         trkOpts.filter.serviceName = opts->filter.serviceName;
         trkOpts.filter = opts->filter;
         trkOpts.filter.versionRange = opts->filter.versionRange;
-        trkOpts.filter.lang = opts->filter.lang;
+        trkOpts.filter.serviceLanguage = opts->filter.serviceLanguage;
 
         service_tracker_t *trk = celix_serviceTracker_createWithOptions(ctx, &trkOpts);
         if (trk != NULL) {
@@ -770,7 +772,7 @@ void celix_bundleContext_useServicesWithOptions(
         trkOpts.filter.serviceName = opts->filter.serviceName;
         trkOpts.filter.filter = opts->filter.filter;
         trkOpts.filter.versionRange = opts->filter.versionRange;
-        trkOpts.filter.lang = opts->filter.lang;
+        trkOpts.filter.serviceLanguage = opts->filter.serviceLanguage;
 
         service_tracker_t *trk = celix_serviceTracker_createWithOptions(ctx, &trkOpts);
         if (trk != NULL) {

http://git-wip-us.apache.org/repos/asf/celix/blob/03df0edc/framework/src/bundle_context_private.h
----------------------------------------------------------------------
diff --git a/framework/src/bundle_context_private.h b/framework/src/bundle_context_private.h
index 43533f8..fc3077f 100644
--- a/framework/src/bundle_context_private.h
+++ b/framework/src/bundle_context_private.h
@@ -31,12 +31,13 @@
 #include "bundle_context.h"
 #include "celix_log.h"
 #include "bundle_listener.h"
+#include "celix_bundle_context.h"
 
 typedef struct celix_bundle_context_bundle_tracker {
 	bundle_context_t *ctx;
 	long trackId;
 	bundle_listener_t listener;
-	celix_bundle_tracker_options_t opts;
+	celix_bundle_tracking_options_t opts;
 } celix_bundle_context_bundle_tracker_t;
 
 struct bundleContext {

http://git-wip-us.apache.org/repos/asf/celix/blob/03df0edc/framework/src/bundle_private.h
----------------------------------------------------------------------
diff --git a/framework/src/bundle_private.h b/framework/src/bundle_private.h
index 8085609..ea0a06e 100644
--- a/framework/src/bundle_private.h
+++ b/framework/src/bundle_private.h
@@ -16,18 +16,13 @@
  *specific language governing permissions and limitations
  *under the License.
  */
-/*
- * bundle_private.h
- *
- *  \date       Feb 18, 2011
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
+
 
 #ifndef BUNDLE_PRIVATE_H_
 #define BUNDLE_PRIVATE_H_
 
 #include "bundle.h"
+#include "celix_bundle.h"
 
 struct bundle {
 	bundle_context_pt context;

http://git-wip-us.apache.org/repos/asf/celix/blob/03df0edc/framework/src/framework.c
----------------------------------------------------------------------
diff --git a/framework/src/framework.c b/framework/src/framework.c
index 952392c..2460434 100644
--- a/framework/src/framework.c
+++ b/framework/src/framework.c
@@ -41,6 +41,7 @@
 #include "listener_hook_service.h"
 #include "service_registration_private.h"
 #include "bundle_private.h"
+#include "celix_bundle_context.h"
 
 typedef celix_status_t (*create_function_fp)(bundle_context_t *context, void **userData);
 typedef celix_status_t (*start_function_fp)(void *userData, bundle_context_t *context);

http://git-wip-us.apache.org/repos/asf/celix/blob/03df0edc/framework/src/service_tracker.c
----------------------------------------------------------------------
diff --git a/framework/src/service_tracker.c b/framework/src/service_tracker.c
index 56ad199..e718874 100644
--- a/framework/src/service_tracker.c
+++ b/framework/src/service_tracker.c
@@ -30,6 +30,7 @@
 #include "celix_log.h"
 #include "service_tracker_customizer_private.h"
 #include "bundle_context_private.h"
+#include "celix_array_list.h"
 
 static celix_status_t serviceTracker_track(service_tracker_pt tracker, service_reference_pt reference, service_event_pt event);
 static celix_status_t serviceTracker_untrack(service_tracker_pt tracker, service_reference_pt reference, service_event_pt event);
@@ -597,7 +598,7 @@ celix_service_tracker_t* celix_serviceTracker_createWithOptions(
             tracker->currentHighestServiceId = -1;
 
             //setting lang
-            const char *lang = opts->filter.lang;
+            const char *lang = opts->filter.serviceLanguage;
             if (lang == NULL || strncmp("", lang, 1) == 0) {
                 lang = CELIX_FRAMEWORK_SERVICE_C_LANGUAGE;
             }

http://git-wip-us.apache.org/repos/asf/celix/blob/03df0edc/framework/tst/bundle_context_bundles_tests.cpp
----------------------------------------------------------------------
diff --git a/framework/tst/bundle_context_bundles_tests.cpp b/framework/tst/bundle_context_bundles_tests.cpp
index 39fdb6c..d71d748 100644
--- a/framework/tst/bundle_context_bundles_tests.cpp
+++ b/framework/tst/bundle_context_bundles_tests.cpp
@@ -26,9 +26,7 @@
 #include <CppUTest/CommandLineTestRunner.h>
 #include <zconf.h>
 
-#include "bundle.h"
-#include "properties.h"
-#include "celix_framework_factory.h"
+#include "celix_api.h"
 
 
 TEST_GROUP(CelixBundleContextBundlesTests) {

http://git-wip-us.apache.org/repos/asf/celix/blob/03df0edc/framework/tst/bundle_context_services_test.cpp
----------------------------------------------------------------------
diff --git a/framework/tst/bundle_context_services_test.cpp b/framework/tst/bundle_context_services_test.cpp
index 9162212..1302f0a 100644
--- a/framework/tst/bundle_context_services_test.cpp
+++ b/framework/tst/bundle_context_services_test.cpp
@@ -25,9 +25,7 @@
 #include <string.h>
 #include <map>
 
-#include "constants.h"
-#include "bundle.h"
-#include "properties.h"
+#include "celix_api.h"
 #include "celix_framework_factory.h"
 #include "celix_service_factory.h"
 

http://git-wip-us.apache.org/repos/asf/celix/blob/03df0edc/shell/src/dm_shell_list_command.c
----------------------------------------------------------------------
diff --git a/shell/src/dm_shell_list_command.c b/shell/src/dm_shell_list_command.c
index 8a0778f..d2a0dbb 100644
--- a/shell/src/dm_shell_list_command.c
+++ b/shell/src/dm_shell_list_command.c
@@ -20,7 +20,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <shell_constants.h>
-#include "bundle_context.h"
+#include "celix_bundle_context.h"
 #include "dm_dependency_manager.h"
 
 

http://git-wip-us.apache.org/repos/asf/celix/blob/03df0edc/utils/include/array_list.h
----------------------------------------------------------------------
diff --git a/utils/include/array_list.h b/utils/include/array_list.h
index 7003501..bdf9547 100644
--- a/utils/include/array_list.h
+++ b/utils/include/array_list.h
@@ -48,8 +48,6 @@ typedef union celix_array_list_entry {
     size_t sizeVal;
 } celix_array_list_entry_t;
 
-typedef struct celix_arrayList celix_array_list_t;
-
 typedef struct celix_arrayList *array_list_pt;
 typedef struct celix_arrayList array_list_t;
 
@@ -112,56 +110,6 @@ UTILS_EXPORT void *arrayListIterator_previous(array_list_iterator_pt iterator);
 
 UTILS_EXPORT void arrayListIterator_remove(array_list_iterator_pt iterator);
 
-
-
-/**********************************************************************************************************************
- **********************************************************************************************************************
- * Updated API
- **********************************************************************************************************************
- **********************************************************************************************************************/
-
-
-celix_array_list_t* celix_arrayList_create();
-
-celix_array_list_t* celix_arrayList_createWithEquals(celix_arrayList_equals_fp equals);
-
-void celix_arrayList_destroy(celix_array_list_t *list);
-
-size_t celix_arrayList_size(const celix_array_list_t *list);
-
-void* celix_arrayList_get(const celix_array_list_t *list, int index);
-
-//more of the same for the different entry types
-int celix_arrayList_getInt(const celix_array_list_t *list, int index);
-long int celix_arrayList_getLong(const celix_array_list_t *list, int index);
-unsigned int celix_arrayList_getUInt(const celix_array_list_t *list, int index);
-unsigned long int celix_arrayList_getULong(const celix_array_list_t *list, int index);
-float celix_arrayList_getFloat(const celix_array_list_t *list, int index);
-double celix_arrayList_getDouble(const celix_array_list_t *list, int index);
-bool celix_arrayList_getBool(const celix_array_list_t *list, int index);
-size_t celix_arrayList_getSize(const celix_array_list_t *list, int index);
-
-void celix_arrayList_add(celix_array_list_t *list, void* val);
-
-//more of the same for the different entry types
-void celix_arrayList_addInt(celix_array_list_t *list, int val);
-void celix_arrayList_addLong(celix_array_list_t *list, long val);
-void celix_arrayList_addUInt(celix_array_list_t *list, unsigned int val);
-void celix_arrayList_addULong(celix_array_list_t *list, unsigned long val);
-void celix_arrayList_addFloat(celix_array_list_t *list, float val);
-void celix_arrayList_addDouble(celix_array_list_t *list, double val);
-void celix_arrayList_addBool(celix_array_list_t *list, bool val);
-void celix_arrayList_addSize(celix_array_list_t *list, size_t val);
-
-int celix_arrayList_indexOf(celix_array_list_t *list, celix_array_list_entry_t entry);
-void celix_arrayList_remove(celix_array_list_t *list, int index);
-
-/**
- * Remove entry from array list. To use this first memset the entry to null to ensure it completely initialized or
- * ensure that the array list is created with a custom equals which matches the used entry.
- */
-void celix_arrayList_removeEntry(celix_array_list_t *list, celix_array_list_entry_t entry);
-
 #ifdef __cplusplus
 }
 #endif

http://git-wip-us.apache.org/repos/asf/celix/blob/03df0edc/utils/include/celix_array_list.h
----------------------------------------------------------------------
diff --git a/utils/include/celix_array_list.h b/utils/include/celix_array_list.h
new file mode 100644
index 0000000..550004c
--- /dev/null
+++ b/utils/include/celix_array_list.h
@@ -0,0 +1,84 @@
+/**
+ *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 "celixbool.h"
+#include "exports.h"
+#include "celix_errno.h"
+#include "stdbool.h"
+
+#ifndef CELIX_ARRAY_LIST_H_
+#define CELIX_ARRAY_LIST_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**********************************************************************************************************************
+ **********************************************************************************************************************
+ * Updated API
+ **********************************************************************************************************************
+ **********************************************************************************************************************/
+
+typedef struct celix_arrayList celix_array_list_t;
+
+celix_array_list_t* celix_arrayList_create();
+
+celix_array_list_t* celix_arrayList_createWithEquals(celix_arrayList_equals_fp equals);
+
+void celix_arrayList_destroy(celix_array_list_t *list);
+
+size_t celix_arrayList_size(const celix_array_list_t *list);
+
+void* celix_arrayList_get(const celix_array_list_t *list, int index);
+
+//more of the same for the different entry types
+int celix_arrayList_getInt(const celix_array_list_t *list, int index);
+long int celix_arrayList_getLong(const celix_array_list_t *list, int index);
+unsigned int celix_arrayList_getUInt(const celix_array_list_t *list, int index);
+unsigned long int celix_arrayList_getULong(const celix_array_list_t *list, int index);
+float celix_arrayList_getFloat(const celix_array_list_t *list, int index);
+double celix_arrayList_getDouble(const celix_array_list_t *list, int index);
+bool celix_arrayList_getBool(const celix_array_list_t *list, int index);
+size_t celix_arrayList_getSize(const celix_array_list_t *list, int index);
+
+void celix_arrayList_add(celix_array_list_t *list, void* val);
+
+//more of the same for the different entry types
+void celix_arrayList_addInt(celix_array_list_t *list, int val);
+void celix_arrayList_addLong(celix_array_list_t *list, long val);
+void celix_arrayList_addUInt(celix_array_list_t *list, unsigned int val);
+void celix_arrayList_addULong(celix_array_list_t *list, unsigned long val);
+void celix_arrayList_addFloat(celix_array_list_t *list, float val);
+void celix_arrayList_addDouble(celix_array_list_t *list, double val);
+void celix_arrayList_addBool(celix_array_list_t *list, bool val);
+void celix_arrayList_addSize(celix_array_list_t *list, size_t val);
+
+int celix_arrayList_indexOf(celix_array_list_t *list, celix_array_list_entry_t entry);
+void celix_arrayList_remove(celix_array_list_t *list, int index);
+
+/**
+ * Remove entry from array list. To use this first memset the entry to null to ensure it completely initialized or
+ * ensure that the array list is created with a custom equals which matches the used entry.
+ */
+void celix_arrayList_removeEntry(celix_array_list_t *list, celix_array_list_entry_t entry);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* CELIX_ARRAY_LIST_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/03df0edc/utils/include/celix_properties.h
----------------------------------------------------------------------
diff --git a/utils/include/celix_properties.h b/utils/include/celix_properties.h
new file mode 100644
index 0000000..fcb2aec
--- /dev/null
+++ b/utils/include/celix_properties.h
@@ -0,0 +1,78 @@
+/**
+ *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 <stdio.h>
+
+#include "hash_map.h"
+#include "exports.h"
+#include "celix_errno.h"
+
+#ifndef CELIX_PROPERTIES_H_
+#define CELIX_PROPERTIES_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef hash_map_t celix_properties_t;
+
+
+/**********************************************************************************************************************
+ **********************************************************************************************************************
+ * Updated API
+ **********************************************************************************************************************
+ **********************************************************************************************************************/
+ 
+celix_properties_t* celix_properties_create(void);
+
+void celix_properties_destroy(celix_properties_t *properties);
+
+celix_properties_t* celix_properties_load(const char *filename);
+
+celix_properties_t* celix_properties_loadWithStream(FILE *stream);
+
+celix_properties_t* celix_properties_loadFromString(const char *input);
+
+void celix_properties_store(celix_properties_t *properties, const char *file, const char *header);
+
+const char* celix_properties_get(const celix_properties_t *properties, const char *key);
+
+const char* celix_properties_getWithDefault(const celix_properties_t *properties, const char *key, const char *defaultValue);
+
+void celix_properties_set(celix_properties_t *properties, const char *key, const char *value);
+
+void celix_properties_unset(celix_properties_t *properties, const char *key);
+
+celix_properties_t* celix_properties_copy(celix_properties_t *properties);
+
+long celix_properties_getAsLong(const celix_properties_t *props, const char *key, long defaultValue);
+
+void celix_properties_setLong(celix_properties_t *props, const char *key, long value);
+
+#define CELIX_PROPERTIES_FOR_EACH(props, key) \
+    for(hash_map_iterator_t iter = hashMapIterator_construct(props); \
+        hashMapIterator_hasNext(&iter), (key) = (const char*)hashMapIterator_nextKey(&iter);)
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CELIX_PROPERTIES_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/03df0edc/utils/include/properties.h
----------------------------------------------------------------------
diff --git a/utils/include/properties.h b/utils/include/properties.h
index 5a19cb7..0efe0c4 100644
--- a/utils/include/properties.h
+++ b/utils/include/properties.h
@@ -38,8 +38,6 @@ extern "C" {
 typedef hash_map_pt properties_pt;
 typedef hash_map_t properties_t;
 
-typedef hash_map_t celix_properties_t;
-
 UTILS_EXPORT properties_pt properties_create(void);
 
 UTILS_EXPORT void properties_destroy(properties_pt properties);
@@ -67,44 +65,6 @@ UTILS_EXPORT celix_status_t properties_copy(properties_pt properties, properties
         hashMapIterator_hasNext(&iter), (key) = (const char*)hashMapIterator_nextKey(&iter);)
 
 
-/**********************************************************************************************************************
- **********************************************************************************************************************
- * Updated API
- **********************************************************************************************************************
- **********************************************************************************************************************/
- 
-celix_properties_t* celix_properties_create(void);
-
-void celix_properties_destroy(celix_properties_t *properties);
-
-celix_properties_t* celix_properties_load(const char *filename);
-
-celix_properties_t* celix_properties_loadWithStream(FILE *stream);
-
-celix_properties_t* celix_properties_loadFromString(const char *input);
-
-void celix_properties_store(celix_properties_t *properties, const char *file, const char *header);
-
-const char* celix_properties_get(const celix_properties_t *properties, const char *key);
-
-const char* celix_properties_getWithDefault(const celix_properties_t *properties, const char *key, const char *defaultValue);
-
-void celix_properties_set(celix_properties_t *properties, const char *key, const char *value);
-
-void celix_properties_unset(celix_properties_t *properties, const char *key);
-
-celix_properties_t* celix_properties_copy(celix_properties_t *properties);
-
-long celix_properties_getAsLong(const celix_properties_t *props, const char *key, long defaultValue);
-
-void celix_properties_setLong(celix_properties_t *props, const char *key, long value);
-
-#define CELIX_PROPERTIES_FOR_EACH(props, key) \
-    for(hash_map_iterator_t iter = hashMapIterator_construct(props); \
-        hashMapIterator_hasNext(&iter), (key) = (const char*)hashMapIterator_nextKey(&iter);)
-
-
-
 #ifdef __cplusplus
 }
 #endif

http://git-wip-us.apache.org/repos/asf/celix/blob/03df0edc/utils/src/array_list.c
----------------------------------------------------------------------
diff --git a/utils/src/array_list.c b/utils/src/array_list.c
index 6a48c7a..e66a3c8 100644
--- a/utils/src/array_list.c
+++ b/utils/src/array_list.c
@@ -28,6 +28,7 @@
 #include <string.h>
 
 #include "array_list.h"
+#include "celix_array_list.h"
 #include "array_list_private.h"
 
 static celix_status_t arrayList_elementEquals(const void *a, const void *b, bool *equals);

http://git-wip-us.apache.org/repos/asf/celix/blob/03df0edc/utils/src/properties.c
----------------------------------------------------------------------
diff --git a/utils/src/properties.c b/utils/src/properties.c
index 5af5646..c8b59a2 100644
--- a/utils/src/properties.c
+++ b/utils/src/properties.c
@@ -29,6 +29,7 @@
 #include <ctype.h>
 #include "celixbool.h"
 #include "properties.h"
+#include "celix_properties.h"
 #include "utils.h"
 
 #define MALLOC_BLOCK_SIZE		5


[03/12] celix git commit: CELIX-446: Removes the clang block example, does not work as expected

Posted by pn...@apache.org.
CELIX-446: Removes the clang block example, does not work as expected


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

Branch: refs/heads/feature/CELIX-426-cxx-api
Commit: a4a1f5000f0f66683923fdf9dec7ca1a5c97e09f
Parents: 5872268
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Thu May 10 16:03:42 2018 +0200
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Thu May 10 16:03:42 2018 +0200

----------------------------------------------------------------------
 .../services_example_c/CMakeLists.txt           |  6 +-
 .../services_example_c/src/consumer_example.c   | 60 ++++++++++----------
 framework/include/bundle_context.h              | 10 ++++
 3 files changed, 46 insertions(+), 30 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/a4a1f500/examples/celix-examples/services_example_c/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/examples/celix-examples/services_example_c/CMakeLists.txt b/examples/celix-examples/services_example_c/CMakeLists.txt
index 6f7913b..f56ddd8 100644
--- a/examples/celix-examples/services_example_c/CMakeLists.txt
+++ b/examples/celix-examples/services_example_c/CMakeLists.txt
@@ -31,10 +31,14 @@ add_celix_bundle(consumer_example
         )
 target_link_libraries(consumer_example PRIVATE services_example_c_api)
 
+if ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")
+  target_compile_definitions(consumer_example PRIVATE USE_NESTED_FUNCTION_EXAMPLE)
+endif()
+
 add_celix_container(services_example_c
     BUNDLES
         Celix::shell
         Celix::shell_tui
         provider_example
         consumer_example
-)
\ No newline at end of file
+)

http://git-wip-us.apache.org/repos/asf/celix/blob/a4a1f500/examples/celix-examples/services_example_c/src/consumer_example.c
----------------------------------------------------------------------
diff --git a/examples/celix-examples/services_example_c/src/consumer_example.c b/examples/celix-examples/services_example_c/src/consumer_example.c
index c472662..899cb57 100644
--- a/examples/celix-examples/services_example_c/src/consumer_example.c
+++ b/examples/celix-examples/services_example_c/src/consumer_example.c
@@ -27,12 +27,12 @@
 #include "bundle_activator.h"
 
 typedef struct activator_data {
-    int trackCount;
     celix_bundle_context_t *ctx;
     pthread_t thread;
 
     pthread_mutex_t mutex; //protects running
     bool running;
+    int trackCount;
 } activator_data_t;
 
 static bool isRunning(activator_data_t *data) {
@@ -62,7 +62,7 @@ static void useCalc(void *handle, void *svc) {
 }
 
 static void gccExample(activator_data_t *data) {
-#ifdef __GNUC__
+#ifdef USE_NESTED_FUNCTION_EXAMPLE
 
     int result = 0;
     long rank = 0;
@@ -88,41 +88,33 @@ static void gccExample(activator_data_t *data) {
 #endif
 }
 
-static void clangExample(activator_data_t *data) {
-#ifdef __clang__
-    /*TODO
-#include <Block.h>
-    __block result = 0;
-    __block rank = 0;
-    __block svcId = 0;
-
-    void (^use)(void *handle, void *svc, const celix_properties_t *props)  =  ^(void *handle, void *svc, const celix_properties_t *props) {
-        example_calc_t *calc = svc;
-        rank = celix_properties_getAsLong(props, OSGI_FRAMEWORK_SERVICE_RANKING, -1L);
-        svcId = celix_properties_getAsLong(props, OSGI_FRAMEWORK_SERVICE_ID, -1L);
-        result = calc->calc(calc->handle, 1);
-    };
-
-    celix_service_use_options_t opts;
-    memset(&opts, 0, sizeof(opts));
+static void addSvc(activator_data_t *data, void *svc __attribute__((unused))) {
+    pthread_mutex_lock(&data->mutex);
+    data->trackCount += 1;
+    pthread_mutex_unlock(&data->mutex);
+}
 
-    opts.serviceName = EXAMPLE_CALC_NAME;
-    opts.callbackHandle = NULL; //can be null for trampolines
-    opts.useWithProperties = use;
-    bool called = celix_bundleContext_useServiceWithOptions(data->ctx, &opts);
+static void removeSvc(activator_data_t *data, void *svc __attribute__((unused))) {
+    pthread_mutex_lock(&data->mutex);
+    data->trackCount -= 1;
+    pthread_mutex_unlock(&data->mutex);
+}
 
-    printf("Called func %s. Result is %i, rank is %li and svc id is %li\n", called ? "called" : "not called", result, rank, svcId);
-     */
-#endif
+static void useHighest(activator_data_t *data __attribute__((unused)), example_calc_t *svc, const celix_properties_t *props) {
+    int result = svc->calc(svc->handle, 2);
+    long svcId = celix_properties_getAsLong(props, OSGI_FRAMEWORK_SERVICE_ID, -1L);
+    long rank = celix_properties_getAsLong(props, OSGI_FRAMEWORK_SERVICE_RANKING, -1L);
+    printf("Called highest ranking service. Result is %i, svc id is %li, svc ranking is %li\n", result, svcId, rank);
 }
 
+
 void * run(void *handle) {
     activator_data_t *data = handle;
 
     printf("starting consumer thread\n");
+    long trkId = celix_bundleContext_trackServices(data->ctx, EXAMPLE_CALC_NAME, data, (void*)addSvc, (void*)removeSvc);
 
     while (isRunning(data)) {
-
         struct info info;
         info.result = 0;
         info.count = 0;
@@ -131,13 +123,23 @@ void * run(void *handle) {
 
         gccExample(data); //gcc trampolines example (nested functions)
 
-        clangExample(data); //TODO use clang blocks
+        celix_service_use_options_t opts;
+        memset(&opts, 0, sizeof(opts));
+
+        opts.serviceName = EXAMPLE_CALC_NAME;
+        opts.callbackHandle = data;
+        opts.useWithProperties = (void*)useHighest;
+        celix_bundleContext_useServiceWithOptions(data->ctx, &opts);
 
-        //TODO tracker example
+        pthread_mutex_lock(&data->mutex);
+        int count = data->trackCount;
+        pthread_mutex_unlock(&data->mutex);
+        printf("Current tracking count is %i\n", count);
 
         sleep(5);
     }
 
+    celix_bundleContext_stopTracker(data->ctx, trkId);
     printf("exiting consumer thread\n");
 
     pthread_exit(NULL);

http://git-wip-us.apache.org/repos/asf/celix/blob/a4a1f500/framework/include/bundle_context.h
----------------------------------------------------------------------
diff --git a/framework/include/bundle_context.h b/framework/include/bundle_context.h
index 5ab777a..ec974fa 100644
--- a/framework/include/bundle_context.h
+++ b/framework/include/bundle_context.h
@@ -230,6 +230,16 @@ long celix_bundleContext_registerServiceForLang(celix_bundle_context_t *ctx, con
  */
 void celix_bundleContext_unregisterService(celix_bundle_context_t *ctx, long serviceId);
 
+
+//TODO 
+//typedef struct celix_service_find_filter_options {
+// servicname, versionrange, filter, lang
+//} celix_service_find_filter_options_t;
+//celix_array_list_t* celix_bundleContext_findServices(celix_bundle_context_t *ctx, const char *serviceName);
+//celix_array_list_t* celix_bundleContext_findServices(celix_bundle_context_t *ctx, const char *serviceName);
+//alts WithOptions
+
+
 /**
  * track service for the provided serviceName and/or filter.
  * The highest ranking services will used for the callback.