Merge pull request #350 from apache/feature/use_async_api_for_rsa

Feature/use async api for rsa
diff --git a/bundles/remote_services/deprecated_rsa_spi/include/import_registration.h b/bundles/remote_services/deprecated_rsa_spi/include/import_registration.h
index d10ae7c..c51eeea 100644
--- a/bundles/remote_services/deprecated_rsa_spi/include/import_registration.h
+++ b/bundles/remote_services/deprecated_rsa_spi/include/import_registration.h
@@ -28,7 +28,6 @@
 
 typedef struct import_reference import_reference_t;
 
-celix_status_t importRegistration_close(import_registration_t *registration);
 celix_status_t importRegistration_getException(import_registration_t *registration);
 celix_status_t importRegistration_getImportReference(import_registration_t *registration, import_reference_t **reference);
 
diff --git a/bundles/remote_services/remote_service_admin_dfi/README.md b/bundles/remote_services/remote_service_admin_dfi/README.md
index 06082b1..e1db893 100644
--- a/bundles/remote_services/remote_service_admin_dfi/README.md
+++ b/bundles/remote_services/remote_service_admin_dfi/README.md
@@ -31,7 +31,12 @@
     RSA_INTERFACE               If specified, the ip adress of interface (i.g. eth0) will be used.
     
     RSA_LOG_CALLS              If set to true, the RSA will Log calls info (including serialized data) to the file in RSA_LOG_CALLS_FILE. Default is false.
-    RSA_LOG_CALLS_FILE         If RSA_LOG_CALLS is enabled to file to log to (starting rsa will truncate file). Default is stdout.          
+    RSA_LOG_CALLS_FILE         If RSA_LOG_CALLS is enabled to file to log to (starting rsa will truncate file). Default is stdout.   
+
+    RSA_DFI_USE_CURL_SHARE_HANDLE   If set to true the RSA will use curl's share handle. 
+                                    The curl share handle has a significant performance boost by sharing DNS, COOKIE en CONNECTIONS over multiple calls, 
+                                    but can also introduce some issues (based on experience).
+                                    Default is false
 
 ###### CMake option
     RSA_REMOTE_SERVICE_ADMIN_DFI=ON
diff --git a/bundles/remote_services/remote_service_admin_dfi/gtest/CMakeLists.txt b/bundles/remote_services/remote_service_admin_dfi/gtest/CMakeLists.txt
index 02e4a95..f3931c7 100644
--- a/bundles/remote_services/remote_service_admin_dfi/gtest/CMakeLists.txt
+++ b/bundles/remote_services/remote_service_admin_dfi/gtest/CMakeLists.txt
@@ -15,9 +15,6 @@
 # specific language governing permissions and limitations
 # under the License.
 
