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 2020/02/04 20:04:14 UTC

[celix] 01/01: gh-145: Refactors multi threading bundle handling in the framework.

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

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

commit bd33f7c5a8309ee7602f5036f5a25ab1a1341085
Author: Pepijn Noltes <pe...@gmail.com>
AuthorDate: Tue Feb 4 21:01:32 2020 +0100

    gh-145: Refactors multi threading bundle handling in the framework.
    
    Trying to improve the multi threading handling of bundles.
    There was an issue than uninstall bunles failed, because of incorrect
    list, mutex & cond handling.
    Note, that there is still a lot that can and _needs_ to be improvded.
---
 libs/framework/include/celix_bundle_context.h      |  10 +-
 libs/framework/private/mock/framework_mock.c       |  16 +-
 .../framework/private/test/bundle_context_test.cpp |  10 +-
 libs/framework/private/test/bundle_test.cpp        |  12 +-
 libs/framework/src/bundle.c                        |   6 +-
 libs/framework/src/bundle_context.c                |  84 +++-
 libs/framework/src/framework.c                     | 509 ++++++++++-----------
 libs/framework/src/framework_private.h             |   8 +-
 .../framework/tst/bundle_context_bundles_tests.cpp |  67 ++-
 libs/framework/tst/run_tests.cpp                   |   1 +
 10 files changed, 398 insertions(+), 325 deletions(-)

diff --git a/libs/framework/include/celix_bundle_context.h b/libs/framework/include/celix_bundle_context.h
index 18c44c0..ab4b827 100644
--- a/libs/framework/include/celix_bundle_context.h
+++ b/libs/framework/include/celix_bundle_context.h
@@ -586,13 +586,21 @@ void celix_bundleContext_useServicesWithOptions(
 celix_array_list_t* celix_bundleContext_listBundles(celix_bundle_context_t *ctx);
 
 /**
- * Check if whether a bundle is installed.
+ * Check whether a bundle is installed.
  * @param ctx       The bundle context.
  * @param bndId     The bundle id to check
  * @return          true if the bundle is installed.
  */
 bool celix_bundleContext_isBundleInstalled(celix_bundle_context_t *ctx, long bndId);
 
+/**
+ * Check whether the bundle is active.
+ * @param ctx       The bundle context.
+ * @param bndId     The bundle id to check
+ * @return          true if the bundle is installed and active.
+ */
+bool celix_bundleContext_isBundleActive(celix_bundle_context_t *ctx, long bndId);
+
 
 /**
  * Install and optional start a bundle.
diff --git a/libs/framework/private/mock/framework_mock.c b/libs/framework/private/mock/framework_mock.c
index 2734934..1f32931 100644
--- a/libs/framework/private/mock/framework_mock.c
+++ b/libs/framework/private/mock/framework_mock.c
@@ -89,10 +89,10 @@ celix_status_t framework_getBundleEntry(framework_pt framework, const_bundle_pt
 }
 
 
-celix_status_t fw_startBundle(framework_pt framework, bundle_pt bundle, int options) {
+celix_status_t fw_startBundle(framework_pt framework, long bundle, int options) {
 	mock_c()->actualCall("fw_startBundle")
 		->withPointerParameters("framework", framework)
-		->withPointerParameters("bundle", bundle)
+		->withLongIntParameters("bundle", bundle)
 		->withIntParameters("options", options);
 	return mock_c()->returnValue().value.intValue;
 }
@@ -105,19 +105,19 @@ celix_status_t framework_updateBundle(framework_pt framework, bundle_pt bundle,
 	return mock_c()->returnValue().value.intValue;
 }
 
-celix_status_t fw_stopBundle(framework_pt framework, bundle_pt bundle, bool record) {
+celix_status_t fw_stopBundle(framework_pt framework, long bundle, bool record) {
 	mock_c()->actualCall("fw_stopBundle")
 		->withPointerParameters("framework", framework)
-		->withPointerParameters("bundle", bundle)
+		->withLongIntParameters("bundle", bundle)
 		->withIntParameters("record", record);
 	return mock_c()->returnValue().value.intValue;
 }
 
 
-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 fw_registerService(framework_pt framework, service_registration_pt * registration, long bundle, const char* serviceName, const void* svcObj, properties_pt properties) {
 	mock_c()->actualCall("fw_registerService")
 		->withPointerParameters("framework", framework)
-		->withPointerParameters("bundle", bundle)
+		->withLongIntParameters("bundle", bundle)
 		->withStringParameters("serviceName", serviceName)
 		->withPointerParameters("service", (void*) svcObj)
 		->withPointerParameters("properties", properties)
@@ -125,10 +125,10 @@ celix_status_t fw_registerService(framework_pt framework, service_registration_p
 		return mock_c()->returnValue().value.intValue;
 }
 
-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 fw_registerServiceFactory(framework_pt framework, service_registration_pt * registration, long bundle, const char* serviceName, service_factory_pt factory, properties_pt properties) {
 	mock_c()->actualCall("fw_registerServiceFactory")
 		->withPointerParameters("framework", framework)
-		->withPointerParameters("bundle", bundle)
+		->withLongIntParameters("bundle", bundle)
 		->withStringParameters("serviceName", serviceName)
 		->withPointerParameters("serviceFactory", factory)
 		->withPointerParameters("properties", properties)
diff --git a/libs/framework/private/test/bundle_context_test.cpp b/libs/framework/private/test/bundle_context_test.cpp
index c8d0c0b..659bbbe 100644
--- a/libs/framework/private/test/bundle_context_test.cpp
+++ b/libs/framework/private/test/bundle_context_test.cpp
@@ -181,9 +181,11 @@ TEST(bundle_context, registerService) {
 	properties_pt properties = (properties_pt) 0x50;
 	service_registration_pt registration = (service_registration_pt) 0x60;
 
-	mock().expectOneCall("fw_registerService")
+    mock().expectOneCall("celix_bundle_getId").withConstPointerParameter("bnd", bundle);
+
+    mock().expectOneCall("fw_registerService")
 		.withParameter("framework", framework)
-		.withParameter("bundle", bundle)
+		.withParameter("bundle", 0)
 		.withParameter("serviceName", serviceName)
 		.withParameter("service", service)
 		.withParameter("properties", properties)
@@ -216,9 +218,11 @@ TEST(bundle_context, registerServiceFactory) {
 	properties_pt properties = (properties_pt) 0x50;
 	service_registration_pt registration = (service_registration_pt) 0x60;
 
+	mock().expectOneCall("celix_bundle_getId").withConstPointerParameter("bnd", bundle);
+
 	mock().expectOneCall("fw_registerServiceFactory")
 		.withParameter("framework", framework)
-		.withParameter("bundle", bundle)
+		.withParameter("bundle", 0)
 		.withParameter("serviceName", serviceName)
 		.withParameter("serviceFactory", serviceFactory)
 		.withParameter("properties", properties)
diff --git a/libs/framework/private/test/bundle_test.cpp b/libs/framework/private/test/bundle_test.cpp
index 04650b2..dcaf38f 100644
--- a/libs/framework/private/test/bundle_test.cpp
+++ b/libs/framework/private/test/bundle_test.cpp
@@ -465,14 +465,14 @@ TEST(bundle, start) {
 	int options = 42;
 
 	long id = 1;
-	mock().expectNCalls(2, "bundleArchive_getId")
+	mock().expectNCalls(4, "bundleArchive_getId")
         				.withParameter("archive", archive)
         				.withOutputParameterReturning("id", &id, sizeof(id))
         				.andReturnValue(CELIX_SUCCESS);
 
 	mock().expectOneCall("fw_startBundle")
 						.withParameter("framework", framework)
-						.withParameter("bundle", bundle)
+						.withParameter("bundle", 1)
 						.withParameter("options", options)
 						.andReturnValue(CELIX_SUCCESS);
 
@@ -481,7 +481,7 @@ TEST(bundle, start) {
 
 	mock().expectOneCall("fw_startBundle")
 						.withParameter("framework", framework)
-						.withParameter("bundle", bundle)
+						.withParameter("bundle", 1)
 						.withParameter("options", 0)
 						.andReturnValue(CELIX_SUCCESS);
 
@@ -525,7 +525,7 @@ TEST(bundle, stop) {
 	bundle->archive = archive;
 
 	long id = 1;
-	mock().expectNCalls(2, "bundleArchive_getId")
+	mock().expectNCalls(4, "bundleArchive_getId")
 	        				.withParameter("archive", archive)
 	        				.withOutputParameterReturning("id", &id, sizeof(id))
 	        				.andReturnValue(CELIX_SUCCESS);
@@ -533,7 +533,7 @@ TEST(bundle, stop) {
 	int options = 1;
 	mock().expectOneCall("fw_stopBundle")
 						.withParameter("framework", framework)
-						.withParameter("bundle", bundle)
+						.withParameter("bundle", id)
 						.withParameter("record", 1)
 						.andReturnValue(CELIX_SUCCESS);
 
@@ -542,7 +542,7 @@ TEST(bundle, stop) {
 
 	mock().expectOneCall("fw_stopBundle")
 						.withParameter("framework", framework)
-						.withParameter("bundle", bundle)
+						.withParameter("bundle", id)
 						.withParameter("record", 0)
 						.andReturnValue(CELIX_SUCCESS);
 
diff --git a/libs/framework/src/bundle.c b/libs/framework/src/bundle.c
index 251941e..61c97dd 100644
--- a/libs/framework/src/bundle.c
+++ b/libs/framework/src/bundle.c
@@ -257,7 +257,8 @@ celix_status_t bundle_startWithOptions(bundle_pt bundle, int options) {
     		if (systemBundle) {
     			framework_start(bundle->framework);
     		} else {
-    			status = fw_startBundle(bundle->framework, bundle, options);
+    		    long bndId = celix_bundle_getId(bundle);
+    			status = fw_startBundle(bundle->framework, bndId, options);
     		}
     	}
     }
@@ -299,7 +300,8 @@ celix_status_t bundle_stopWithOptions(bundle_pt bundle, int options) {
 			if (systemBundle) {
 				framework_stop(bundle->framework);
 			} else {
-				status = fw_stopBundle(bundle->framework, bundle, options);
+                long bndId = celix_bundle_getId(bundle);
+				status = fw_stopBundle(bundle->framework, bndId, options);
 			}
 		}
 	}
diff --git a/libs/framework/src/bundle_context.c b/libs/framework/src/bundle_context.c
index 430781c..11cb39a 100644
--- a/libs/framework/src/bundle_context.c
+++ b/libs/framework/src/bundle_context.c
@@ -163,7 +163,8 @@ celix_status_t bundleContext_registerService(bundle_context_pt context, const ch
 	celix_status_t status = CELIX_SUCCESS;
 
 	if (context != NULL) {
-	    fw_registerService(context->framework, &registration, context->bundle, serviceName, svcObj, properties);
+	    long bndId = celix_bundle_getId(context->bundle);
+	    fw_registerService(context->framework, &registration, bndId, serviceName, svcObj, properties);
 	    *service_registration = registration;
 	} else {
 	    status = CELIX_ILLEGAL_ARGUMENT;
@@ -180,7 +181,8 @@ celix_status_t bundleContext_registerServiceFactory(bundle_context_pt context, c
     celix_status_t status = CELIX_SUCCESS;
 
     if (context != NULL && *service_registration == NULL) {
-        fw_registerServiceFactory(context->framework, &registration, context->bundle, serviceName, factory, properties);
+        long bndId = celix_bundle_getId(context->bundle);
+        fw_registerServiceFactory(context->framework, &registration, bndId, serviceName, factory, properties);
         *service_registration = registration;
     } else {
         status = CELIX_ILLEGAL_ARGUMENT;
@@ -717,6 +719,17 @@ bool celix_bundleContext_isBundleInstalled(celix_bundle_context_t *ctx, long bnd
     return bnd != NULL;
 }
 
+static void celix_bundleContext_isBundleActiveCallback(void *handle, const celix_bundle_t *bnd) {
+    bool *active = handle;
+    *active = celix_bundle_getState(bnd) == OSGI_FRAMEWORK_BUNDLE_ACTIVE;
+}
+
+bool celix_bundleContext_isBundleActive(celix_bundle_context_t *ctx, long bndId) {
+    bool active = false;
+    celix_bundleContext_useBundle(ctx, bndId, &active, celix_bundleContext_isBundleActiveCallback);
+    return active;
+}
+
 static void bundleContext_startBundleCallback(void *handle, const bundle_t *c_bnd) {
     bool *started = handle;
     *started = false;
@@ -752,20 +765,67 @@ bool celix_bundleContext_stopBundle(celix_bundle_context_t *ctx, long bundleId)
     return stopped;
 }
 
-static void bundleContext_uninstallBundleCallback(void *handle, const bundle_t *c_bnd) {
-    bool *uninstalled = handle;
-    bundle_t *bnd = (bundle_t*)c_bnd;
-    if (celix_bundle_getState(bnd) == OSGI_FRAMEWORK_BUNDLE_ACTIVE) {
-        bundle_stop(bnd);
+struct celix_bundleContext_uninstallBundleCalllback_data {
+    bool threadCreated;
+    const celix_bundle_t *bnd;
+    celix_thread_t uninstallthread; //thread for uninstall
+    celix_thread_mutex_t  mutex; //protects below
+    celix_thread_cond_t cond;
+    bool uninstallCalled;
+    bool uninstalled;
+
+};
+
+static void* celix_bundleContext_uninstallBundleUninstallThread(void *handle) {
+    struct celix_bundleContext_uninstallBundleCalllback_data *data = handle;
+    celix_status_t status = bundle_uninstall((celix_bundle_t*)data->bnd);
+    celixThreadMutex_lock(&data->mutex);
+    data->uninstallCalled = true;
+    data->uninstalled = status == CELIX_SUCCESS;
+    celixThreadCondition_broadcast(&data->cond);
+    celixThreadMutex_unlock(&data->mutex);
+    return NULL;
+}
+
+static void celix_bundleContext_uninstallBundleCallback(void *handle, const celix_bundle_t *bnd) {
+    struct celix_bundleContext_uninstallBundleCalllback_data *data = handle;
+    celix_bundle_state_e bndState = celix_bundle_getState(bnd);
+    if (bndState == OSGI_FRAMEWORK_BUNDLE_ACTIVE) {
+        bundle_stop((celix_bundle_t*)bnd);
+    }
+    bndState = celix_bundle_getState(bnd);
+    if (bndState == OSGI_FRAMEWORK_BUNDLE_RESOLVED || bndState == OSGI_FRAMEWORK_BUNDLE_INSTALLED) {
+        data->bnd = bnd;
+        data->threadCreated = true;
+        celixThread_create(&data->uninstallthread, NULL, celix_bundleContext_uninstallBundleUninstallThread, data);
     }
-    bundle_uninstall(bnd);
-    *uninstalled = true;
 }
 
 bool celix_bundleContext_uninstallBundle(bundle_context_t *ctx, long bundleId) {
-    bool uninstalled = false;
-    celix_framework_useBundle(ctx->framework, true, bundleId, &uninstalled, bundleContext_uninstallBundleCallback);
-    return uninstalled;
+    bool result = false;
+    struct celix_bundleContext_uninstallBundleCalllback_data data;
+    data.threadCreated = false;
+    data.uninstalled = false;
+    data.uninstallCalled = false;
+    celixThreadMutex_create(&data.mutex, NULL);
+    celixThreadCondition_init(&data.cond, NULL);
+
+    bool called = celix_framework_useBundle(ctx->framework, false, bundleId, &data, celix_bundleContext_uninstallBundleCallback);
+    if (called && data.threadCreated) {
+        celixThreadMutex_lock(&data.mutex);
+        while (!data.uninstallCalled) {
+            celixThreadCondition_wait(&data.cond, &data.mutex);
+        }
+        celixThreadMutex_unlock(&data.mutex);
+        celixThread_join(data.uninstallthread, NULL);
+        celixThreadMutex_lock(&data.mutex);
+        result = data.uninstalled;
+        celixThreadMutex_unlock(&data.mutex);
+    }
+
+    celixThreadMutex_destroy(&data.mutex);
+    celixThreadCondition_destroy(&data.cond);
+    return result;
 }
 
 bool celix_bundleContext_useServiceWithId(
diff --git a/libs/framework/src/framework.c b/libs/framework/src/framework.c
index 0d586ec..eb5b715 100644
--- a/libs/framework/src/framework.c
+++ b/libs/framework/src/framework.c
@@ -97,60 +97,36 @@ static inline void fw_bundleEntry_destroy(celix_framework_bundle_entry_t *entry,
     free(entry);
 }
 
+static inline void fw_bundleEntry_increaseUseCount(celix_framework_bundle_entry_t *entry) {
+    //pre condition mutex is taken on  fw->installedBundles.mutex
+    assert(entry != NULL);
+    celixThreadMutex_lock(&entry->useMutex);
+    ++entry->useCount;
+    celixThreadMutex_unlock(&entry->useMutex);
+}
 
-static inline void fw_bundleEntry_increaseUseCount(framework_t *fw, long bndId) {
-    assert(bndId >= 0);
-    if (bndId > 0) { //note not in/decreasing framework bundle use count, to prevent that the framework is waiting on it self
-        celixThreadMutex_lock(&fw->installedBundles.mutex);
-        int size = celix_arrayList_size(fw->installedBundles.entries);
-        for (int i = 0; i < size; ++i) {
-            celix_framework_bundle_entry_t *entry = celix_arrayList_get(fw->installedBundles.entries, i);
-            if (entry != NULL && entry->bndId == bndId) {
-                celixThreadMutex_lock(&entry->useMutex);
-                entry->useCount += 1;
-                celixThreadMutex_unlock(&entry->useMutex);
-            }
-        }
-        celixThreadMutex_unlock(&fw->installedBundles.mutex);
-    }
+static inline void fw_bundleEntry_decreaseUseCount(celix_framework_bundle_entry_t *entry) {
+    //pre condition mutex is taken on  fw->installedBundles.mutex
+    celixThreadMutex_lock(&entry->useMutex);
+    assert(entry->useCount > 0);
+    --entry->useCount;
+    celixThreadCondition_broadcast(&entry->useCond);
+    celixThreadMutex_unlock(&entry->useMutex);
 }
 
-/*
-static inline size_t fw_bundleEntry_getUseCount(framework_t *fw, long bndId) {
-    size_t count = 0;
+static inline celix_framework_bundle_entry_t* fw_bundleEntry_getBundleEntryAndIncreaseUseCount(celix_framework_t *fw, long bndId) {
+    celix_framework_bundle_entry_t* found = NULL;
     celixThreadMutex_lock(&fw->installedBundles.mutex);
-    int size = celix_arrayList_size(fw->installedBundles.entries);
-    for (int i = 0; i < size; ++i) {
+    for (int i = 0; i < celix_arrayList_size(fw->installedBundles.entries); ++i) {
         celix_framework_bundle_entry_t *entry = celix_arrayList_get(fw->installedBundles.entries, i);
-        if (entry != NULL && entry->bndId == bndId) {
-            celixThreadMutex_lock(&entry->useMutex);
-            count = entry->useCount;
-            celixThreadMutex_unlock(&entry->useMutex);
+        if (entry->bndId == bndId) {
+            fw_bundleEntry_increaseUseCount(entry);
+            found = entry;
+            break;
         }
     }
     celixThreadMutex_unlock(&fw->installedBundles.mutex);
-    return count;
-}*/
-
-static inline void fw_bundleEntry_decreaseUseCount(framework_t *fw, long bndId) {
-    assert(bndId >= 0);
-    if (bndId > 0) { //note not in/decreasing framework bundle use count, to prevent that the framework is waiting on it self
-        celixThreadMutex_lock(&fw->installedBundles.mutex);
-        int size = celix_arrayList_size(fw->installedBundles.entries);
-        for (int i = 0; i < size; ++i) {
-            celix_framework_bundle_entry_t *entry = celix_arrayList_get(fw->installedBundles.entries, i);
-            if (entry != NULL && entry->bndId == bndId) {
-                celixThreadMutex_lock(&entry->useMutex);
-                assert(entry->useCount > 0);
-                entry->useCount -= 1;
-                if (entry->useCount == 0) {
-                    celixThreadCondition_broadcast(&entry->useCond);
-                }
-                celixThreadMutex_unlock(&entry->useMutex);
-            }
-        }
-        celixThreadMutex_unlock(&fw->installedBundles.mutex);
-    }
+    return found;
 }
 
 celix_status_t framework_setBundleStateAndNotify(framework_pt framework, bundle_pt bundle, int state);
@@ -160,8 +136,8 @@ long framework_getNextBundleId(framework_pt framework);
 
 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 fw_refreshBundles(framework_pt framework, bundle_pt bundles[], int size);
-celix_status_t fw_refreshBundle(framework_pt framework, bundle_pt bundle);
+celix_status_t fw_refreshBundles(framework_pt framework, long bundleIds[], int size);
+celix_status_t fw_refreshBundle(framework_pt framework, long bndId);
 
 celix_status_t fw_populateDependentGraph(framework_pt framework, bundle_pt exporter, hash_map_pt *map);
 
@@ -267,15 +243,13 @@ static inline void listener_release(celix_fw_service_listener_entry_t *entry) {
     celixThreadMutex_lock(&entry->mutex);
     assert(entry->useCount > 0);
     entry->useCount -= 1;
-    if (entry->useCount == 0) {
-        celixThreadCondition_broadcast(&entry->useCond);
-    }
+    celixThreadCondition_broadcast(&entry->useCond);
     celixThreadMutex_unlock(&entry->mutex);
 }
 
 static inline void listener_waitAndDestroy(celix_framework_t *framework, celix_fw_service_listener_entry_t *entry) {
     celixThreadMutex_lock(&entry->mutex);
-    while(entry->useCount != 0) {
+    while (entry->useCount != 0) {
         celixThreadCondition_wait(&entry->useCond, &entry->mutex);
     }
     celixThreadMutex_unlock(&entry->mutex);
@@ -698,7 +672,7 @@ static void framework_autoStartConfiguredBundlesForList(bundle_context_t *fwCtx,
 
 
 celix_status_t framework_stop(framework_pt framework) {
-	return fw_stopBundle(framework, framework->bundle, true);
+	return fw_stopBundle(framework, framework->bundleId, true);
 }
 
 celix_status_t fw_getProperty(framework_pt framework, const char* name, const char* defaultValue, const char** out) {
@@ -775,7 +749,7 @@ celix_status_t fw_installBundle2(framework_pt framework, bundle_pt * bundle, lon
     }
 
     //increase use count of framework bundle to prevent a stop.
-    fw_bundleEntry_increaseUseCount(framework, framework->bundleId);
+    celix_framework_bundle_entry_t *entry = fw_bundleEntry_getBundleEntryAndIncreaseUseCount(framework, framework->bundleId);
 
   	status = CELIX_DO_IF(status, bundle_getState(framework->bundle, &state));
   	if (status == CELIX_SUCCESS) {
@@ -788,7 +762,7 @@ celix_status_t fw_installBundle2(framework_pt framework, bundle_pt * bundle, lon
     if (status == CELIX_SUCCESS) {
         *bundle = framework_getBundle(framework, location);
         if (*bundle != NULL) {
-            fw_bundleEntry_decreaseUseCount(framework, framework->bundleId);
+            fw_bundleEntry_decreaseUseCount(entry);
             free(location);
             return CELIX_SUCCESS;
         }
@@ -824,7 +798,7 @@ celix_status_t fw_installBundle2(framework_pt framework, bundle_pt * bundle, lon
         }
     }
 
-    fw_bundleEntry_decreaseUseCount(framework, framework->bundleId);
+    fw_bundleEntry_decreaseUseCount(entry);
 
     if (status != CELIX_SUCCESS) {
     	fw_logCode(framework->logger, OSGI_FRAMEWORK_LOG_ERROR, status, "Could not install bundle");
@@ -867,7 +841,7 @@ celix_status_t framework_getBundleEntry(framework_pt framework, const_bundle_pt
 	return status;
 }
 
-celix_status_t fw_startBundle(framework_pt framework, bundle_pt bundle, int options __attribute__((unused))) {
+celix_status_t fw_startBundle(framework_pt framework, long bndId, int options __attribute__((unused))) {
 	celix_status_t status = CELIX_SUCCESS;
 
 	linked_list_pt wires = NULL;
@@ -878,10 +852,11 @@ celix_status_t fw_startBundle(framework_pt framework, bundle_pt bundle, int opti
 	char *error = NULL;
 	const char *name = NULL;
 
-	long bndId = celix_bundle_getId(bundle);
-    fw_bundleEntry_increaseUseCount(framework, bndId);
+    celix_framework_bundle_entry_t *entry = fw_bundleEntry_getBundleEntryAndIncreaseUseCount(framework, bndId);
+
+    status = entry->bnd != NULL ? CELIX_SUCCESS : CELIX_ILLEGAL_ARGUMENT;
 
-	status = CELIX_DO_IF(status, bundle_getState(bundle, &state));
+	status = CELIX_DO_IF(status, bundle_getState(entry->bnd, &state));
 
 	if (status == CELIX_SUCCESS) {
 	    switch (state) {
@@ -904,7 +879,7 @@ celix_status_t fw_startBundle(framework_pt framework, bundle_pt bundle, int opti
             case OSGI_FRAMEWORK_BUNDLE_ACTIVE:
                 break;
             case OSGI_FRAMEWORK_BUNDLE_INSTALLED:
-                bundle_getCurrentModule(bundle, &module);
+                bundle_getCurrentModule(entry->bnd, &module);
                 module_getSymbolicName(module, &name);
                 if (!module_isResolved(module)) {
                     wires = resolver_resolve(module);
@@ -920,10 +895,10 @@ celix_status_t fw_startBundle(framework_pt framework, bundle_pt bundle, int opti
             case OSGI_FRAMEWORK_BUNDLE_RESOLVED:
                 module = NULL;
                 name = NULL;
-                bundle_getCurrentModule(bundle, &module);
+                bundle_getCurrentModule(entry->bnd, &module);
                 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));
+                status = CELIX_DO_IF(status, bundleContext_create(framework, framework->logger, entry->bnd, &context));
+                status = CELIX_DO_IF(status, bundle_setContext(entry->bnd, context));
 
                 if (status == CELIX_SUCCESS) {
                     activator = calloc(1,(sizeof(*activator)));
@@ -931,21 +906,21 @@ celix_status_t fw_startBundle(framework_pt framework, bundle_pt bundle, int opti
                         status = CELIX_ENOMEM;
                     } else {
                         void * userData = NULL;
-                        create_function_fp create = (create_function_fp) celix_libloader_getSymbol((celix_library_handle_t*) bundle_getHandle(bundle), OSGI_FRAMEWORK_BUNDLE_ACTIVATOR_CREATE);
+                        create_function_fp create = (create_function_fp) celix_libloader_getSymbol((celix_library_handle_t*) bundle_getHandle(entry->bnd), OSGI_FRAMEWORK_BUNDLE_ACTIVATOR_CREATE);
                         if (create == NULL) {
-                            create = celix_libloader_getSymbol(bundle_getHandle(bundle), OSGI_FRAMEWORK_DEPRECATED_BUNDLE_ACTIVATOR_CREATE);
+                            create = celix_libloader_getSymbol(bundle_getHandle(entry->bnd), OSGI_FRAMEWORK_DEPRECATED_BUNDLE_ACTIVATOR_CREATE);
                         }
-                        start_function_fp start = (start_function_fp) celix_libloader_getSymbol((celix_library_handle_t*) bundle_getHandle(bundle), OSGI_FRAMEWORK_BUNDLE_ACTIVATOR_START);
+                        start_function_fp start = (start_function_fp) celix_libloader_getSymbol((celix_library_handle_t*) bundle_getHandle(entry->bnd), OSGI_FRAMEWORK_BUNDLE_ACTIVATOR_START);
                         if (start == NULL) {
-                            start = (start_function_fp) celix_libloader_getSymbol((celix_library_handle_t*) bundle_getHandle(bundle), OSGI_FRAMEWORK_DEPRECATED_BUNDLE_ACTIVATOR_START);
+                            start = (start_function_fp) celix_libloader_getSymbol((celix_library_handle_t*) bundle_getHandle(entry->bnd), OSGI_FRAMEWORK_DEPRECATED_BUNDLE_ACTIVATOR_START);
                         }
-                        stop_function_fp stop = (stop_function_fp) celix_libloader_getSymbol((celix_library_handle_t*) bundle_getHandle(bundle), OSGI_FRAMEWORK_BUNDLE_ACTIVATOR_STOP);
+                        stop_function_fp stop = (stop_function_fp) celix_libloader_getSymbol((celix_library_handle_t*) bundle_getHandle(entry->bnd), OSGI_FRAMEWORK_BUNDLE_ACTIVATOR_STOP);
                         if (stop == NULL) {
-                            stop = (stop_function_fp) celix_libloader_getSymbol((celix_library_handle_t*) bundle_getHandle(bundle), OSGI_FRAMEWORK_DEPRECATED_BUNDLE_ACTIVATOR_STOP);
+                            stop = (stop_function_fp) celix_libloader_getSymbol((celix_library_handle_t*) bundle_getHandle(entry->bnd), OSGI_FRAMEWORK_DEPRECATED_BUNDLE_ACTIVATOR_STOP);
                         }
-                        destroy_function_fp destroy = (destroy_function_fp) celix_libloader_getSymbol((celix_library_handle_t*) bundle_getHandle(bundle), OSGI_FRAMEWORK_BUNDLE_ACTIVATOR_DESTROY);
+                        destroy_function_fp destroy = (destroy_function_fp) celix_libloader_getSymbol((celix_library_handle_t*) bundle_getHandle(entry->bnd), OSGI_FRAMEWORK_BUNDLE_ACTIVATOR_DESTROY);
                         if (destroy == NULL) {
-                            destroy = (destroy_function_fp) celix_libloader_getSymbol((celix_library_handle_t*) bundle_getHandle(bundle), OSGI_FRAMEWORK_DEPRECATED_BUNDLE_ACTIVATOR_DESTROY);
+                            destroy = (destroy_function_fp) celix_libloader_getSymbol((celix_library_handle_t*) bundle_getHandle(entry->bnd), OSGI_FRAMEWORK_DEPRECATED_BUNDLE_ACTIVATOR_DESTROY);
                         }
 
                         activator->create = create;
@@ -953,12 +928,12 @@ celix_status_t fw_startBundle(framework_pt framework, bundle_pt bundle, int opti
                         activator->stop = stop;
                         activator->destroy = destroy;
 
-                        status = CELIX_DO_IF(status, bundle_setActivator(bundle, activator));
+                        status = CELIX_DO_IF(status, bundle_setActivator(entry->bnd, 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, framework_setBundleStateAndNotify(framework, entry->bnd, OSGI_FRAMEWORK_BUNDLE_STARTING));
+                        status = CELIX_DO_IF(status, fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_STARTING, entry->bnd));
 
-                        status = CELIX_DO_IF(status, bundle_getContext(bundle, &context));
+                        status = CELIX_DO_IF(status, bundle_getContext(entry->bnd, &context));
 
                         if (status == CELIX_SUCCESS) {
                             if (create != NULL) {
@@ -974,12 +949,12 @@ celix_status_t fw_startBundle(framework_pt framework, bundle_pt bundle, int opti
                             }
                         }
 
-                        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));
+                        status = CELIX_DO_IF(status, framework_setBundleStateAndNotify(framework, entry->bnd, OSGI_FRAMEWORK_BUNDLE_ACTIVE));
+                        status = CELIX_DO_IF(status, fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_STARTED, entry->bnd));
 
                         if (status != CELIX_SUCCESS) {
                             //state is still STARTING, back to resolved
-                            framework_setBundleStateAndNotify(framework, bundle, OSGI_FRAMEWORK_BUNDLE_RESOLVED);
+                            framework_setBundleStateAndNotify(framework, entry->bnd, OSGI_FRAMEWORK_BUNDLE_RESOLVED);
                         }
                     }
                 }
@@ -988,14 +963,12 @@ celix_status_t fw_startBundle(framework_pt framework, bundle_pt bundle, int opti
         }
 	}
 
-    fw_bundleEntry_decreaseUseCount(framework, bndId);
-
 	if (status != CELIX_SUCCESS) {
 	    const char *symbolicName = NULL;
 	    long id = 0;
-	    bundle_getCurrentModule(bundle, &module);
+	    bundle_getCurrentModule(entry->bnd, &module);
 	    module_getSymbolicName(module, &symbolicName);
-	    bundle_getBundleId(bundle, &id);
+	    bundle_getBundleId(entry->bnd, &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 {
@@ -1003,6 +976,10 @@ celix_status_t fw_startBundle(framework_pt framework, bundle_pt bundle, int opti
 	    }
 	}
 
+	if (entry != NULL) {
+	    fw_bundleEntry_decreaseUseCount(entry);
+    }
+
 	return status;
 }
 
@@ -1013,13 +990,13 @@ celix_status_t framework_updateBundle(framework_pt framework, bundle_pt bundle,
 	bundle_archive_pt archive = NULL;
 	char *error = NULL;
 
-    long bndId = celix_bundle_getId(bundle);
-    fw_bundleEntry_increaseUseCount(framework, bndId);
+	long bndId = celix_bundle_getId(bundle);
+    celix_framework_bundle_entry_t *entry = fw_bundleEntry_getBundleEntryAndIncreaseUseCount(framework, bndId);
 
-	status = CELIX_DO_IF(status, bundle_getState(bundle, &oldState));
+    status = CELIX_DO_IF(status, bundle_getState(bundle, &oldState));
 	if (status == CELIX_SUCCESS) {
         if (oldState == OSGI_FRAMEWORK_BUNDLE_ACTIVE) {
-            fw_stopBundle(framework, bundle, false);
+            fw_stopBundle(framework, bndId, false);
         }
 	}
 	status = CELIX_DO_IF(status, bundle_getArchive(bundle, &archive));
@@ -1050,12 +1027,12 @@ celix_status_t framework_updateBundle(framework_pt framework, bundle_pt bundle,
 
 	if (status == CELIX_SUCCESS) {
 	    if (oldState == OSGI_FRAMEWORK_BUNDLE_ACTIVE) {
-	        status = CELIX_DO_IF(status, fw_startBundle(framework, bundle, 1));
+	        status = CELIX_DO_IF(status, fw_startBundle(framework, bndId, 1));
 	    }
 	}
 
 
-    fw_bundleEntry_decreaseUseCount(framework, bndId);
+	fw_bundleEntry_decreaseUseCount(entry);
 
 	if (status != CELIX_SUCCESS) {
 	    module_pt module = NULL;
@@ -1074,7 +1051,7 @@ celix_status_t framework_updateBundle(framework_pt framework, bundle_pt bundle,
 	return status;
 }
 
-celix_status_t fw_stopBundle(framework_pt framework, bundle_pt bundle, bool record) {
+celix_status_t fw_stopBundle(framework_pt framework, long bndId, bool record) {
 	celix_status_t status = CELIX_SUCCESS;
 	bundle_state_e state;
     celix_bundle_activator_t *activator = NULL;
@@ -1082,15 +1059,13 @@ celix_status_t fw_stopBundle(framework_pt framework, bundle_pt bundle, bool reco
     bool wasActive = false;
     char *error = NULL;
 
-    long bndId = celix_bundle_getId(bundle);
-    fw_bundleEntry_increaseUseCount(framework, bndId);
-
+    celix_framework_bundle_entry_t *entry = fw_bundleEntry_getBundleEntryAndIncreaseUseCount(framework, bndId);
 
-	if (record) {
-	    status = CELIX_DO_IF(status, bundle_setPersistentStateInactive(bundle));
+    if (record) {
+	    status = CELIX_DO_IF(status, bundle_setPersistentStateInactive(entry->bnd));
     }
 
-	status = CELIX_DO_IF(status, bundle_getState(bundle, &state));
+	status = CELIX_DO_IF(status, bundle_getState(entry->bnd, &state));
 	if (status == CELIX_SUCCESS) {
 	    switch (state) {
             case OSGI_FRAMEWORK_BUNDLE_UNKNOWN:
@@ -1119,13 +1094,13 @@ celix_status_t fw_stopBundle(framework_pt framework, bundle_pt bundle, bool reco
 	}
 
 
-	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, entry->bnd, OSGI_FRAMEWORK_BUNDLE_STOPPING));
+	status = CELIX_DO_IF(status, fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_STOPPING, entry->bnd));
 	if (status == CELIX_SUCCESS) {
 	    if (wasActive || (bndId == 0)) {
-	        activator = bundle_getActivator(bundle);
+	        activator = bundle_getActivator(entry->bnd);
 
-	        status = CELIX_DO_IF(status, bundle_getContext(bundle, &context));
+	        status = CELIX_DO_IF(status, bundle_getContext(entry->bnd, &context));
 	        if (status == CELIX_SUCCESS) {
                 if (activator->stop != NULL) {
                     status = CELIX_DO_IF(status, activator->stop(activator->userData, context));
@@ -1142,25 +1117,25 @@ celix_status_t fw_stopBundle(framework_pt framework, bundle_pt bundle, bool reco
 	        }
 
             if (bndId > 0) {
-	            celix_serviceTracker_syncForContext(bundle->context);
-                status = CELIX_DO_IF(status, serviceRegistry_clearServiceRegistrations(framework->registry, bundle));
+	            celix_serviceTracker_syncForContext(entry->bnd->context);
+                status = CELIX_DO_IF(status, serviceRegistry_clearServiceRegistrations(framework->registry, entry->bnd));
                 if (status == CELIX_SUCCESS) {
                     module_pt module = NULL;
                     const char *symbolicName = NULL;
                     long id = 0;
-                    bundle_getCurrentModule(bundle, &module);
+                    bundle_getCurrentModule(entry->bnd, &module);
                     module_getSymbolicName(module, &symbolicName);
-                    bundle_getBundleId(bundle, &id);
+                    bundle_getBundleId(entry->bnd, &id);
 
-                    serviceRegistry_clearReferencesFor(framework->registry, bundle);
+                    serviceRegistry_clearReferencesFor(framework->registry, entry->bnd);
                 }
 
                 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, bundle_setContext(entry->bnd, NULL));
                 }
 
-                status = CELIX_DO_IF(status, framework_setBundleStateAndNotify(framework, bundle, OSGI_FRAMEWORK_BUNDLE_RESOLVED));
+                status = CELIX_DO_IF(status, framework_setBundleStateAndNotify(framework, entry->bnd, OSGI_FRAMEWORK_BUNDLE_RESOLVED));
             } else if (bndId == 0) {
                 //framework bundle
                 celix_serviceTracker_syncForContext(framework->bundle->context);
@@ -1168,32 +1143,29 @@ celix_status_t fw_stopBundle(framework_pt framework, bundle_pt bundle, bool reco
 	    }
 
 	    if (activator != NULL) {
-	        bundle_setActivator(bundle, NULL);
+	        bundle_setActivator(entry->bnd, NULL);
 	        free(activator);
 	    }
 	}
 
-
-    fw_bundleEntry_decreaseUseCount(framework, bndId);
-
-
 	if (status != CELIX_SUCCESS) {
 	    module_pt module = NULL;
         const char *symbolicName = NULL;
         long id = 0;
-        bundle_getCurrentModule(bundle, &module);
+        bundle_getCurrentModule(entry->bnd, &module);
         module_getSymbolicName(module, &symbolicName);
-        bundle_getBundleId(bundle, &id);
+        bundle_getBundleId(entry->bnd, &id);
         if (error != NULL) {
             fw_logCode(framework->logger, OSGI_FRAMEWORK_LOG_ERROR, status, "Cannot stop bundle: %s [%ld]; cause: %s", symbolicName, id, error);
         } else {
             fw_logCode(framework->logger, OSGI_FRAMEWORK_LOG_ERROR, status, "Cannot stop bundle: %s [%ld]", symbolicName, id);
         }
  	} else {
-        fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_STOPPED, bundle);
+        fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_STOPPED, entry->bnd);
  	}
 
- 	celix_serviceTracker_syncForFramework(framework);
+	fw_bundleEntry_decreaseUseCount(entry);
+    celix_serviceTracker_syncForFramework(framework);
 
 	return status;
 }
@@ -1201,59 +1173,61 @@ celix_status_t fw_stopBundle(framework_pt framework, bundle_pt bundle, bool reco
 celix_status_t fw_uninstallBundle(framework_pt framework, bundle_pt bundle) {
     celix_status_t status;
 
-    celix_framework_bundle_entry_t *entry = NULL;
-    long bndId = -1L;
-    status = bundle_getBundleId(bundle, &bndId);
-    if (status == CELIX_SUCCESS) {
+    long bndId = celix_bundle_getId(bundle);
+    celix_framework_bundle_entry_t *entry = fw_bundleEntry_getBundleEntryAndIncreaseUseCount(framework, bndId);
+
+    if (entry != NULL) {
+        status = fw_stopBundle(framework, bndId, true);
         celixThreadMutex_lock(&framework->installedBundles.mutex);
         int size = celix_arrayList_size(framework->installedBundles.entries);
         for (int i = 0; i < size; ++i) {
             celix_framework_bundle_entry_t *visit = celix_arrayList_get(framework->installedBundles.entries, i);
-            if (visit != NULL && visit->bndId == bndId) {
-                entry = visit;
+            if (visit == entry) {
+                celix_arrayList_removeAt(framework->installedBundles.entries, i);
                 break;
             }
         }
         celixThreadMutex_unlock(&framework->installedBundles.mutex);
-        status = entry != NULL ? CELIX_SUCCESS : CELIX_ILLEGAL_ARGUMENT;
+    } else {
+        status = CELIX_ILLEGAL_ARGUMENT;
     }
 
     if (entry != NULL) {
         //NOTE wait outside installedBundles.mutex
+        fw_bundleEntry_decreaseUseCount(entry);
         fw_bundleEntry_destroy(entry, true); //wait till use count is 0 -> e.g. not used
     }
 
-    status = CELIX_DO_IF(status, fw_stopBundle(framework, bundle, true));
-
-    bundle_archive_t *archive = NULL;
-    bundle_revision_t *revision = NULL;
-	array_list_pt handles = NULL;
-	status = CELIX_DO_IF(status, bundle_getArchive(bundle, &archive));
-    status = CELIX_DO_IF(status, bundleArchive_setPersistentState(archive, OSGI_FRAMEWORK_BUNDLE_UNINSTALLED)); //set state to uninstalled, so that next framework start will not start bundle.
-	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--) {
-			celix_library_handle_t *handle = arrayList_get(handles, i);
-			celix_libloader_close(handle);
-		}
-	}
+    if (status == CELIX_SUCCESS) {
+        bundle_archive_t *archive = NULL;
+        bundle_revision_t *revision = NULL;
+        array_list_pt handles = NULL;
+        status = CELIX_DO_IF(status, bundle_getArchive(bundle, &archive));
+        status = CELIX_DO_IF(status, bundleArchive_setPersistentState(archive, OSGI_FRAMEWORK_BUNDLE_UNINSTALLED)); //set state to uninstalled, so that next framework start will not start bundle.
+        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--) {
+                celix_library_handle_t *handle = arrayList_get(handles, i);
+                celix_libloader_close(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_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)));
+        status = CELIX_DO_IF(status, framework_setBundleStateAndNotify(framework, bundle, OSGI_FRAMEWORK_BUNDLE_UNINSTALLED));
+        status = CELIX_DO_IF(status, bundleArchive_setLastModified(archive, time(NULL)));
 
-    status = CELIX_DO_IF(status, fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_UNINSTALLED, bundle));
+        status = CELIX_DO_IF(status, fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_UNINSTALLED, bundle));
 
-    if (status == CELIX_SUCCESS) {
-        bundle_pt bundles[] = { bundle };
-        celix_status_t refreshStatus = fw_refreshBundles(framework, bundles, 1);
-        if (refreshStatus != CELIX_SUCCESS) {
-            printf("Could not refresh bundle");
-        } else {
-            bundleArchive_destroy(archive);
-            status = CELIX_DO_IF(status, bundle_destroy(bundle));
+        if (status == CELIX_SUCCESS) {
+            celix_status_t refreshStatus = fw_refreshBundle(framework, bndId);
+            if (refreshStatus != CELIX_SUCCESS) {
+                printf("Could not refresh bundle");
+            } else {
+                bundleArchive_destroy(archive);
+                status = CELIX_DO_IF(status, bundle_destroy(bundle));
+            }
         }
     }
 
@@ -1272,91 +1246,90 @@ celix_status_t fw_uninstallBundle(framework_pt framework, bundle_pt bundle) {
     return status;
 }
 
-celix_status_t fw_refreshBundles(framework_pt framework, bundle_pt bundles[], int size) {
-    celix_status_t status = CELIX_SUCCESS;
-
-    hash_map_values_pt values;
-    bundle_pt *newTargets;
-    unsigned int nrofvalues;
-    bool restart = false;
-    hash_map_pt map = hashMap_create(NULL, NULL, NULL, NULL);
-    int targetIdx = 0;
-    for (targetIdx = 0; targetIdx < size; targetIdx++) {
-        bundle_pt bundle = bundles[targetIdx];
-        hashMap_put(map, bundle, bundle);
-        fw_populateDependentGraph(framework, bundle, &map);
-    }
-    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;
-        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];
-            helpers[i].framework = framework;
-            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);
-    }
-
-    framework_logIfError(framework->logger, status, NULL, "Cannot refresh bundles");
-
-    return status;
-}
+//celix_status_t fw_refreshBundles(framework_pt framework, long bundleIds[], int size) {
+//    celix_status_t status = CELIX_SUCCESS;
+//
+//    hash_map_values_pt values;
+//    bundle_pt *newTargets;
+//    unsigned int nrofvalues;
+//    bool restart = false;
+//    hash_map_pt map = hashMap_create(NULL, NULL, NULL, NULL);
+//    int targetIdx = 0;
+//    for (targetIdx = 0; targetIdx < size; targetIdx++) {
+//        long bndId = bundles[targetIdx];
+//        hashMap_put(map, bundle, bundle);
+//        fw_populateDependentGraph(framework, bundle, &map);
+//    }
+//    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;
+//        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];
+//            helpers[i].framework = framework;
+//            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);
+//    }
+//
+//    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 fw_refreshBundle(framework_pt framework, long bndId) {
     celix_status_t status = CELIX_SUCCESS;
     bundle_state_e state;
 
-    long bndId = celix_bundle_getId(bundle);
-    fw_bundleEntry_increaseUseCount(framework, bndId);
-
 
+    celix_framework_bundle_entry_t *entry = fw_bundleEntry_getBundleEntryAndIncreaseUseCount(framework, bndId);
+    if (entry != NULL) {
+        bool fire;
+        bundle_getState(entry->bnd, &state);
+        fire = (state != OSGI_FRAMEWORK_BUNDLE_INSTALLED);
+        bundle_refresh(entry->bnd);
 
-    bool fire;
-    bundle_getState(bundle, &state);
-    fire = (state != OSGI_FRAMEWORK_BUNDLE_INSTALLED);
-    bundle_refresh(bundle);
+        if (fire) {
+            framework_setBundleStateAndNotify(framework, entry->bnd, OSGI_FRAMEWORK_BUNDLE_INSTALLED);
+            fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_UNRESOLVED, entry->bnd);
+        }
 
-    if (fire) {
-        framework_setBundleStateAndNotify(framework, bundle, OSGI_FRAMEWORK_BUNDLE_INSTALLED);
-        fw_fireBundleEvent(framework, OSGI_FRAMEWORK_BUNDLE_EVENT_UNRESOLVED, bundle);
+        fw_bundleEntry_decreaseUseCount(entry);
+    } else {
+        framework_logIfError(framework->logger, status, NULL, "Cannot refresh bundle");
     }
 
 
-    fw_bundleEntry_decreaseUseCount(framework, bndId);
-
-    framework_logIfError(framework->logger, status, NULL, "Cannot refresh bundle");
-
     return status;
 }
 
@@ -1365,7 +1338,8 @@ celix_status_t fw_refreshHelper_stop(struct fw_refreshHelper * refreshHelper) {
 	bundle_getState(refreshHelper->bundle, &state);
     if (state == OSGI_FRAMEWORK_BUNDLE_ACTIVE) {
         refreshHelper->oldState = OSGI_FRAMEWORK_BUNDLE_ACTIVE;
-        fw_stopBundle(refreshHelper->framework, refreshHelper->bundle, false);
+        long bndId = celix_bundle_getId(refreshHelper->bundle);
+        fw_stopBundle(refreshHelper->framework, bndId, false);
     }
 
     return CELIX_SUCCESS;
@@ -1378,14 +1352,16 @@ celix_status_t fw_refreshHelper_refreshOrRemove(struct fw_refreshHelper * refres
         bundle_closeAndDelete(refreshHelper->bundle);
         refreshHelper->bundle = NULL;
     } else {
-        fw_refreshBundle(refreshHelper->framework, refreshHelper->bundle);
+        long bndId = celix_bundle_getId(refreshHelper->bundle);
+        fw_refreshBundle(refreshHelper->framework, bndId);
     }
     return CELIX_SUCCESS;
 }
 
 celix_status_t fw_refreshHelper_restart(struct fw_refreshHelper * refreshHelper) {
     if ((refreshHelper->bundle != NULL) && (refreshHelper->oldState == OSGI_FRAMEWORK_BUNDLE_ACTIVE)) {
-        fw_startBundle(refreshHelper->framework, refreshHelper->bundle, 0);
+        long bndId = celix_bundle_getId(refreshHelper->bundle);
+        fw_startBundle(refreshHelper->framework, bndId, 0);
     }
     return CELIX_SUCCESS;
 }
@@ -1446,7 +1422,7 @@ celix_status_t fw_populateDependentGraph(framework_pt framework, bundle_pt expor
     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 fw_registerService(framework_pt framework, service_registration_pt *registration, long bndId, const char* serviceName, const void* svcObj, properties_pt properties) {
 	celix_status_t status = CELIX_SUCCESS;
 	char *error = NULL;
 	if (serviceName == NULL || svcObj == NULL) {
@@ -1454,11 +1430,11 @@ celix_status_t fw_registerService(framework_pt framework, service_registration_p
 	    error = "ServiceName and SvcObj cannot be null";
 	}
 
-	long bndId = celix_bundle_getId(bundle);
-    fw_bundleEntry_increaseUseCount(framework, bndId);
+    celix_framework_bundle_entry_t *entry = fw_bundleEntry_getBundleEntryAndIncreaseUseCount(framework, bndId);
 
 
-	status = CELIX_DO_IF(status, serviceRegistry_registerService(framework->registry, bundle, serviceName, svcObj, properties, registration));
+
+    status = CELIX_DO_IF(status, serviceRegistry_registerService(framework->registry, entry->bnd, serviceName, svcObj, properties, registration));
 
 	if (status == CELIX_SUCCESS) {
 	    // If this is a listener hook, invoke the callback with all current listeners
@@ -1480,7 +1456,7 @@ celix_status_t fw_registerService(framework_pt framework, service_registration_p
                     listener_hook_info_pt info = NULL;
                     bundle_context_pt lContext = NULL;
 
-                    subs = CELIX_DO_IF(subs, bundle_getContext(bundle, &context));
+                    subs = CELIX_DO_IF(subs, bundle_getContext(entry->bnd, &context));
                     if (subs == CELIX_SUCCESS) {
                         info = (listener_hook_info_pt) malloc(sizeof(*info));
                         if (info == NULL) {
@@ -1524,15 +1500,14 @@ celix_status_t fw_registerService(framework_pt framework, service_registration_p
 	}
 
 
-    fw_bundleEntry_decreaseUseCount(framework, bndId);
-
+	fw_bundleEntry_decreaseUseCount(entry);
 
     framework_logIfError(framework->logger, status, error, "Cannot register service: %s", serviceName);
 
 	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 fw_registerServiceFactory(framework_pt framework, service_registration_pt *registration, long bndId, const char* serviceName, service_factory_pt factory, properties_pt properties) {
     celix_status_t status = CELIX_SUCCESS;
     char *error = NULL;
 	if (serviceName == NULL || factory == NULL) {
@@ -1540,14 +1515,11 @@ celix_status_t fw_registerServiceFactory(framework_pt framework, service_registr
         error = "Service name and factory cannot be null";
     }
 
-    long bndId = celix_bundle_getId(bundle);
-    fw_bundleEntry_increaseUseCount(framework, bndId);
-
+    celix_framework_bundle_entry_t *entry = fw_bundleEntry_getBundleEntryAndIncreaseUseCount(framework, bndId);
 
-	status = CELIX_DO_IF(status, serviceRegistry_registerServiceFactory(framework->registry, bundle, serviceName, factory, properties, registration));
+	status = CELIX_DO_IF(status, serviceRegistry_registerServiceFactory(framework->registry, entry->bnd, serviceName, factory, properties, registration));
 
-
-    fw_bundleEntry_decreaseUseCount(framework, bndId);
+	fw_bundleEntry_decreaseUseCount(entry);
 
     framework_logIfError(framework->logger, status, error, "Cannot register service factory: %s", serviceName);
 
@@ -1952,7 +1924,7 @@ celix_status_t framework_markBundleResolved(framework_pt framework, module_pt mo
     if (bundle != NULL) {
 
         long bndId = celix_bundle_getId(bundle);
-        fw_bundleEntry_increaseUseCount(framework, bndId);
+        celix_framework_bundle_entry_t *entry = fw_bundleEntry_getBundleEntryAndIncreaseUseCount(framework, bndId);
 
         bundle_getState(bundle, &state);
         if (state != OSGI_FRAMEWORK_BUNDLE_INSTALLED) {
@@ -1983,7 +1955,7 @@ celix_status_t framework_markBundleResolved(framework_pt framework, module_pt mo
         }
 
 
-        fw_bundleEntry_decreaseUseCount(framework, bndId);
+        fw_bundleEntry_decreaseUseCount(entry);
     }
 
     return status;
@@ -2028,23 +2000,6 @@ bundle_pt framework_getBundle(framework_pt framework, const char* location) {
     return bnd;
 }
 
-bundle_pt framework_getBundleById(framework_pt framework, long id) {
-    bundle_t *bnd = NULL;
-
-    celixThreadMutex_lock(&framework->installedBundles.mutex);
-    int size = celix_arrayList_size(framework->installedBundles.entries);
-    for (int i = 0; i < size; ++i) {
-        celix_framework_bundle_entry_t *entry = celix_arrayList_get(framework->installedBundles.entries, i);
-        if (entry != NULL && entry->bndId == id) {
-            bnd = entry->bnd;
-            break;
-        }
-    }
-    celixThreadMutex_unlock(&framework->installedBundles.mutex);
-
-    return bnd;
-}
-
 celix_status_t framework_setBundleStateAndNotify(framework_pt framework, bundle_pt bundle, int state) {
     int ret = CELIX_SUCCESS;
     bundle_setState(bundle, state);
@@ -2095,7 +2050,7 @@ static void* framework_shutdown(void *framework) {
         bundle_state_e state;
         bundle_getState(bnd, &state);
         if (state == OSGI_FRAMEWORK_BUNDLE_ACTIVE || state == OSGI_FRAMEWORK_BUNDLE_STARTING) {
-            fw_stopBundle(fw, bnd, 0);
+            fw_stopBundle(fw, entry->bndId, 0);
         }
         bundle_close(bnd);
     }
@@ -2110,7 +2065,7 @@ static void* framework_shutdown(void *framework) {
         bundle_state_e state;
         bundle_getState(bnd, &state);
         if (state == OSGI_FRAMEWORK_BUNDLE_ACTIVE || state == OSGI_FRAMEWORK_BUNDLE_STARTING) {
-            fw_stopBundle(fw, bnd, 0);
+            fw_stopBundle(fw, fwEntry->bndId, 0);
         }
         bundle_close(bnd);
     }
@@ -2586,21 +2541,21 @@ void celix_framework_useBundles(framework_t *fw, bool includeFrameworkBundle, vo
 bool celix_framework_useBundle(framework_t *fw, bool onlyActive, long bundleId, void *callbackHandle, void(*use)(void *handle, const bundle_t *bnd)) {
     bool called = false;
     if (bundleId >= 0) {
-        fw_bundleEntry_increaseUseCount(fw, bundleId);
-        bundle_t *bnd = framework_getBundleById(fw, bundleId);
-        if (bnd != NULL) {
-            celix_bundle_state_e bndState = celix_bundle_getState(bnd);
+        celix_framework_bundle_entry_t *entry = fw_bundleEntry_getBundleEntryAndIncreaseUseCount(fw, bundleId);
+
+        if (entry != NULL) {
+            celix_bundle_state_e bndState = celix_bundle_getState(entry->bnd);
             if (onlyActive && (bndState == OSGI_FRAMEWORK_BUNDLE_ACTIVE || bndState == OSGI_FRAMEWORK_BUNDLE_STARTING)) {
-                use(callbackHandle, bnd);
+                use(callbackHandle, entry->bnd);
                 called = true;
             } else if (!onlyActive) {
-                use(callbackHandle, bnd);
+                use(callbackHandle, entry->bnd);
                 called = true;
             }
+            fw_bundleEntry_decreaseUseCount(entry);
         } else {
             framework_logIfError(fw->logger, CELIX_FRAMEWORK_EXCEPTION, NULL, "Bundle with id %li is not installed", bundleId);
         }
-        fw_bundleEntry_decreaseUseCount(fw, bundleId);
     }
     return called;
 }
@@ -2611,13 +2566,14 @@ service_registration_t* celix_framework_registerServiceFactory(framework_t *fw ,
     service_registration_t *reg = NULL;
 
     long bndId = celix_bundle_getId(bnd);
-    fw_bundleEntry_increaseUseCount(fw, bndId);
+    celix_framework_bundle_entry_t *entry = fw_bundleEntry_getBundleEntryAndIncreaseUseCount(fw, bndId);
+
 
     if (serviceName != NULL && factory != NULL) {
         status = CELIX_DO_IF(status, celix_serviceRegistry_registerServiceFactory(fw->registry, bnd, serviceName, factory, properties, &reg));
     }
 
-    fw_bundleEntry_decreaseUseCount(fw, bndId);
+    fw_bundleEntry_decreaseUseCount(entry);
 
     framework_logIfError(fw->logger, status, error, "Cannot register service factory: %s", serviceName);
 
@@ -2650,3 +2606,12 @@ celix_bundle_t* celix_framework_getFrameworkBundle(const celix_framework_t *fw)
     return bnd;
 }
 
+bundle_pt framework_getBundleById(framework_pt framework, long id) {
+    celix_bundle_t *bnd = NULL;
+    celix_framework_bundle_entry_t *entry = fw_bundleEntry_getBundleEntryAndIncreaseUseCount(framework, id);
+    if (entry != NULL) {
+        bnd = entry->bnd;
+        fw_bundleEntry_decreaseUseCount(entry); //NOTE returning bundle without increased use count -> FIXME make all getBundle api private (use bundle id instead)
+    }
+    return bnd;
+}
\ No newline at end of file
diff --git a/libs/framework/src/framework_private.h b/libs/framework/src/framework_private.h
index 39c1358..537a040 100644
--- a/libs/framework/src/framework_private.h
+++ b/libs/framework/src/framework_private.h
@@ -98,12 +98,12 @@ FRAMEWORK_EXPORT celix_status_t fw_uninstallBundle(framework_pt framework, bundl
 
 FRAMEWORK_EXPORT celix_status_t framework_getBundleEntry(framework_pt framework, const_bundle_pt bundle, const char* name, char** entry);
 
-FRAMEWORK_EXPORT celix_status_t fw_startBundle(framework_pt framework, bundle_pt bundle, int options);
+FRAMEWORK_EXPORT celix_status_t fw_startBundle(framework_pt framework, long bndId, int options);
 FRAMEWORK_EXPORT celix_status_t framework_updateBundle(framework_pt framework, bundle_pt bundle, const char* inputFile);
-FRAMEWORK_EXPORT celix_status_t fw_stopBundle(framework_pt framework, bundle_pt bundle, bool record);
+FRAMEWORK_EXPORT celix_status_t fw_stopBundle(framework_pt framework, long bndId, bool record);
 
-FRAMEWORK_EXPORT celix_status_t fw_registerService(framework_pt framework, service_registration_pt * registration, bundle_pt bundle, const char* serviceName, const void* svcObj, properties_pt properties);
-FRAMEWORK_EXPORT 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);
+FRAMEWORK_EXPORT celix_status_t fw_registerService(framework_pt framework, service_registration_pt * registration, long bundleId, const char* serviceName, const void* svcObj, properties_pt properties);
+FRAMEWORK_EXPORT celix_status_t fw_registerServiceFactory(framework_pt framework, service_registration_pt * registration, long bundleId, const char* serviceName, service_factory_pt factory, properties_pt properties);
 FRAMEWORK_EXPORT void fw_unregisterService(service_registration_pt registration);
 
 FRAMEWORK_EXPORT celix_status_t fw_getServiceReferences(framework_pt framework, array_list_pt *references, bundle_pt bundle, const char* serviceName, const char* filter);
diff --git a/libs/framework/tst/bundle_context_bundles_tests.cpp b/libs/framework/tst/bundle_context_bundles_tests.cpp
index d492875..0189e04 100644
--- a/libs/framework/tst/bundle_context_bundles_tests.cpp
+++ b/libs/framework/tst/bundle_context_bundles_tests.cpp
@@ -92,6 +92,50 @@ TEST(CelixBundleContextBundlesTests, useBundlesTest) {
     CHECK_EQUAL(1, count);
 };
 
+TEST(CelixBundleContextBundlesTests, installAndUninstallBundlesTest) {
+    //install bundles
+    long bndId1 = celix_bundleContext_installBundle(ctx, TEST_BND1_LOC, true);
+    long bndId2 = celix_bundleContext_installBundle(ctx, TEST_BND2_LOC, false);
+    long bndId3 = celix_bundleContext_installBundle(ctx, TEST_BND3_LOC, true);
+
+    CHECK_TRUE(bndId1 >= 0L);
+    CHECK_TRUE(bndId2 >= 0L);
+    CHECK_TRUE(bndId3 >= 0L);
+
+    CHECK_TRUE(celix_bundleContext_isBundleInstalled(ctx, bndId1));
+    CHECK_TRUE(celix_bundleContext_isBundleInstalled(ctx, bndId2));
+    CHECK_TRUE(celix_bundleContext_isBundleInstalled(ctx, bndId3));
+
+    CHECK_TRUE(celix_bundleContext_isBundleActive(ctx, bndId1));
+    CHECK_FALSE(celix_bundleContext_isBundleActive(ctx, bndId2)); //not auto started
+    CHECK_TRUE(celix_bundleContext_isBundleActive(ctx, bndId3));
+
+    //uninstall bundles
+    CHECK_TRUE(celix_bundleContext_uninstallBundle(ctx, bndId1));
+    CHECK_TRUE(celix_bundleContext_uninstallBundle(ctx, bndId2));
+    CHECK_TRUE(celix_bundleContext_uninstallBundle(ctx, bndId3));
+
+    CHECK_FALSE(celix_bundleContext_isBundleInstalled(ctx, bndId1));
+    CHECK_FALSE(celix_bundleContext_isBundleInstalled(ctx, bndId2));
+    CHECK_FALSE(celix_bundleContext_isBundleInstalled(ctx, bndId3));
+
+    CHECK_FALSE(celix_bundleContext_isBundleActive(ctx, bndId1)); //not uninstall -> not active
+    CHECK_FALSE(celix_bundleContext_isBundleActive(ctx, bndId2));
+    CHECK_FALSE(celix_bundleContext_isBundleActive(ctx, bndId3));
+
+    //reinstall bundles
+    long bndId4 = celix_bundleContext_installBundle(ctx, TEST_BND1_LOC, true);
+    long bndId5 = celix_bundleContext_installBundle(ctx, TEST_BND2_LOC, false);
+    long bndId6 = celix_bundleContext_installBundle(ctx, TEST_BND3_LOC, true);
+
+    CHECK_TRUE(bndId4 >= 0L);
+    CHECK_FALSE(bndId1 == bndId4); //not new id
+    CHECK_TRUE(bndId5 >= 0L);
+    CHECK_FALSE(bndId2 == bndId5); //not new id
+    CHECK_TRUE(bndId6 >= 0L);
+    CHECK_FALSE(bndId5 == bndId6); //not new id
+}
+
 TEST(CelixBundleContextBundlesTests, startBundleWithException) {
     long bndId = celix_bundleContext_installBundle(ctx, TEST_BND_WITH_EXCEPTION_LOC, true);
     CHECK(bndId > 0); //bundle is installed, but not started
@@ -103,8 +147,6 @@ TEST(CelixBundleContextBundlesTests, startBundleWithException) {
     CHECK_TRUE(called);
 }
 
-/* TODO enable again with newer Ubuntu. For now cannot reproduce this.
- * Should be fixed with #121
 TEST(CelixBundleContextBundlesTests, startUnresolveableBundle) {
     long bndId = celix_bundleContext_installBundle(ctx, TEST_BND_UNRESOLVEABLE_LOC, true);
     CHECK(bndId > 0); //bundle is installed, but not resolved
@@ -123,18 +165,19 @@ TEST(CelixBundleContextBundlesTests, startUnresolveableBundle) {
     });
     CHECK_TRUE(called);
 }
-*/
+
 
 TEST(CelixBundleContextBundlesTests, useBundleTest) {
     int count = 0;
 
-    celix_bundleContext_useBundle(ctx, 0, &count, [](void *handle, const bundle_t *bnd) {
+    bool called = celix_bundleContext_useBundle(ctx, 0, &count, [](void *handle, const bundle_t *bnd) {
         int *c = (int*)handle;
         *c += 1;
         long id = celix_bundle_getId(bnd);
         CHECK_EQUAL(0, id);
     });
 
+    CHECK_TRUE(called);
     CHECK_EQUAL(1, count);
 };
 
@@ -194,7 +237,6 @@ TEST(CelixBundleContextBundlesTests, DoubleStopTest) {
     CHECK_TRUE(bndId > 0);
     CHECK_TRUE(celix_bundleContext_isBundleInstalled(ctx, bndId));
 
-    //TODO rewrite using celix_bundleContext_useBundlesWithOptions ....
     bool called = celix_framework_useBundle(fw, false, bndId, nullptr, [](void *, const celix_bundle_t *bnd) {
         CHECK_EQUAL(OSGI_FRAMEWORK_BUNDLE_ACTIVE, celix_bundle_getState(bnd));
     });
@@ -282,7 +324,6 @@ TEST(CelixBundleContextBundlesTests, trackBundlesTest) {
     }
     CHECK_EQUAL(2, data.count);
 
-    /* TODO does not work -> stopping bundle event is never forward to the bundle listener ?? very old bug?
     celix_bundleContext_uninstallBundle(ctx, bundleId2);
     {
         std::unique_lock<std::mutex> lock{data.mutex};
@@ -308,13 +349,11 @@ TEST(CelixBundleContextBundlesTests, trackBundlesTest) {
 
     }
     CHECK_EQUAL(4, data.count);
-     */
 
 
     celix_bundleContext_stopTracker(ctx, trackerId);
 };
 
-/* IGNORE TODO need to add locks
 TEST(CelixBundleContextBundlesTests, useBundlesConcurrentTest) {
 
     struct data {
@@ -322,7 +361,6 @@ TEST(CelixBundleContextBundlesTests, useBundlesConcurrentTest) {
         std::condition_variable cond{};
         bool inUse{false};
         bool readyToExit{false};
-        bool called{false};
     };
     struct data data{};
 
@@ -336,18 +374,13 @@ TEST(CelixBundleContextBundlesTests, useBundlesConcurrentTest) {
         d->cond.notify_all();
         d->cond.wait(lock, [d]{return d->readyToExit;});
         lock.unlock();
-
-        auto state = celix_bundle_getState(bnd);
-        CHECK_EQUAL(OSGI_FRAMEWORK_BUNDLE_ACTIVE, state);
-
-        d->called = true;
     };
 
     long bndId = celix_bundleContext_installBundle(ctx, TEST_BND1_LOC, true);
 
     auto call = [&] {
-        celix_bundleContext_useBundle(ctx, bndId, &data, use);
-        CHECK(data.called);
+        bool called = celix_bundleContext_useBundle(ctx, bndId, &data, use);
+        CHECK(called);
     };
     std::thread useThread{call};
 
@@ -378,4 +411,4 @@ TEST(CelixBundleContextBundlesTests, useBundlesConcurrentTest) {
     std::cout << "use thread joined" << std::endl;
     uninstallThread.join();
     std::cout << "uninstall thread joined" << std::endl;
-};*/
\ No newline at end of file
+};
\ No newline at end of file
diff --git a/libs/framework/tst/run_tests.cpp b/libs/framework/tst/run_tests.cpp
index c0d52be..efaee82 100644
--- a/libs/framework/tst/run_tests.cpp
+++ b/libs/framework/tst/run_tests.cpp
@@ -21,5 +21,6 @@
 #include "CppUTest/CommandLineTestRunner.h"
 
 int main(int argc, char** argv) {
+    MemoryLeakWarningPlugin::turnOffNewDeleteOverloads();
     return RUN_ALL_TESTS(argc, argv);
 }
\ No newline at end of file