-find_package(CppUTest REQUIRED)
-include_directories(SYSTEM PRIVATE ${CppUTest_INCLUDE_DIR})
-
 add_celix_bundle(rsa_dfi_tst_bundle
     VERSION 0.0.1
     SOURCES
diff --git a/bundles/remote_services/remote_service_admin_dfi/gtest/src/rsa_client_server_tests.cc b/bundles/remote_services/remote_service_admin_dfi/gtest/src/rsa_client_server_tests.cc
index 32f1dd9..a47e3ed 100644
--- a/bundles/remote_services/remote_service_admin_dfi/gtest/src/rsa_client_server_tests.cc
+++ b/bundles/remote_services/remote_service_admin_dfi/gtest/src/rsa_client_server_tests.cc
@@ -41,7 +41,7 @@
     static celix_framework_t *clientFramework = NULL;
     static celix_bundle_context_t *clientContext = NULL;
 
-    static void setupFm(void) {
+    static void setupFm(bool useCurlShare) {
         //server
         celix_properties_t *serverProps = celix_properties_load("server.properties");
         ASSERT_TRUE(serverProps != NULL);
@@ -52,6 +52,7 @@
 
         //client
         celix_properties_t *clientProperties = celix_properties_load("client.properties");
+        celix_properties_setBool(clientProperties, "RSA_DFI_USE_CURL_SHARE_HANDLE", useCurlShare);
         ASSERT_TRUE(clientProperties != NULL);
         clientFramework = celix_frameworkFactory_createFramework(clientProperties);
         ASSERT_TRUE(clientFramework != NULL);
@@ -164,7 +165,7 @@
 class RsaDfiClientServerTests : public ::testing::Test {
 public:
     RsaDfiClientServerTests() {
-        setupFm();
+        setupFm(false);
     }
     ~RsaDfiClientServerTests() override {
         teardownFm();
@@ -172,15 +173,34 @@
 
 };
 
+class RsaDfiClientServerWithCurlShareTests : public ::testing::Test {
+public:
+    RsaDfiClientServerWithCurlShareTests() {
+        setupFm(true);
+    }
+    ~RsaDfiClientServerWithCurlShareTests() override {
+        teardownFm();
+    }
+
+};
+
 
 TEST_F(RsaDfiClientServerTests, TestRemoteCalculator) {
     test(testCalculator);
 }
 
+TEST_F(RsaDfiClientServerWithCurlShareTests, TestRemoteCalculator) {
+    test(testCalculator);
+}
+
 TEST_F(RsaDfiClientServerTests, TestRemoteComplex) {
     test(testComplex);
 }
 
+TEST_F(RsaDfiClientServerWithCurlShareTests, TestRemoteComplex) {
+    test(testComplex);
+}
+
 TEST_F(RsaDfiClientServerTests, TestRemoteNumbers) {
     test(testNumbers);
 }
diff --git a/bundles/remote_services/remote_service_admin_dfi/gtest/src/rsa_tests.cc b/bundles/remote_services/remote_service_admin_dfi/gtest/src/rsa_tests.cc
index b2fee66..c0c6b7e 100644
--- a/bundles/remote_services/remote_service_admin_dfi/gtest/src/rsa_tests.cc
+++ b/bundles/remote_services/remote_service_admin_dfi/gtest/src/rsa_tests.cc
@@ -107,43 +107,30 @@
     }
 
     static void testImportServiceCallback(void *handle __attribute__((unused)), void *svc) {
-        auto *rsa = static_cast<remote_service_admin_service_t *>(svc);
+        thread_local bool init = true;
+        thread_local endpoint_description_t *endpoint = nullptr;
+        if (init) {
+            auto *rsa = static_cast<remote_service_admin_service_t *>(svc);
+            celix_properties_t *props = celix_properties_create();
+            celix_properties_set(props, OSGI_RSA_ENDPOINT_SERVICE_ID, "42");
+            celix_properties_set(props, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, "eec5404d-51d0-47ef-8d86-c825a8beda42");
+            celix_properties_set(props, OSGI_RSA_ENDPOINT_ID, "eec5404d-51d0-47ef-8d86-c825a8beda42-42");
+            celix_properties_set(props, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, TST_CONFIGURATION_TYPE);
+            celix_properties_set(props, OSGI_FRAMEWORK_OBJECTCLASS, "org.apache.celix.Example");
 
-        int rc = 0;
-        import_registration_t *reg = NULL;
-        endpoint_description_t *endpoint = NULL;
+            int rc = endpointDescription_create(props, &endpoint);
+            ASSERT_EQ(CELIX_SUCCESS, rc);
 
-        celix_properties_t *props = celix_properties_create();
-        celix_properties_set(props, OSGI_RSA_ENDPOINT_SERVICE_ID, "42");
-        celix_properties_set(props, OSGI_RSA_ENDPOINT_FRAMEWORK_UUID, "eec5404d-51d0-47ef-8d86-c825a8beda42");
-        celix_properties_set(props, OSGI_RSA_ENDPOINT_ID, "eec5404d-51d0-47ef-8d86-c825a8beda42-42");
-        celix_properties_set(props, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, TST_CONFIGURATION_TYPE);
-        celix_properties_set(props, OSGI_FRAMEWORK_OBJECTCLASS, "org.apache.celix.Example");
+            import_registration_t* reg = nullptr;
+            rc = rsa->importService(rsa->admin, endpoint, &reg);
+            ASSERT_EQ(CELIX_SUCCESS, rc);
+            ASSERT_TRUE(reg != nullptr);
 
-        rc = endpointDescription_create(props, &endpoint);
-        ASSERT_EQ(CELIX_SUCCESS, rc);
-
-        rc = rsa->importService(rsa->admin, endpoint, &reg);
-        ASSERT_EQ(CELIX_SUCCESS, rc);
-        ASSERT_TRUE(reg != NULL);
-
-        service_reference_pt ref = NULL;
-        rc = bundleContext_getServiceReference(context, (char *)"org.apache.celix.Example", &ref);
-        ASSERT_EQ(CELIX_SUCCESS, rc);
-        ASSERT_TRUE(ref != NULL);
-
-        rc = bundleContext_ungetServiceReference(context, ref);
-        ASSERT_EQ(CELIX_SUCCESS, rc);
-
-        rc = endpointDescription_destroy(endpoint);
-        ASSERT_EQ(CELIX_SUCCESS, rc);
-
-        /* Cannot test. uses requesting bundles descriptor
-        void *service = NULL;
-        rc = bundleContext_getService(context, ref, &service);
-        ASSERT_EQ(CELIX_SUCCESS, rc);
-        ASSERT_TRUE(service != NULL);
-         */
+            init = false;
+        } else {
+            int rc = endpointDescription_destroy(endpoint);
+            ASSERT_EQ(CELIX_SUCCESS, rc);
+        }
     }
 
     static void testImportService(void) {
@@ -152,8 +139,18 @@
         opts.use = testImportServiceCallback;
         opts.filter.ignoreServiceLanguage = true;
         opts.waitTimeoutInSeconds = 0.25;
+
+        //first call -> init
         bool called = celix_bundleContext_useServiceWithOptions(context, &opts);
         ASSERT_TRUE(called);
+
+        celix_framework_waitForEmptyEventQueue(celix_bundleContext_getFramework(context));
+        long svcId = celix_bundleContext_findService(context, "org.apache.celix.Example");
+        EXPECT_GE(svcId, 0);
+
+        //second call -> deinit
+        called = celix_bundleContext_useServiceWithOptions(context, &opts);
+        ASSERT_TRUE(called);
     }
 
     static void testBundles(void) {
diff --git a/bundles/remote_services/remote_service_admin_dfi/src/export_registration_dfi.c b/bundles/remote_services/remote_service_admin_dfi/src/export_registration_dfi.c
index f63c39a..7af2cd9 100644
--- a/bundles/remote_services/remote_service_admin_dfi/src/export_registration_dfi.c
+++ b/bundles/remote_services/remote_service_admin_dfi/src/export_registration_dfi.c
@@ -40,6 +40,7 @@
     struct export_reference exportReference;
     char *servId;
     dyn_interface_type *intf; //owner
+    char filter[32];
 
 
     celix_thread_mutex_t mutex;
@@ -228,47 +229,52 @@
     return CELIX_BUNDLE_EXCEPTION;
 }
 
+static void exportRegistration_destroyCallback(void* data) {
+    export_registration_t* reg = data;
+    if (reg->intf != NULL) {
+        dyn_interface_type *intf = reg->intf;
+        reg->intf = NULL;
+        dynInterface_destroy(intf);
+    }
+
+    if (reg->exportReference.endpoint != NULL) {
+        endpoint_description_t *ep = reg->exportReference.endpoint;
+        reg->exportReference.endpoint = NULL;
+        endpointDescription_destroy(ep);
+    }
+    if (reg->servId != NULL) {
+        free(reg->servId);
+    }
+    remoteInterceptorsHandler_destroy(reg->interceptorsHandler);
+    bundleContext_ungetServiceReference(reg->context, reg->exportReference.reference);
+
+    celixThreadMutex_destroy(&reg->mutex);
+    celixThreadCondition_destroy(&reg->cond);
+    free(reg);
+}
+
 void exportRegistration_destroy(export_registration_t *reg) {
     if (reg != NULL) {
-        if (reg->intf != NULL) {
-            dyn_interface_type *intf = reg->intf;
-            reg->intf = NULL;
-            dynInterface_destroy(intf);
-        }
-
-        if (reg->exportReference.endpoint != NULL) {
-            endpoint_description_t *ep = reg->exportReference.endpoint;
-            reg->exportReference.endpoint = NULL;
-            endpointDescription_destroy(ep);
-        }
         if (reg->trackerId >= 0) {
-            celix_bundleContext_stopTracker(reg->context, reg->trackerId);
+            celix_bundleContext_stopTrackerAsync(reg->context, reg->trackerId, reg, exportRegistration_destroyCallback);
+        } else {
+            exportRegistration_destroyCallback(reg);
         }
-        if (reg->servId != NULL) {
-            free(reg->servId);
-        }
-
-        remoteInterceptorsHandler_destroy(reg->interceptorsHandler);
-
-        celixThreadMutex_destroy(&reg->mutex);
-        celixThreadCondition_destroy(&reg->cond);
-        free(reg);
     }
 }
 
 celix_status_t exportRegistration_start(export_registration_t *reg) {
     celix_status_t status = CELIX_SUCCESS;
 
-    char filter[32];
-    snprintf(filter, 32, "(service.id=%s)", reg->servId);
+    snprintf(reg->filter, 32, "(service.id=%s)", reg->servId);
     celix_service_tracking_options_t opts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS;
-    opts.filter.filter = filter;
+    opts.filter.filter = reg->filter;
     opts.filter.serviceName = "*";
     opts.filter.ignoreServiceLanguage = true;
     opts.callbackHandle = reg;
     opts.add = exportRegistration_addServ;
     opts.remove = exportRegistration_removeServ;
-    long newTrkId = celix_bundleContext_trackServicesWithOptions(reg->context, &opts);
+    long newTrkId = celix_bundleContext_trackServicesWithOptionsAsync(reg->context, &opts);
 
     celixThreadMutex_lock(&reg->mutex);
     long prevTrkId = reg->trackerId;
@@ -277,28 +283,12 @@
 
     if (prevTrkId >= 0) {
         celix_logHelper_error(reg->helper, "Error starting export registration. The export registration already had an active service tracker");
-        celix_bundleContext_stopTracker(reg->context, prevTrkId);
+        celix_bundleContext_stopTrackerAsync(reg->context, prevTrkId, NULL, NULL);
     }
 
     return status;
 }
 
-
-celix_status_t exportRegistration_stop(export_registration_t *reg) {
-    celix_status_t status = CELIX_SUCCESS;
-    if (status == CELIX_SUCCESS) {
-        status = bundleContext_ungetServiceReference(reg->context, reg->exportReference.reference);
-
-        celixThreadMutex_lock(&reg->mutex);
-        long trkId = reg->trackerId;
-        reg->trackerId = -1L;
-        celixThreadMutex_unlock(&reg->mutex);
-        celix_bundleContext_stopTracker(reg->context, trkId);
-
-    }
-    return status;
-}
-
 void exportRegistration_setActive(export_registration_t *reg, bool active) {
     celixThreadMutex_lock(&reg->mutex);
     reg->active = active;
diff --git a/bundles/remote_services/remote_service_admin_dfi/src/export_registration_dfi.h b/bundles/remote_services/remote_service_admin_dfi/src/export_registration_dfi.h
index e290442..b07b869 100644
--- a/bundles/remote_services/remote_service_admin_dfi/src/export_registration_dfi.h
+++ b/bundles/remote_services/remote_service_admin_dfi/src/export_registration_dfi.h
@@ -29,7 +29,6 @@
 void exportRegistration_destroy(export_registration_t *registration);
 
 celix_status_t exportRegistration_start(export_registration_t *registration);
-celix_status_t exportRegistration_stop(export_registration_t *registration);
 void exportRegistration_setActive(export_registration_t *registration, bool active);
 
 celix_status_t exportRegistration_call(export_registration_t *export, char *data, int datalength, celix_properties_t *metadata, char **response, int *responseLength);
diff --git a/bundles/remote_services/remote_service_admin_dfi/src/import_registration_dfi.c b/bundles/remote_services/remote_service_admin_dfi/src/import_registration_dfi.c
index 55f0e05..70221c2 100644
--- a/bundles/remote_services/remote_service_admin_dfi/src/import_registration_dfi.c
+++ b/bundles/remote_services/remote_service_admin_dfi/src/import_registration_dfi.c
@@ -34,12 +34,11 @@
     const char *classObject; //NOTE owned by endpoint
     version_pt version;
 
-    celix_thread_mutex_t mutex; //protects send & sendhandle
     send_func_type send;
     void *sendHandle;
 
-    service_factory_pt factory;
-    service_registration_t *factoryReg;
+    celix_service_factory_t factory;
+    long factorySvcId;
 
     hash_map_pt proxies; //key -> bundle, value -> service_proxy
     celix_thread_mutex_t proxiesMutex; //protects proxies
@@ -64,34 +63,37 @@
 static void importRegistration_clearProxies(import_registration_t *import);
 static const char* importRegistration_getUrl(import_registration_t *reg);
 static const char* importRegistration_getServiceName(import_registration_t *reg);
+static void* importRegistration_getService(void *handle, const celix_bundle_t *requestingBundle, const celix_properties_t *svcProperties);
+void importRegistration_ungetService(void *handle, const celix_bundle_t *requestingBundle, const celix_properties_t *svcProperties);
 
-celix_status_t importRegistration_create(celix_bundle_context_t *context, endpoint_description_t *endpoint, const char *classObject, const char* serviceVersion, FILE *logFile, import_registration_t **out) {
+celix_status_t importRegistration_create(
+        celix_bundle_context_t *context,
+        endpoint_description_t *endpoint,
+        const char *classObject,
+        const char* serviceVersion,
+        send_func_type sendFn,
+        void* sendFnHandle,
+        FILE *logFile,
+        import_registration_t **out) {
     celix_status_t status = CELIX_SUCCESS;
     import_registration_t *reg = calloc(1, sizeof(*reg));
+    reg->context = context;
+    reg->endpoint = endpoint;
+    reg->classObject = classObject;
+    reg->send = sendFn;
+    reg->sendHandle = sendFnHandle;
+    reg->proxies = hashMap_create(NULL, NULL, NULL, NULL);
 
-    if (reg != NULL) {
-        reg->factory = calloc(1, sizeof(*reg->factory));
-    }
+    remoteInterceptorsHandler_create(context, &reg->interceptorsHandler);
 
-    if (reg != NULL && reg->factory != NULL) {
-        reg->context = context;
-        reg->endpoint = endpoint;
-        reg->classObject = classObject;
-        reg->proxies = hashMap_create(NULL, NULL, NULL, NULL);
+    celixThreadMutex_create(&reg->proxiesMutex, NULL);
+    status = version_createVersionFromString((char*)serviceVersion,&(reg->version));
 
-        remoteInterceptorsHandler_create(context, &reg->interceptorsHandler);
-
-        celixThreadMutex_create(&reg->mutex, NULL);
-        celixThreadMutex_create(&reg->proxiesMutex, NULL);
-        status = version_createVersionFromString((char*)serviceVersion,&(reg->version));
-
-        reg->factory->handle = reg;
-        reg->factory->getService = (void *)importRegistration_getService;
-        reg->factory->ungetService = (void *)importRegistration_ungetService;
-        reg->logFile = logFile;
-    } else {
-        status = CELIX_ENOMEM;
-    }
+    reg->factorySvcId = -1;
+    reg->factory.handle = reg;
+    reg->factory.getService = importRegistration_getService;
+    reg->factory.ungetService = importRegistration_ungetService;
+    reg->logFile = logFile;
 
 
     if (status == CELIX_SUCCESS) {
@@ -104,18 +106,6 @@
     return status;
 }
 
-
-celix_status_t importRegistration_setSendFn(import_registration_t *reg,
-                                            send_func_type send,
-                                            void *handle) {
-    celixThreadMutex_lock(&reg->mutex);
-    reg->send = send;
-    reg->sendHandle = handle;
-    celixThreadMutex_unlock(&reg->mutex);
-
-    return CELIX_SUCCESS;
-}
-
 static void importRegistration_clearProxies(import_registration_t *import) {
     if (import != NULL) {
         pthread_mutex_lock(&import->proxiesMutex);
@@ -132,56 +122,44 @@
     }
 }
 
+static void importRegistration_destroyCallback(void* data) {
+    import_registration_t* import = data;
+    importRegistration_clearProxies(import);
+    if (import->proxies != NULL) {
+        hashMap_destroy(import->proxies, false, false);
+        import->proxies = NULL;
+    }
+
+    remoteInterceptorsHandler_destroy(import->interceptorsHandler);
+
+    pthread_mutex_destroy(&import->proxiesMutex);
+
+    if (import->version != NULL) {
+        version_destroy(import->version);
+    }
+    free(import);
+}
+
 void importRegistration_destroy(import_registration_t *import) {
     if (import != NULL) {
-        if (import->proxies != NULL) {
-            hashMap_destroy(import->proxies, false, false);
-            import->proxies = NULL;
+        if (import->factorySvcId >= 0) {
+            celix_bundleContext_unregisterServiceAsync(import->context, import->factorySvcId, import, importRegistration_destroyCallback);
+        } else {
+            importRegistration_destroyCallback(import);
         }
-
-        remoteInterceptorsHandler_destroy(import->interceptorsHandler);
-
-        pthread_mutex_destroy(&import->mutex);
-        pthread_mutex_destroy(&import->proxiesMutex);
-
-        if (import->factory != NULL) {
-            free(import->factory);
-        }
-
-        if(import->version!=NULL){
-        	version_destroy(import->version);
-        }
-        free(import);
     }
 }
 
 celix_status_t importRegistration_start(import_registration_t *import) {
-    celix_status_t  status = CELIX_SUCCESS;
-    if (import->factoryReg == NULL && import->factory != NULL) {
-        celix_properties_t *props =  celix_properties_copy(import->endpoint->properties);
-        status = bundleContext_registerServiceFactory(import->context, (char *)import->classObject, import->factory, props, &import->factoryReg);
-    } else {
-        status = CELIX_ILLEGAL_STATE;
-    }
-    return status;
+    celix_properties_t *props =  celix_properties_copy(import->endpoint->properties);
+    import->factorySvcId = celix_bundleContext_registerServiceFactoryAsync(import->context, &import->factory, import->classObject, props);
+    return import->factorySvcId >= 0 ? CELIX_SUCCESS : CELIX_ILLEGAL_STATE;
 }
 
-celix_status_t importRegistration_stop(import_registration_t *import) {
-    celix_status_t status = CELIX_SUCCESS;
-
-    if (import->factoryReg != NULL) {
-        serviceRegistration_unregister(import->factoryReg);
-        import->factoryReg = NULL;
-    }
-
-    importRegistration_clearProxies(import);
-
-    return status;
-}
-
-
-celix_status_t importRegistration_getService(import_registration_t *import, celix_bundle_t *bundle, service_registration_t *registration, void **out) {
+static void* importRegistration_getService(void *handle, const celix_bundle_t *requestingBundle, const celix_properties_t *svcProperties) {
     celix_status_t  status = CELIX_SUCCESS;
+    void* svc = NULL;
+    import_registration_t* import = handle;
 
     /*
     module_pt module = NULL;
@@ -193,21 +171,36 @@
 
 
     pthread_mutex_lock(&import->proxiesMutex);
-    struct service_proxy *proxy = hashMap_get(import->proxies, bundle);
+    struct service_proxy *proxy = hashMap_get(import->proxies, requestingBundle);
     if (proxy == NULL) {
-        status = importRegistration_createProxy(import, bundle, &proxy);
+        status = importRegistration_createProxy(import, (celix_bundle_t*)requestingBundle, &proxy);
         if (status == CELIX_SUCCESS) {
-            hashMap_put(import->proxies, bundle, proxy);
+            hashMap_put(import->proxies, (void*)requestingBundle, proxy);
         }
     }
-
     if (status == CELIX_SUCCESS) {
         proxy->count += 1;
-        *out = proxy->service;
+        svc = proxy->service;
     }
     pthread_mutex_unlock(&import->proxiesMutex);
 
-    return status;
+    return svc;
+}
+
+void importRegistration_ungetService(void *handle, const celix_bundle_t *requestingBundle, const celix_properties_t *svcProperties) {
+    import_registration_t* import = handle;
+    assert(import != NULL);
+    assert(import->proxies != NULL);
+    pthread_mutex_lock(&import->proxiesMutex);
+    struct service_proxy *proxy = hashMap_get(import->proxies, requestingBundle);
+    if (proxy != NULL) {
+        proxy->count -= 1;
+        if (proxy->count == 0) {
+            hashMap_remove(import->proxies, requestingBundle);
+            importRegistration_destroyProxy(proxy);
+        }
+    }
+    pthread_mutex_unlock(&import->proxiesMutex);
 }
 
 static celix_status_t importRegistration_findAndParseInterfaceDescriptor(celix_bundle_context_t * const context, celix_bundle_t * const bundle, char const * const name, dyn_interface_type **out) {
@@ -341,11 +334,7 @@
         celix_properties_t *metadata = NULL;
         bool cont = remoteInterceptorHandler_invokePreProxyCall(import->interceptorsHandler, import->endpoint->properties, entry->name, &metadata);
         if (cont) {
-            celixThreadMutex_lock(&import->mutex);
-            if (import->send != NULL) {
-                import->send(import->sendHandle, import->endpoint, invokeRequest, metadata, &reply, &rc);
-            }
-            celixThreadMutex_unlock(&import->mutex);
+            import->send(import->sendHandle, import->endpoint, invokeRequest, metadata, &reply, &rc);
             //printf("request sended. got reply '%s' with status %i\n", reply, rc);
 
             if (rc == 0 && dynFunction_hasReturn(entry->dynFunc)) {
@@ -376,33 +365,6 @@
     }
 }
 
-celix_status_t importRegistration_ungetService(import_registration_t *import, celix_bundle_t *bundle, service_registration_t *registration, void **out) {
-    celix_status_t  status = CELIX_SUCCESS;
-
-    assert(import != NULL);
-    assert(import->proxies != NULL);
-
-    pthread_mutex_lock(&import->proxiesMutex);
-
-    struct service_proxy *proxy = hashMap_get(import->proxies, bundle);
-    if (proxy != NULL) {
-        if (*out == proxy->service) {
-            proxy->count -= 1;
-        } else {
-            status = CELIX_ILLEGAL_ARGUMENT;
-        }
-
-        if (proxy->count == 0) {
-            hashMap_remove(import->proxies, bundle);
-            importRegistration_destroyProxy(proxy);
-        }
-    }
-
-    pthread_mutex_unlock(&import->proxiesMutex);
-
-    return status;
-}
-
 static void importRegistration_destroyProxy(struct service_proxy *proxy) {
     if (proxy != NULL) {
         if (proxy->intf != NULL) {
@@ -415,13 +377,6 @@
     }
 }
 
-
-celix_status_t importRegistration_close(import_registration_t *registration) {
-    celix_status_t status = CELIX_SUCCESS;
-    importRegistration_stop(registration);
-    return status;
-}
-
 celix_status_t importRegistration_getException(import_registration_t *registration) {
     celix_status_t status = CELIX_SUCCESS;
     //TODO
diff --git a/bundles/remote_services/remote_service_admin_dfi/src/import_registration_dfi.h b/bundles/remote_services/remote_service_admin_dfi/src/import_registration_dfi.h
index c99fcee..75d40bb 100644
--- a/bundles/remote_services/remote_service_admin_dfi/src/import_registration_dfi.h
+++ b/bundles/remote_services/remote_service_admin_dfi/src/import_registration_dfi.h
@@ -27,18 +27,17 @@
 
 typedef void (*send_func_type)(void *handle, endpoint_description_t *endpointDescription, char *request, celix_properties_t *metadata, char **reply, int* replyStatus);
 
-celix_status_t importRegistration_create(celix_bundle_context_t *context, endpoint_description_t *description, const char *classObject, const char* serviceVersion, FILE *logFile,
-                                         import_registration_t **import);
-celix_status_t importRegistration_close(import_registration_t *import);
+celix_status_t importRegistration_create(
+        celix_bundle_context_t *context,
+        endpoint_description_t *description,
+        const char *classObject,
+        const char* serviceVersion,
+        send_func_type sendFn,
+        void* sendFnHandle,
+        FILE *logFile,
+        import_registration_t **import);
 void importRegistration_destroy(import_registration_t *import);
 
-celix_status_t importRegistration_setSendFn(import_registration_t *reg,
-                                            send_func_type,
-                                            void *handle);
 celix_status_t importRegistration_start(import_registration_t *import);
-celix_status_t importRegistration_stop(import_registration_t *import);
-
-celix_status_t importRegistration_getService(import_registration_t *import, celix_bundle_t *bundle, service_registration_t *registration, void **service);
-celix_status_t importRegistration_ungetService(import_registration_t *import, celix_bundle_t *bundle, service_registration_t *registration, void **service);
 
 #endif //CELIX_IMPORT_REGISTRATION_DFI_H
diff --git a/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_activator.c b/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_activator.c
index 9ad6f0f..b524b45 100644
--- a/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_activator.c
+++ b/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_activator.c
@@ -17,102 +17,58 @@
  * under the License.
  */
 
-#include <stdlib.h>
-#include <remote_service_admin.h>
+#include "celix_api.h"
 
 #include "remote_service_admin_dfi.h"
-
-#include "bundle_activator.h"
-#include "service_registration.h"
-
 #include "export_registration_dfi.h"
 #include "import_registration_dfi.h"
 
-struct activator {
-	remote_service_admin_t *admin;
-	remote_service_admin_service_t *adminService;
-	service_registration_t *registration;
-};
+typedef struct celix_remote_service_admin_activator {
+    remote_service_admin_t *admin;
+    remote_service_admin_service_t adminService;
+    long svcIdRsa;
+} celix_remote_service_admin_activator_t;
 
-celix_status_t bundleActivator_create(celix_bundle_context_t *context, void **userData) {
-	celix_status_t status = CELIX_SUCCESS;
-	struct activator *activator;
-
-	activator = calloc(1, sizeof(*activator));
-	if (!activator) {
-		status = CELIX_ENOMEM;
-	} else {
-		activator->admin = NULL;
-		activator->registration = NULL;
-
-		*userData = activator;
-	}
-
-	return status;
-}
-
-celix_status_t bundleActivator_start(void * userData, celix_bundle_context_t *context) {
-	celix_status_t status = CELIX_SUCCESS;
-	struct activator *activator = userData;
-	remote_service_admin_service_t *remoteServiceAdmin = NULL;
-
-	status = remoteServiceAdmin_create(context, &activator->admin);
-	if (status == CELIX_SUCCESS) {
-		remoteServiceAdmin = calloc(1, sizeof(*remoteServiceAdmin));
-		if (!remoteServiceAdmin) {
-			status = CELIX_ENOMEM;
-		} else {
-			remoteServiceAdmin->admin = activator->admin;
-			remoteServiceAdmin->exportService = remoteServiceAdmin_exportService;
-
-			remoteServiceAdmin->getExportedServices = remoteServiceAdmin_getExportedServices;
-			remoteServiceAdmin->getImportedEndpoints = remoteServiceAdmin_getImportedEndpoints;
-			remoteServiceAdmin->importService = remoteServiceAdmin_importService;
-
-			remoteServiceAdmin->exportReference_getExportedEndpoint = exportReference_getExportedEndpoint;
-			remoteServiceAdmin->exportReference_getExportedService = exportReference_getExportedService;
-
-			remoteServiceAdmin->exportRegistration_close = remoteServiceAdmin_removeExportedService;
-			remoteServiceAdmin->exportRegistration_getException = exportRegistration_getException;
-			remoteServiceAdmin->exportRegistration_getExportReference = exportRegistration_getExportReference;
-
-			remoteServiceAdmin->importReference_getImportedEndpoint = importReference_getImportedEndpoint;
-			remoteServiceAdmin->importReference_getImportedService = importReference_getImportedService;
-
-			remoteServiceAdmin->importRegistration_close = remoteServiceAdmin_removeImportedService;
-			remoteServiceAdmin->importRegistration_getException = importRegistration_getException;
-			remoteServiceAdmin->importRegistration_getImportReference = importRegistration_getImportReference;
-
-			status = bundleContext_registerService(context, OSGI_RSA_REMOTE_SERVICE_ADMIN, remoteServiceAdmin, NULL, &activator->registration);
-			activator->adminService = remoteServiceAdmin;
-		}
-	}
-
-	return status;
-}
-
-celix_status_t bundleActivator_stop(void * userData, celix_bundle_context_t *context) {
+static celix_status_t celix_rsa_start(celix_remote_service_admin_activator_t* activator, celix_bundle_context_t* ctx) {
     celix_status_t status = CELIX_SUCCESS;
-    struct activator *activator = userData;
+    activator->svcIdRsa = -1;
 
-    serviceRegistration_unregister(activator->registration);
-    activator->registration = NULL;
+    status = remoteServiceAdmin_create(ctx, &activator->admin);
+    if (status == CELIX_SUCCESS) {
+        activator->adminService.admin = activator->admin;
+        activator->adminService.exportService = remoteServiceAdmin_exportService;
 
-    remoteServiceAdmin_stop(activator->admin);
-    remoteServiceAdmin_destroy(&activator->admin);
+        activator->adminService.getExportedServices = remoteServiceAdmin_getExportedServices;
+        activator->adminService.getImportedEndpoints = remoteServiceAdmin_getImportedEndpoints;
+        activator->adminService.importService = remoteServiceAdmin_importService;
 
-    free(activator->adminService);
+        activator->adminService.exportReference_getExportedEndpoint = exportReference_getExportedEndpoint;
+        activator->adminService.exportReference_getExportedService = exportReference_getExportedService;
+
+        activator->adminService.exportRegistration_close = remoteServiceAdmin_removeExportedService;
+        activator->adminService.exportRegistration_getException = exportRegistration_getException;
+        activator->adminService.exportRegistration_getExportReference = exportRegistration_getExportReference;
+
+        activator->adminService.importReference_getImportedEndpoint = importReference_getImportedEndpoint;
+        activator->adminService.importReference_getImportedService = importReference_getImportedService;
+
+        activator->adminService.importRegistration_close = remoteServiceAdmin_removeImportedService;
+        activator->adminService.importRegistration_getException = importRegistration_getException;
+        activator->adminService.importRegistration_getImportReference = importRegistration_getImportReference;
+
+        activator->svcIdRsa = celix_bundleContext_registerService(ctx, &activator->adminService, OSGI_RSA_REMOTE_SERVICE_ADMIN, NULL);
+    }
 
     return status;
 }
 
-celix_status_t bundleActivator_destroy(void * userData, celix_bundle_context_t *context) {
-	celix_status_t status = CELIX_SUCCESS;
-	struct activator *activator = userData;
-
-	free(activator);
-
-	return status;
+static celix_status_t celix_rsa_stop(celix_remote_service_admin_activator_t* activator, celix_bundle_context_t* ctx) {
+    celix_bundleContext_unregisterService(ctx, activator->svcIdRsa);
+    remoteServiceAdmin_stop(activator->admin);
+    remoteServiceAdmin_destroy(&activator->admin);
+    return CELIX_SUCCESS;
 }
 
+CELIX_GEN_BUNDLE_ACTIVATOR(celix_remote_service_admin_activator_t, celix_rsa_start, celix_rsa_stop)
+
 
diff --git a/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi.c b/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi.c
index 9de4518..ced1a08 100644
--- a/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi.c
+++ b/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi.c
@@ -91,6 +91,8 @@
     struct mg_context *ctx;
 
     FILE *logFile;
+
+    bool curlShareEnabled;
     void *curlShare;
     pthread_mutex_t curlMutexConnect;
     pthread_mutex_t curlMutexCookie;
@@ -200,6 +202,7 @@
         long port = celix_bundleContext_getPropertyAsLong(context, RSA_PORT_KEY, RSA_PORT_DEFAULT);
         const char *ip = celix_bundleContext_getProperty(context, RSA_IP_KEY, RSA_IP_DEFAULT);
         const char *interface = celix_bundleContext_getProperty(context, RSA_INTERFACE_KEY, NULL);
+        (*admin)->curlShareEnabled = celix_bundleContext_getPropertyAsBool(context, RSA_DFI_USE_CURL_SHARE_HANDLE, RSA_DFI_USE_CURL_SHARE_HANDLE_DEFAULT);
 
         char *detectedIp = NULL;
         if ((interface != NULL) && (remoteServiceAdmin_getIpAddress((char*)interface, &detectedIp) != CELIX_SUCCESS)) {
@@ -288,10 +291,11 @@
 }
 
 
-celix_status_t remoteServiceAdmin_destroy(remote_service_admin_t **admin)
-{
+celix_status_t remoteServiceAdmin_destroy(remote_service_admin_t **admin) {
     celix_status_t status = CELIX_SUCCESS;
 
+    celix_bundleContext_waitForEvents((*admin)->context);
+
     if ( (*admin)->logFile != NULL && (*admin)->logFile != stdout) {
         fclose((*admin)->logFile);
     }
@@ -320,7 +324,6 @@
         }
         for (int i = 0; i < celix_arrayList_size(admin->stopExports); ++i) {
             export_registration_t *export = celix_arrayList_get(admin->stopExports, i);
-            exportRegistration_stop(export);
             exportRegistration_destroy(export);
         }
         celix_arrayList_clear(admin->stopExports);
@@ -365,7 +368,6 @@
             celixThreadMutex_unlock(&admin->stopExportsMutex);
         } else {
             exportRegistration_waitTillNotUsed(export);
-            exportRegistration_stop(export);
             exportRegistration_destroy(export);
         }
     }
@@ -397,7 +399,6 @@
     for (i = 0; i < size ; i += 1) {
         import_registration_t *import = arrayList_get(admin->importedServices, i);
         if (import != NULL) {
-            importRegistration_stop(import);
             importRegistration_destroy(import);
         }
     }
@@ -617,7 +618,6 @@
             export_registration_t *registration = NULL;
 
             remoteServiceAdmin_createEndpointDescription(admin, reference, properties, (char *) interface, &endpoint);
-            //TODO precheck if descriptor exists
             status = exportRegistration_create(admin->loghelper, reference, endpoint, admin->context, admin->logFile,
                                                &registration);
             if (status == CELIX_SUCCESS) {
@@ -841,10 +841,9 @@
 
         if (objectClass != NULL) {
             status = importRegistration_create(admin->context, endpointDescription, objectClass, serviceVersion,
-                                               admin->logFile, &import);
-        }
-        if (status == CELIX_SUCCESS && import != NULL) {
-            importRegistration_setSendFn(import, (send_func_type) remoteServiceAdmin_send, admin);
+                                               (send_func_type )remoteServiceAdmin_send, admin,
+                                               admin->logFile,
+                                               &import);
         }
 
         if (status == CELIX_SUCCESS && import != NULL) {
@@ -876,7 +875,6 @@
         current = arrayList_get(admin->importedServices, i);
         if (current == registration) {
             arrayList_remove(admin->importedServices, i);
-            importRegistration_close(current);
             importRegistration_destroy(current);
             break;
         }
@@ -951,8 +949,9 @@
         curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, remoteServiceAdmin_write);
         curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&get);
         curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, (curl_off_t)post.size);
-        curl_easy_setopt(curl, CURLOPT_SHARE, rsa->curlShare);
-        //celix_logHelper_log(rsa->loghelper, CELIX_LOG_LEVEL_DEBUG, "RSA: Performing curl post\n");
+        if (rsa->curlShareEnabled) {
+            curl_easy_setopt(curl, CURLOPT_SHARE, rsa->curlShare);
+        }
         res = curl_easy_perform(curl);
 
         fputc('\0', get.stream);
diff --git a/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi_constants.h b/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi_constants.h
index ceabf13..1f31702 100644
--- a/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi_constants.h
+++ b/bundles/remote_services/remote_service_admin_dfi/src/remote_service_admin_dfi_constants.h
@@ -33,12 +33,23 @@
 #define RSA_LOG_CALLS_FILE_KEY          "RSA_LOG_CALLS_FILE"
 #define RSA_LOG_CALLS_FILE_DEFAULT      "stdout"
 
-
-
-
 #define RSA_DFI_CONFIGURATION_TYPE      "org.amdatu.remote.admin.http"
 #define RSA_DFI_ENDPOINT_URL            "org.amdatu.remote.admin.http.url"
 
+/**
+ * @brief Remote Service Admin DFI environment property (named "RSA_DFI_USE_CURL_SHARE_HANDLE") which specified
+ * whether the RSA DFI should use curl's share handle.
+ *
+ * The curl share handle has a significant performance boost by sharing DNS, COOKIE en CONNECTIONS over multiple calls,
+ * but can also introduce some issues (based on experience)
+ *
+ * The property is of the type boolean and the default is false
+ */
+#define RSA_DFI_USE_CURL_SHARE_HANDLE           "RSA_DFI_USE_CURL_SHARE_HANDLE"
 
+/**
+ * @brief Default value for the enviroment property RSA_DFI_USE_CURL_SHARE_HANDLE
+ */
+#define RSA_DFI_USE_CURL_SHARE_HANDLE_DEFAULT   false
 
 #endif //CELIX_REMOTE_SERVICE_ADMIN_DFI_CONSTANTS_H
diff --git a/bundles/remote_services/rsa_common/src/remote_interceptors_handler.c b/bundles/remote_services/rsa_common/src/remote_interceptors_handler.c
index 08ff711..c1f830f 100644
--- a/bundles/remote_services/rsa_common/src/remote_interceptors_handler.c
+++ b/bundles/remote_services/rsa_common/src/remote_interceptors_handler.c
@@ -65,20 +65,22 @@
             opts.callbackHandle = *handler;
             opts.addWithProperties = remoteInterceptorsHandler_addInterceptor;
             opts.removeWithProperties = remoteInterceptorsHandler_removeInterceptor;
-            (*handler)->interceptorsTrackerId = celix_bundleContext_trackServicesWithOptions(ctx, &opts);
+            (*handler)->interceptorsTrackerId = celix_bundleContext_trackServicesWithOptionsAsync(ctx, &opts);
         }
     }
 
     return status;
 }
 
-celix_status_t remoteInterceptorsHandler_destroy(remote_interceptors_handler_t *handler) {
-    celix_bundleContext_stopTracker(handler->ctx, handler->interceptorsTrackerId);
-
+static void remoteInterceptorsHandler_destroyCallback(void* data) {
+    remote_interceptors_handler_t *handler = data;
     celix_arrayList_destroy(handler->interceptors);
     celixThreadMutex_destroy(&handler->lock);
     free(handler);
+}
 
+celix_status_t remoteInterceptorsHandler_destroy(remote_interceptors_handler_t *handler) {
+    celix_bundleContext_stopTrackerAsync(handler->ctx, handler->interceptorsTrackerId, handler, remoteInterceptorsHandler_destroyCallback);
     return CELIX_SUCCESS;
 }
 
diff --git a/bundles/remote_services/topology_manager/CMakeLists.txt b/bundles/remote_services/topology_manager/CMakeLists.txt
index d65526c..0425934 100644
--- a/bundles/remote_services/topology_manager/CMakeLists.txt
+++ b/bundles/remote_services/topology_manager/CMakeLists.txt
@@ -30,11 +30,7 @@
 target_link_libraries(rsa_topology_manager PRIVATE Celix::log_helper Celix::deprecated_rsa_spi)
 
 if (ENABLE_TESTING)
-    find_package(CppUTest REQUIRED)
     find_package(Jansson REQUIRED)
-
-    include_directories("SYSTEM PRIVATE ${CppUTest_INCLUDE_DIR}")
-    include_directories("SYSTEM PRIVATE ${CPPUTEST_EXT_INCLUDE_DIR}")
     add_subdirectory(tms_tst)
 endif (ENABLE_TESTING)
 
diff --git a/bundles/remote_services/topology_manager/src/activator.c b/bundles/remote_services/topology_manager/src/activator.c
index d2aa195..e074c68 100644
--- a/bundles/remote_services/topology_manager/src/activator.c
+++ b/bundles/remote_services/topology_manager/src/activator.c
@@ -201,11 +201,11 @@
     bundleContext_registerService(context, (char *) OSGI_FRAMEWORK_LISTENER_HOOK_SERVICE_NAME, hookService, NULL, &activator->hook);
 
     if (status == CELIX_SUCCESS) {
-        status = serviceTracker_open(activator->exportedServicesTracker);
+        serviceTracker_open(activator->remoteServiceAdminTracker);
     }
 
     if (status == CELIX_SUCCESS) {
-        serviceTracker_open(activator->remoteServiceAdminTracker);
+        status = serviceTracker_open(activator->exportedServicesTracker);
     }
 
     if (status == CELIX_SUCCESS) {
diff --git a/bundles/remote_services/topology_manager/tms_tst/CMakeLists.txt b/bundles/remote_services/topology_manager/tms_tst/CMakeLists.txt
index 82a7136..2a7442d 100644
--- a/bundles/remote_services/topology_manager/tms_tst/CMakeLists.txt
+++ b/bundles/remote_services/topology_manager/tms_tst/CMakeLists.txt
@@ -29,18 +29,13 @@
 add_subdirectory(bundle)
 add_subdirectory(disc_mock)
 
-#SET(CMAKE_SKIP_BUILD_RPATH  FALSE) #TODO needed?
-#SET(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) #TODO needed?
-#SET(CMAKE_INSTALL_RPATH "${PROJECT_BINARY_DIR}/framework" "${PROJECT_BINARY_DIR}/utils" "${PROJECT_BINARY_DIR}/dfi")
-
 add_executable(test_tm_scoped
-    run_tests.cpp
-    tms_tests.cpp
+        tms_tests.cpp
 )
 target_include_directories(test_tm_scoped SYSTEM PRIVATE ${CppUTest_INCLUDE_DIR} PRIVATE ../src ../include)
 target_link_libraries(test_tm_scoped PRIVATE
         Celix::framework
-        ${CppUTest_LIBRARY}
+        GTest::gtest GTest::gtest_main
         Jansson
         calculator_api
         Celix::rsa_common
diff --git a/bundles/remote_services/topology_manager/tms_tst/run_tests.cpp b/bundles/remote_services/topology_manager/tms_tst/run_tests.cpp
deleted file mode 100644
index 1da4975..0000000
--- a/bundles/remote_services/topology_manager/tms_tst/run_tests.cpp
+++ /dev/null
@@ -1,25 +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 <CppUTest/TestHarness.h>
-#include "CppUTest/CommandLineTestRunner.h"
-
-int main(int argc, char** argv) {
-    return RUN_ALL_TESTS(argc, argv);
-}
diff --git a/bundles/remote_services/topology_manager/tms_tst/scope2.json b/bundles/remote_services/topology_manager/tms_tst/scope2.json
index 0d2daef..3474b72 100644
--- a/bundles/remote_services/topology_manager/tms_tst/scope2.json
+++ b/bundles/remote_services/topology_manager/tms_tst/scope2.json
@@ -2,7 +2,7 @@
 "exportServices": [
 {
 "filter": "(&(objectClass=org.apache.celix.calc.api.Calculator)(module=Calc))",
-"zone": "thales"
+"zone": "a_zone"
 },
 {
 "filter": "(objectClass=org.apache.celix.calc.*)",
diff --git a/bundles/remote_services/topology_manager/tms_tst/scope3.json b/bundles/remote_services/topology_manager/tms_tst/scope3.json
index efa1b40..0768a99 100644
--- a/bundles/remote_services/topology_manager/tms_tst/scope3.json
+++ b/bundles/remote_services/topology_manager/tms_tst/scope3.json
@@ -2,7 +2,7 @@
 "exportServices": [
 {
 "filter": "(&(objectClass=org.apache.celix.calc.api.Calculator)(module=Calc))",
-"zone": "thales",
+"zone": "a_zone",
 "key1": "value1"
 },
 {
diff --git a/bundles/remote_services/topology_manager/tms_tst/scope4.json b/bundles/remote_services/topology_manager/tms_tst/scope4.json
index 5f98cd8..508937a 100644
--- a/bundles/remote_services/topology_manager/tms_tst/scope4.json
+++ b/bundles/remote_services/topology_manager/tms_tst/scope4.json
@@ -2,7 +2,7 @@
 "exportServices": [
 {
 "filter": "(objectClass=org.apache.celix.calc.api.Calculator)",
-"zone": "thales"
+"zone": "a_zone"
 },
 {
 "filter": "(objectClass=org.apache.celix.calc.*)",
@@ -14,7 +14,7 @@
 "filter": "(key3=value3)"
 },
 {
-"filter": "(zone=thales)"
+"filter": "(zone=a_zone)"
 }
 ]
 }
diff --git a/bundles/remote_services/topology_manager/tms_tst/tms_tests.cpp b/bundles/remote_services/topology_manager/tms_tst/tms_tests.cpp
index e21c3cc..92bc86b 100644
--- a/bundles/remote_services/topology_manager/tms_tst/tms_tests.cpp
+++ b/bundles/remote_services/topology_manager/tms_tst/tms_tests.cpp
@@ -16,21 +16,13 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-/**
- * topology_manager_scoped_test.cpp
- *
- *  \date       Feb 11, 2013
- *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright  Apache License, Version 2.0
- */
+
+#include "gtest/gtest.h"
 
 #include <stdlib.h>
 #include <stdio.h>
 
-#include "CppUTest/TestHarness.h"
-#include "CppUTest/TestHarness_c.h"
-#include "CppUTest/CommandLineTestRunner.h"
-#include "CppUTestExt/MockSupport.h"
+#include "celix_bundle_context.h"
 
 extern "C" {
 
@@ -89,42 +81,42 @@
     static void setupFm(void) {
         int rc = 0;
         rc = celixLauncher_launch("config.properties", &framework);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
 
         celix_bundle_t *bundle = NULL;
         rc = framework_getFrameworkBundle(framework, &bundle);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
 
         rc = bundle_getContext(bundle, &context);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
 
         rc = bundleContext_getServiceReference(context, (char *)OSGI_RSA_REMOTE_SERVICE_ADMIN, &rsaRef);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
-        CHECK(rsaRef != NULL);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
+        EXPECT_TRUE(rsaRef != NULL);
 
         rc = bundleContext_getService(context, rsaRef, (void **)&rsa);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
 
         rc = bundleContext_getServiceReference(context, (char *)TOPOLOGYMANAGER_SCOPE_SERVICE, &scopeServiceRef);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
-        CHECK(scopeServiceRef != NULL);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
+        EXPECT_TRUE(scopeServiceRef != NULL);
 
         rc = bundleContext_getService(context, scopeServiceRef, (void **)&tmScopeService);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
 
         rc = bundleContext_getServiceReference(context, (char *)CALCULATOR_SERVICE, &calcRef);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
-        CHECK(calcRef != NULL);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
+        EXPECT_TRUE(calcRef != NULL);
 
         rc = bundleContext_getService(context, calcRef, (void **)&calc);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
 
         rc = bundleContext_getServiceReference(context, (char *)DISC_MOCK_SERVICE_NAME, &discRef);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
-        CHECK(discRef != NULL);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
+        EXPECT_TRUE(discRef != NULL);
 
         rc = bundleContext_getService(context, discRef, (void **)&discMock);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
 
         printf("==> Finished setup.\n");
     }
@@ -134,24 +126,24 @@
         int rc = 0;
 
         rc = bundleContext_ungetService(context, scopeServiceRef, NULL);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
         rc = bundleContext_ungetServiceReference(context,scopeServiceRef);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
 
         rc = bundleContext_ungetService(context, calcRef, NULL);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
         rc = bundleContext_ungetServiceReference(context,calcRef);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
 
         rc = bundleContext_ungetService(context, rsaRef, NULL);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
         rc = bundleContext_ungetServiceReference(context,rsaRef);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
 
         rc = bundleContext_ungetService(context, discRef, NULL);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
         rc = bundleContext_ungetServiceReference(context,discRef);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
 
         celixLauncher_stop(framework);
         celixLauncher_waitForShutdown(framework);
@@ -180,66 +172,70 @@
     static void setupFmImport(void) {
         int rc = 0;
         rc = celixLauncher_launch("config_import.properties", &framework);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
 
         celix_bundle_t *bundle = NULL;
         rc = framework_getFrameworkBundle(framework, &bundle);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
 
         rc = bundle_getContext(bundle, &context);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
+
+        celix_array_list_t* bundles = celix_bundleContext_listBundles(context);
+        EXPECT_EQ(celix_arrayList_size(bundles), 4); //rsa, calculator, topman, test bundle
+        celix_arrayList_destroy(bundles);
 
         rc = bundleContext_getServiceReference(context, (char *)OSGI_RSA_REMOTE_SERVICE_ADMIN, &rsaRef);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
-        CHECK(rsaRef != NULL);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
+        EXPECT_TRUE(rsaRef != NULL);
 
         rc = bundleContext_getService(context, rsaRef, (void **)&rsa);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
 
         rc = bundleContext_getServiceReference(context, (char *)TOPOLOGYMANAGER_SCOPE_SERVICE, &scopeServiceRef);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
-        CHECK(scopeServiceRef != NULL);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
+        EXPECT_TRUE(scopeServiceRef != NULL);
 
         rc = bundleContext_getService(context, scopeServiceRef, (void **)&tmScopeService);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
 
         rc = bundleContext_getServiceReference(context, (char *)TST_SERVICE_NAME, &testRef);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
-        CHECK(testRef != NULL);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
+        EXPECT_TRUE(testRef != NULL);
 
         rc = bundleContext_getService(context, testRef, (void **)&testImport);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
 
         rc = bundleContext_getServiceReference(context, (char*)OSGI_ENDPOINT_LISTENER_SERVICE, &eplRef);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
-        CHECK(eplRef != NULL);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
+        EXPECT_TRUE(eplRef != NULL);
 
         rc = bundleContext_getService(context, eplRef, (void **)&eplService);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
     }
 
     static void teardownFmImport(void) {
         int rc = 0;
 
         rc = bundleContext_ungetService(context, rsaRef, NULL);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
         rc = bundleContext_ungetServiceReference(context,rsaRef);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
 
         rc = bundleContext_ungetService(context, scopeServiceRef, NULL);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
         rc = bundleContext_ungetServiceReference(context,scopeServiceRef);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
 
         rc = bundleContext_ungetService(context, testRef, NULL);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
         rc = bundleContext_ungetServiceReference(context,testRef);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
 
         rc = bundleContext_ungetService(context, eplRef, NULL);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
         rc = bundleContext_ungetServiceReference(context,eplRef);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
 
         celixLauncher_stop(framework);
         celixLauncher_waitForShutdown(framework);
@@ -274,8 +270,8 @@
             array_list_pt bundles = NULL;
 
             int rc = bundleContext_getBundles(context, &bundles);
-            CHECK_EQUAL(0, rc);
-            CHECK_EQUAL(5, arrayList_size(bundles)); //framework, scopeService & calc & rsa
+            EXPECT_EQ(0, rc);
+            EXPECT_EQ(5, arrayList_size(bundles)); //framework, scopeService & calc & rsa
 
             /*
             int size = arrayList_size(bundles);
@@ -378,7 +374,7 @@
             printf("File error: line %d position %d\n", error.line, error.position);
             status = CELIX_FILE_IO_EXCEPTION;
         }
-        CHECK_EQUAL(CELIX_SUCCESS, status);
+        EXPECT_EQ(CELIX_SUCCESS, status);
     }
 
     /// \TEST_CASE_ID{2}
@@ -392,18 +388,18 @@
 
         printf("\nBegin: %s\n", __func__);
         scopeInit("scope.json", &nr_exported, &nr_imported);
-        CHECK_EQUAL(2, nr_exported);
-        CHECK_EQUAL(0, nr_imported);
+        EXPECT_EQ(2, nr_exported);
+        EXPECT_EQ(0, nr_imported);
 
         discMock->getEPDescriptors(discMock->handle, &epList);
         // We export one service: Calculator, which has DFI bundle info
-        CHECK_EQUAL(1, arrayList_size(epList));
+        EXPECT_EQ(1, arrayList_size(epList));
         for (unsigned int i = 0; i < arrayList_size(epList); i++) {
             endpoint_description_t *ep = (endpoint_description_t *) arrayList_get(epList, i);
             celix_properties_t *props = ep->properties;
             hash_map_entry_pt entry = hashMap_getEntry(props, (void*)"key2");
             char* value = (char*) hashMapEntry_getValue(entry);
-            STRCMP_EQUAL("inaetics", value);
+            EXPECT_STREQ("inaetics", value);
             /*
             printf("Service: %s ", ep->service);
             hash_map_iterator_pt iter = hashMapIterator_create(props);
@@ -429,17 +425,17 @@
         array_list_pt epList;
         printf("\nBegin: %s\n", __func__);
         scopeInit("scope2.json", &nr_exported, &nr_imported);
-        CHECK_EQUAL(3, nr_exported);
-        CHECK_EQUAL(1, nr_imported);
+        EXPECT_EQ(3, nr_exported);
+        EXPECT_EQ(1, nr_imported);
         discMock->getEPDescriptors(discMock->handle, &epList);
         // We export one service: Calculator, which has DFI bundle info
-        CHECK_EQUAL(1, arrayList_size(epList));
+        EXPECT_EQ(1, arrayList_size(epList));
         for (unsigned int i = 0; i < arrayList_size(epList); i++) {
             endpoint_description_t *ep = (endpoint_description_t *) arrayList_get(epList, i);
             celix_properties_t *props = ep->properties;
             hash_map_entry_pt entry = hashMap_getEntry(props, (void*)"key2");
             char* value = (char*) hashMapEntry_getValue(entry);
-            STRCMP_EQUAL("inaetics", value);
+            EXPECT_STREQ("inaetics", value);
         }
         printf("End: %s\n", __func__);
     }
@@ -454,47 +450,21 @@
         array_list_pt epList;
         printf("\nBegin: %s\n", __func__);
         scopeInit("scope3.json", &nr_exported, &nr_imported);
-        CHECK_EQUAL(3, nr_exported);
-        CHECK_EQUAL(1, nr_imported);
+        EXPECT_EQ(3, nr_exported);
+        EXPECT_EQ(1, nr_imported);
         discMock->getEPDescriptors(discMock->handle, &epList);
         // We export one service: Calculator, which has DFI bundle info
-        CHECK_EQUAL(1, arrayList_size(epList));
+        EXPECT_EQ(1, arrayList_size(epList));
         for (unsigned int i = 0; i < arrayList_size(epList); i++) {
             endpoint_description_t *ep = (endpoint_description_t *) arrayList_get(epList, i);
             celix_properties_t *props = ep->properties;
             hash_map_entry_pt entry = hashMap_getEntry(props, (void *)"key2");
             char* value = (char*) hashMapEntry_getValue(entry);
-            STRCMP_EQUAL("inaetics", value);
+            EXPECT_STREQ("inaetics", value);
         }
         printf("End: %s\n", __func__);
     }
 
-    /// \TEST_CASE_ID{5}
-    /// \TEST_CASE_TITLE{Test scope initialisation}
-    /// \TEST_CASE_REQ{REQ-5}
-    /// \TEST_CASE_DESC Invalid input file, two partly matching filters with same key name
-    /*
-    static void testScope4(void) {
-        int nr_exported;
-        int nr_imported;
-        array_list_pt epList;
-        printf("\nBegin: %s\n", __func__);
-        scopeInit("scope4.json", &nr_exported, &nr_imported);
-        CHECK_EQUAL(2, nr_exported);
-        discMock->getEPDescriptors(discMock->handle, &epList);
-        // We export two services: Calculator and Calculator2, but only 1 has DFI bundle info
-        CHECK_EQUAL(1, arrayList_size(epList));
-        for (unsigned int i = 0; i < arrayList_size(epList); i++) {
-            endpoint_description_t *ep = (endpoint_description_t *) arrayList_get(epList, i);
-            celix_properties_t *props = ep->properties;
-            hash_map_entry_pt entry = hashMap_getEntry(props, (void*)"zone");
-            char* value = (char*) hashMapEntry_getValue(entry);
-            STRCMP_EQUAL("inaetics", value);
-            CHECK_TRUE((entry == NULL));
-        }
-        printf("End: %s\n", __func__);
-    }*/
-
     /// \TEST_CASE_ID{6}
     /// \TEST_CASE_TITLE{Test import scope}
     /// \TEST_CASE_REQ{REQ-3}
@@ -505,7 +475,7 @@
         printf("\nBegin: %s\n", __func__);
 
         scopeInit("scope.json", &nr_exported, &nr_imported);
-        CHECK_EQUAL(0, nr_imported);
+        EXPECT_EQ(0, nr_imported);
         int rc = 0;
 
         endpoint_description_t *endpoint = NULL;
@@ -516,23 +486,27 @@
         celix_properties_set(props, OSGI_RSA_ENDPOINT_ID, "eec5404d-51d0-47ef-8d86-c825a8beda42-42");
         celix_properties_set(props, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, TST_CONFIGURATION_TYPE);
         celix_properties_set(props, OSGI_FRAMEWORK_OBJECTCLASS, "org.apache.celix.test.MyBundle");
-        celix_properties_set(props, "service.version", "1.0.0"); //TODO find out standard in osgi spec
-        celix_properties_set(props, "zone", "thales");
+        celix_properties_set(props, "service.version", "1.0.0");
+        celix_properties_set(props, "zone", "a_zone");
 
         rc = endpointDescription_create(props, &endpoint);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
 
         rc = eplService->endpointAdded(eplService->handle, endpoint, NULL);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
+
+        celix_framework_waitForEmptyEventQueue(framework);
 
         bool imported = testImport->IsImported(testImport);
-        CHECK_EQUAL(true, imported);
+        EXPECT_EQ(true, imported);
 
         rc = eplService->endpointRemoved(eplService->handle, endpoint, NULL);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
+
+        celix_framework_waitForEmptyEventQueue(framework);
 
         rc = endpointDescription_destroy(endpoint);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
 
         printf("*****After importService\n");
         printf("End: %s\n", __func__);
@@ -548,7 +522,7 @@
         printf("\nBegin: %s\n", __func__);
 
         scopeInit("scope2.json", &nr_exported, &nr_imported);
-        CHECK_EQUAL(1, nr_imported);
+        EXPECT_EQ(1, nr_imported);
         int rc = 0;
 
         endpoint_description_t *endpoint = NULL;
@@ -559,23 +533,27 @@
         celix_properties_set(props, OSGI_RSA_ENDPOINT_ID, "eec5404d-51d0-47ef-8d86-c825a8beda42-42");
         celix_properties_set(props, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, TST_CONFIGURATION_TYPE);
         celix_properties_set(props, OSGI_FRAMEWORK_OBJECTCLASS, "org.apache.celix.test.MyBundle");
-        celix_properties_set(props, "service.version", "1.0.0"); //TODO find out standard in osgi spec
-        celix_properties_set(props, "zone", "thales");
+        celix_properties_set(props, "service.version", "1.0.0");
+        celix_properties_set(props, "zone", "a_zone");
 
         rc = endpointDescription_create(props, &endpoint);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
 
         rc = eplService->endpointAdded(eplService->handle, endpoint, NULL);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
+
+        celix_framework_waitForEmptyEventQueue(framework);
 
         bool imported = testImport->IsImported(testImport);
-        CHECK_EQUAL(true, imported);
+        EXPECT_EQ(true, imported);
 
         rc = eplService->endpointRemoved(eplService->handle, endpoint, NULL);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
+
+        celix_framework_waitForEmptyEventQueue(framework);
 
         rc = endpointDescription_destroy(endpoint);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
 
         printf("End: %s\n", __func__);
     }
@@ -590,7 +568,7 @@
         printf("\nBegin: %s\n", __func__);
 
         scopeInit("scope3.json", &nr_exported, &nr_imported);
-        CHECK_EQUAL(1, nr_imported);
+        EXPECT_EQ(1, nr_imported);
         int rc = 0;
 
         endpoint_description_t *endpoint = NULL;
@@ -602,22 +580,26 @@
         celix_properties_set(props, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, TST_CONFIGURATION_TYPE);
         celix_properties_set(props, OSGI_FRAMEWORK_OBJECTCLASS, "org.apache.celix.test.MyBundle");
         celix_properties_set(props, "service.version", "1.0.0"); //TODO find out standard in osgi spec
-        celix_properties_set(props, "zone", "thales");
+        celix_properties_set(props, "zone", "a_zone");
 
         rc = endpointDescription_create(props, &endpoint);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
 
         rc = eplService->endpointAdded(eplService->handle, endpoint, NULL);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
+
+        celix_framework_waitForEmptyEventQueue(framework);
 
         bool imported = testImport->IsImported(testImport);
-        CHECK_EQUAL(false, imported);
+        EXPECT_EQ(false, imported);
 
         rc = eplService->endpointRemoved(eplService->handle, endpoint, NULL);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
+
+        celix_framework_waitForEmptyEventQueue(framework);
 
         rc = endpointDescription_destroy(endpoint);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
 
         printf("End: %s\n", __func__);
     }
@@ -632,7 +614,7 @@
         printf("\nBegin: %s\n", __func__);
 
         scopeInit("scope4.json", &nr_exported, &nr_imported);
-        CHECK_EQUAL(2, nr_imported);
+        EXPECT_EQ(2, nr_imported);
         int rc = 0;
 
         endpoint_description_t *endpoint = NULL;
@@ -643,92 +625,83 @@
         celix_properties_set(props, OSGI_RSA_ENDPOINT_ID, "eec5404d-51d0-47ef-8d86-c825a8beda42-42");
         celix_properties_set(props, OSGI_RSA_SERVICE_IMPORTED_CONFIGS, TST_CONFIGURATION_TYPE);
         celix_properties_set(props, OSGI_FRAMEWORK_OBJECTCLASS, "org.apache.celix.test.MyBundle");
-        celix_properties_set(props, "service.version", "1.0.0"); //TODO find out standard in osgi spec
-        celix_properties_set(props, "zone", "thales");
+        celix_properties_set(props, "service.version", "1.0.0");
+        celix_properties_set(props, "zone", "a_zone");
 
         rc = endpointDescription_create(props, &endpoint);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
 
         rc = eplService->endpointAdded(eplService->handle, endpoint, NULL);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
 
+        celix_framework_waitForEmptyEventQueue(framework);
+
+        celix_framework_waitForEmptyEventQueue(framework);
         bool imported = testImport->IsImported(testImport);
-        CHECK_EQUAL(true, imported);
+        EXPECT_EQ(true, imported);
 
         rc = eplService->endpointRemoved(eplService->handle, endpoint, NULL);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
+
+        celix_framework_waitForEmptyEventQueue(framework);
 
         rc = endpointDescription_destroy(endpoint);
-        CHECK_EQUAL(CELIX_SUCCESS, rc);
+        EXPECT_EQ(CELIX_SUCCESS, rc);
 
         printf("End: %s\n", __func__);
     }
 }
 
-TEST_GROUP(topology_manager_scoped_export) {
-    void setup(void) {
+class RemoteServiceTopologyAdminExportTestSuite : public ::testing::Test {
+public:
+    RemoteServiceTopologyAdminExportTestSuite() {
         setupFm();
     }
-
-    void teardown() {
+    ~RemoteServiceTopologyAdminExportTestSuite() override {
         teardownFm();
     }
+
 };
 
-TEST_GROUP(topology_manager_scoped_import) {
-    void setup(void) {
+class RemoteServiceTopologyAdminImportTestSuite : public ::testing::Test {
+public:
+    RemoteServiceTopologyAdminImportTestSuite() {
         setupFmImport();
     }
-
-    void teardown() {
+    ~RemoteServiceTopologyAdminImportTestSuite() override {
         teardownFmImport();
     }
+
 };
 
-// Test9
-TEST(topology_manager_scoped_import, scope_import_multiple) {
+TEST_F(RemoteServiceTopologyAdminImportTestSuite, scope_import_multiple) {
     testImportScopeMultiple();
 }
 
-// Test8
-TEST(topology_manager_scoped_import, scope_import_fail) {
+TEST_F(RemoteServiceTopologyAdminImportTestSuite, scope_import_fail) {
     testImportScopeFail();
 }
 
-// Test7
-TEST(topology_manager_scoped_import, scope_import_match) {
+TEST_F(RemoteServiceTopologyAdminImportTestSuite, scope_import_match) {
     testImportScopeMatch();
 }
 
-// Test6
-TEST(topology_manager_scoped_import, scope_import) {
+TEST_F(RemoteServiceTopologyAdminImportTestSuite, scope_import) {
     testImportScope();
 }
 
-// Test5
-/*
-TODO: NYI
-TEST(topology_manager_scoped_export, scope_init4) {
-    testScope4();
-}
-*/
-
-// Test4
-TEST(topology_manager_scoped_export, scope_init3) {
+TEST_F(RemoteServiceTopologyAdminExportTestSuite, scope_init3) {
     testScope3();
 }
 
-// Test3
-TEST(topology_manager_scoped_export, scope_init2) {
+TEST_F(RemoteServiceTopologyAdminExportTestSuite, scope_init2) {
     testScope2();
 }
 
-// Test2
-TEST(topology_manager_scoped_export, scope_init) {
+TEST_F(RemoteServiceTopologyAdminExportTestSuite, scope_init) {
     testScope();
 }
 
-// Test1
-TEST(topology_manager_scoped_export, init_test) {
+TEST_F(RemoteServiceTopologyAdminExportTestSuite, init_test) {
     testBundles();
 }
diff --git a/libs/framework/src/bundle_context.c b/libs/framework/src/bundle_context.c
index 1f1831d..23cffdd 100644
--- a/libs/framework/src/bundle_context.c
+++ b/libs/framework/src/bundle_context.c
@@ -899,6 +899,11 @@
     celixThreadMutex_lock(&tracker->ctx->mutex);
     hashMap_remove(tracker->ctx->stoppingTrackerEventIds, (void*)tracker->trackerId);
     celixThreadMutex_unlock(&tracker->ctx->mutex);
+    if (tracker->isFreeFilterNeeded) {
+        free((char*)tracker->opts.filter.serviceName);
+        free((char*)tracker->opts.filter.versionRange);
+        free((char*)tracker->opts.filter.filter);
+    }
     free(tracker);
 }
 
@@ -959,6 +964,11 @@
             free(bundleTracker);
         } else if (serviceTracker != NULL) {
             celix_serviceTracker_destroy(serviceTracker->tracker);
+            if (serviceTracker->isFreeFilterNeeded) {
+                free((char*)serviceTracker->opts.filter.serviceName);
+                free((char*)serviceTracker->opts.filter.versionRange);
+                free((char*)serviceTracker->opts.filter.filter);
+            }
             free(serviceTracker);
         } else if (svcTrackerTracker != NULL) {
             celix_framework_unregister(ctx->framework, ctx->bundle, svcTrackerTracker->serviceId);
@@ -1383,6 +1393,11 @@
     celixThreadMutex_unlock(&entry->ctx->mutex);
     if (cancelled) {
         //tracker creation cancelled -> entry already removed from map, but memory needs to be freed.
+        if (entry->isFreeFilterNeeded) {
+            free((char*)entry->opts.filter.serviceName);
+            free((char*)entry->opts.filter.versionRange);
+            free((char*)entry->opts.filter.filter);
+        }
         free(entry);
     } else if (entry->trackerCreatedCallback != NULL) {
         entry->trackerCreatedCallback(entry->trackerCreatedCallbackData);
@@ -1412,6 +1427,7 @@
             entry->ctx = ctx;
             entry->tracker = tracker;
             entry->opts = *opts;
+            entry->isFreeFilterNeeded = false;
             entry->createEventId = -1;
             celixThreadMutex_lock(&ctx->mutex);
             entry->trackerId = ctx->nextTrackerId++;
@@ -1426,9 +1442,16 @@
         entry->createEventId = celix_framework_nextEventId(ctx->framework);
         entry->tracker = NULL; //will be set async
         entry->opts = *opts;
+
         if (async) { //note only setting the async callback if this is a async call
             entry->trackerCreatedCallbackData = opts->trackerCreatedCallbackData;
             entry->trackerCreatedCallback = opts->trackerCreatedCallback;
+
+            //for async copying the const char* inputs
+            entry->isFreeFilterNeeded = true;
+            entry->opts.filter.serviceName = celix_utils_strdup(opts->filter.serviceName);
+            entry->opts.filter.versionRange = celix_utils_strdup(opts->filter.versionRange);
+            entry->opts.filter.filter = celix_utils_strdup(opts->filter.filter);
         }
         celixThreadMutex_lock(&ctx->mutex);
         entry->trackerId = ctx->nextTrackerId++;
diff --git a/libs/framework/src/bundle_context_private.h b/libs/framework/src/bundle_context_private.h
index 6e6d9e5..22c72f5 100644
--- a/libs/framework/src/bundle_context_private.h
+++ b/libs/framework/src/bundle_context_private.h
@@ -47,7 +47,7 @@
 	celix_service_tracker_t* tracker;
     void *trackerCreatedCallbackData;
     void (*trackerCreatedCallback)(void *trackerCreatedCallbackData);
-
+    bool isFreeFilterNeeded;
 
     //used for sync
     long createEventId;