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/12/17 19:04:55 UTC

[celix] 01/02: Refactors dep man component / service dependency to use celix_bundleContext_trackServices instead directly using service references.

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

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

commit 5740833d08ec5917495a463930d0fee92af49618
Author: Pepijn Noltes <pe...@gmail.com>
AuthorDate: Thu Dec 17 19:53:42 2020 +0100

    Refactors dep man component / service dependency to use celix_bundleContext_trackServices instead directly using service references.
---
 bundles/shell/shell/src/dm_shell_list_command.c    |   35 +-
 libs/framework/CMakeLists.txt                      |    2 +-
 libs/framework/include/celix_dm_component.h        |    8 +-
 libs/framework/include/celix_dm_info.h             |    2 +
 .../include/celix_dm_service_dependency.h          |    7 +-
 libs/framework/include/dm_service_dependency.h     |   15 -
 libs/framework/include/requirement.h               |   10 +-
 .../src/celix_dm_event.h}                          |   42 +-
 libs/framework/src/dm_component_impl.c             | 1313 ++++----------------
 libs/framework/src/dm_component_impl.h             |    4 +-
 libs/framework/src/dm_event.c                      |  103 --
 libs/framework/src/dm_event.h                      |   72 --
 libs/framework/src/dm_service_dependency.c         |  815 +++---------
 libs/framework/src/dm_service_dependency_impl.h    |   91 +-
 libs/framework/src/requirement.c                   |    2 +-
 libs/utils/CMakeLists.txt                          |    4 -
 libs/utils/gtest/CMakeLists.txt                    |    2 +
 libs/utils/gtest/src/VersionRangeTestSuite.cc      |  423 +++++++
 libs/utils/include/array_list.h                    |    7 -
 libs/utils/include/celix_utils.h                   |    5 +
 libs/utils/include/celix_version_range.h           |  144 +++
 libs/utils/include/version_range.h                 |   25 +-
 libs/utils/private/test/utils_test.cpp             |   11 +
 libs/utils/private/test/version_range_test.cpp     |  475 -------
 libs/utils/private/test/version_test.cpp           |   11 +
 libs/utils/src/utils.c                             |    4 +
 libs/utils/src/version.c                           |    8 +-
 libs/utils/src/version_range.c                     |  276 ++--
 libs/utils/src/version_range_private.h             |   15 +-
 29 files changed, 1297 insertions(+), 2634 deletions(-)

diff --git a/bundles/shell/shell/src/dm_shell_list_command.c b/bundles/shell/shell/src/dm_shell_list_command.c
index e656c90..34b0fcc 100644
--- a/bundles/shell/shell/src/dm_shell_list_command.c
+++ b/bundles/shell/shell/src/dm_shell_list_command.c
@@ -61,38 +61,41 @@ static void printFullInfo(FILE *out, bool colors, long bundleId, dm_component_in
         startColors = compInfo->active ? OK_COLOR : NOK_COLOR;
         endColors = END_COLOR;
     }
-    fprintf(out, "Component: Name=%s\n|- ID=%s, %sActive=%s%s, State=%s, Bundle=%li\n", compInfo->name, compInfo->id,
-            startColors, compInfo->active ? "true " : "false", endColors, compInfo->state, bundleId);
-    fprintf(out, "|- Interfaces (%d):\n", arrayList_size(compInfo->interfaces));
-    for (unsigned int interfCnt = 0; interfCnt < arrayList_size(compInfo->interfaces); interfCnt++) {
-        dm_interface_info_pt intfInfo = arrayList_get(compInfo->interfaces, interfCnt);
-        fprintf(out, "   |- Interface: %s\n", intfInfo->name);
+    fprintf(out, "%sComponent: Name=%s%s\n", startColors, compInfo->name, endColors);
+    fprintf(out, "|- UUID   = %s\n", compInfo->id);
+    fprintf(out, "|- Active = %s\n", compInfo->active ? "true" : "false");
+    fprintf(out, "|- State  = %s\n", compInfo->state);
+    fprintf(out, "|- Bundle = %li\n", bundleId);
+
+    fprintf(out, "|- Interfaces (%d):\n", celix_arrayList_size(compInfo->interfaces));
+    for (int interfCnt = 0; interfCnt < celix_arrayList_size(compInfo->interfaces); interfCnt++) {
+        dm_interface_info_pt intfInfo = celix_arrayList_get(compInfo->interfaces, interfCnt);
+        fprintf(out, "   |- %sInterface %i: %s%s\n", startColors, (interfCnt+1), intfInfo->name, endColors);
 
         hash_map_iterator_t iter = hashMapIterator_construct((hash_map_pt) intfInfo->properties);
         char *key = NULL;
         while ((key = hashMapIterator_nextKey(&iter)) != NULL) {
-            fprintf(out, "      | %15s = %s\n", key, properties_get(intfInfo->properties, key));
+            fprintf(out, "      | %15s = %s\n", key, celix_properties_get(intfInfo->properties, key, "!ERROR!"));
         }
     }
 
-    fprintf(out, "|- Dependencies (%d):\n", arrayList_size(compInfo->dependency_list));
-    for (unsigned int depCnt = 0; depCnt < arrayList_size(compInfo->dependency_list); depCnt++) {
+    fprintf(out, "|- Dependencies (%d):\n", celix_arrayList_size(compInfo->dependency_list));
+    for (int depCnt = 0; depCnt < celix_arrayList_size(compInfo->dependency_list); ++depCnt) {
         dm_service_dependency_info_pt dependency;
-        dependency = arrayList_get(compInfo->dependency_list, depCnt);
+        dependency = celix_arrayList_get(compInfo->dependency_list, depCnt);
         const char *depStartColors = "";
-        const char *depEndColors = "";
         if (colors) {
             if (dependency->required) {
                 depStartColors = dependency->available ? OK_COLOR : NOK_COLOR;
             } else {
                 depStartColors = dependency->available ? OK_COLOR : WARNING_COLOR;
             }
-
-            depEndColors = END_COLOR;
         }
-        fprintf(out, "   |- Dependency: %sAvailable = %s%s, Required = %s, Filter = %s\n", depStartColors,
-                dependency->available ? "true " : "false", depEndColors,
-                dependency->required ? "true " : "false", dependency->filter);
+        fprintf(out, "   |- %sDependency %i: %s%s\n", depStartColors, (depCnt+1), dependency->serviceName == NULL ? "(any)" : dependency->serviceName, endColors);
+        fprintf(out, "      | %15s = %s\n", "Available", dependency->available ? "true " : "false");
+        fprintf(out, "      | %15s = %s\n", "Required", dependency->required ? "true " : "false");
+        fprintf(out, "      | %15s = %s\n", "Version Range", dependency->versionRange == NULL ? "N/A" : dependency->versionRange);
+        fprintf(out, "      | %15s = %s\n", "Filter", dependency->filter == NULL ? "N/A" : dependency->filter);
     }
     fprintf(out, "\n");
 
diff --git a/libs/framework/CMakeLists.txt b/libs/framework/CMakeLists.txt
index 950de4e..5ac13e0 100644
--- a/libs/framework/CMakeLists.txt
+++ b/libs/framework/CMakeLists.txt
@@ -30,7 +30,7 @@ set(SOURCES
         src/celix_log.c src/celix_launcher.c
         src/celix_framework_factory.c
         src/dm_dependency_manager_impl.c src/dm_component_impl.c
-        src/dm_service_dependency.c src/dm_event.c src/celix_library_loader.c
+        src/dm_service_dependency.c src/celix_library_loader.c
 )
 add_library(framework SHARED ${SOURCES})
 set_target_properties(framework PROPERTIES OUTPUT_NAME "celix_framework")
diff --git a/libs/framework/include/celix_dm_component.h b/libs/framework/include/celix_dm_component.h
index 38bb88b..9e6b7db 100644
--- a/libs/framework/include/celix_dm_component.h
+++ b/libs/framework/include/celix_dm_component.h
@@ -47,12 +47,18 @@ typedef enum celix_dm_component_state_enum {
 typedef int (*celix_dm_cmp_lifecycle_fpt)(void *userData);
 
 /**
- * Creates a DM Component
+ * Creates a DM Component with a random generated UUID.
  * Caller has ownership.
  */
 celix_dm_component_t* celix_dmComponent_create(celix_bundle_context_t *context, const char* name);
 
 /**
+ * Creates a DM Component with a provided UUID.
+ * Caller has ownership.
+ */
+celix_dm_component_t* celix_dmComponent_createWithUUID(celix_bundle_context_t *context, const char* name, const char* UUID);
+
+/**
  * Destroys a DM Component
  */
 void celix_dmComponent_destroy(celix_dm_component_t *cmp);
diff --git a/libs/framework/include/celix_dm_info.h b/libs/framework/include/celix_dm_info.h
index d6b8ea4..b7cfda9 100644
--- a/libs/framework/include/celix_dm_info.h
+++ b/libs/framework/include/celix_dm_info.h
@@ -40,7 +40,9 @@ typedef struct celix_dm_interface_info_struct dm_interface_info_t;  //deprecated
 typedef struct celix_dm_interface_info_struct celix_dm_interface_info_t;
 
 struct celix_dm_service_dependency_info_struct {
+    char *serviceName;
     char *filter;
+    char *versionRange;
     bool available;
     bool required;
     size_t count;
diff --git a/libs/framework/include/celix_dm_service_dependency.h b/libs/framework/include/celix_dm_service_dependency.h
index 2d80fed..9ef51a8 100644
--- a/libs/framework/include/celix_dm_service_dependency.h
+++ b/libs/framework/include/celix_dm_service_dependency.h
@@ -46,12 +46,12 @@ typedef struct celix_dm_service_dependency_callback_options {
 	celix_dm_service_update_fp set;
 	celix_dm_service_update_fp add;
 	celix_dm_service_update_fp remove;
-	celix_dm_service_swap_fp swap;
+	celix_dm_service_swap_fp swap; //not used, deprecated
 
 	celix_dm_service_update_with_props_fp setWithProps;
 	celix_dm_service_update_with_props_fp addWithProps;
 	celix_dm_service_update_with_props_fp removeWithProps;
-	celix_dm_service_swap_with_props_fp swapWithProps;
+	celix_dm_service_swap_with_props_fp swapWithProps; //not used, deprecated
 } celix_dm_service_dependency_callback_options_t;
 
 #define CELIX_EMPTY_DM_SERVICE_DEPENDENCY_CALLBACK_OPTIONS { .set = NULL, \
@@ -66,6 +66,9 @@ typedef struct celix_dm_service_dependency_callback_options {
 /**
  * Create a service dependency.
  * Caller has ownership.
+ *
+ * \warning The dmServiceDependency is not thread safe when constructing or modifying.
+ *          The handling of service updates is thread safe.
  */
 celix_dm_service_dependency_t* celix_dmServiceDependency_create(void);
 
diff --git a/libs/framework/include/dm_service_dependency.h b/libs/framework/include/dm_service_dependency.h
index c846688..7d5fc2e 100644
--- a/libs/framework/include/dm_service_dependency.h
+++ b/libs/framework/include/dm_service_dependency.h
@@ -120,21 +120,6 @@ celix_status_t serviceDependency_getFilter(celix_dm_service_dependency_t *depend
  */
 celix_status_t serviceDependency_setCallbacks(celix_dm_service_dependency_t *dependency, service_set_fpt set, service_add_fpt add, service_change_fpt change, service_remove_fpt remove, service_swap_fpt swap) CELIX_DEPRECATED_ATTR;
 
-/**
- * Set the set, add, change, remove and swap function callbacks when services specified by the service dependency
- * are (respectively) set, added, changed, removed or swapped.
- * The first argument of the callbacks will be the component implement (@see component_getImplementation)
- * The second argument of th callbacks will be a pointer to an instance of a service struct of the specified service dependency.
- * The third argument of th callbacks will be a pointer to a service reference of the a service instance of the specified service dependency.
- */
-celix_status_t serviceDependency_setCallbacksWithServiceReference(celix_dm_service_dependency_t *dependency, service_set_with_ref_fpt set, service_add_with_ref_fpt add, service_change_with_ref_fpt change, service_remove_with_ref_fpt remove, service_swap_with_ref_fpt swap) CELIX_DEPRECATED_ATTR;
-
-/**
- * Specifies which field member (pointer to) to update when a service dependencies is set.
- * If provided the provided service_lock will be used for locking when updating the service instance.
- */
-celix_status_t serviceDependency_setAutoConfigure(celix_dm_service_dependency_t *dependency, celix_thread_mutex_t *service_lock, const void** field) CELIX_DEPRECATED_ATTR;
-
 #define serviceDependency_setCallbacksSafe(dep, cmpType, servType, set, add, change, remove, swap) \
 	do { \
 		int (*tmpSet)(cmpType, servType) = set; \
diff --git a/libs/framework/include/requirement.h b/libs/framework/include/requirement.h
index e726754..2b14c69 100644
--- a/libs/framework/include/requirement.h
+++ b/libs/framework/include/requirement.h
@@ -16,13 +16,6 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-/**
- * requirement.h
- *
- *  \date       Jul 12, 2010
- *  \author    	<a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright	Apache License, Version 2.0
- */
 
 #ifndef REQUIREMENT_H_
 #define REQUIREMENT_H_
@@ -31,6 +24,7 @@ typedef struct requirement *requirement_pt;
 
 #include "capability.h"
 #include "hash_map.h"
+#include "celix_version_range.h"
 #include "version_range.h"
 #ifdef __cplusplus
 extern "C" {
@@ -40,7 +34,7 @@ celix_status_t requirement_create(hash_map_pt directives, hash_map_pt attributes
 
 celix_status_t requirement_destroy(requirement_pt requirement);
 
-celix_status_t requirement_getVersionRange(requirement_pt requirement, version_range_pt *range);
+celix_status_t requirement_getVersionRange(requirement_pt requirement, celix_version_range_t **range);
 
 celix_status_t requirement_getTargetName(requirement_pt requirement, const char **targetName);
 
diff --git a/libs/utils/src/version_range_private.h b/libs/framework/src/celix_dm_event.h
similarity index 60%
copy from libs/utils/src/version_range_private.h
copy to libs/framework/src/celix_dm_event.h
index bcd8296..7a8f162 100644
--- a/libs/utils/src/version_range_private.h
+++ b/libs/framework/src/celix_dm_event.h
@@ -16,24 +16,32 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-/**
- * version_range_private.h
- *
- *  \date       Dec 18, 2012
- *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright  Apache License, Version 2.0
- */
 
-#ifndef VERSION_RANGE_PRIVATE_H_
-#define VERSION_RANGE_PRIVATE_H_
+#ifndef CELIX_DM_EVENT_H_
+#define CELIX_DM_EVENT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "celix_types.h"
+#include "celix_properties.h"
+
+typedef enum celix_dm_event_type {
+	CELIX_DM_EVENT_SVC_ADD,
+	CELIX_DM_EVENT_SVC_REM,
+    CELIX_DM_EVENT_SVC_SET
+} celix_dm_event_type_e;
 
-#include "version_range.h"
+typedef struct celix_dm_event {
+	celix_dm_service_dependency_t* dep;
+    celix_dm_event_type_e eventType;
+    void* svc;
+    const celix_properties_t* props;
+} celix_dm_event_t;
 
-struct versionRange {
-    version_pt low;
-    bool isLowInclusive;
-    version_pt high;
-    bool isHighInclusive;
-};
+#ifdef __cplusplus
+}
+#endif
 
-#endif /* VERSION_RANGE_PRIVATE_H_ */
+#endif /* CELIX_DM_EVENT_H_ */
diff --git a/libs/framework/src/dm_component_impl.c b/libs/framework/src/dm_component_impl.c
index b76f8e9..39484f9 100644
--- a/libs/framework/src/dm_component_impl.c
+++ b/libs/framework/src/dm_component_impl.c
@@ -17,25 +17,24 @@
  * under the License.
  */
 
-
-#include <stdarg.h>
 #include <stdlib.h>
 #include <string.h>
 #include <uuid/uuid.h>
+#include <celix_utils.h>
+#include <assert.h>
 
 #include "celix_constants.h"
-#include "filter.h"
+#include "celix_filter.h"
 #include "dm_component_impl.h"
-
-
-typedef struct dm_executor_struct * dm_executor_pt;
+#include "bundle_context_private.h"
+#include "framework_private.h"
 
 struct celix_dm_component_struct {
-    char id[DM_COMPONENT_MAX_ID_LENGTH];
+    char uuid[DM_COMPONENT_MAX_ID_LENGTH];
     char name[DM_COMPONENT_MAX_NAME_LENGTH];
-    bundle_context_pt context;
-    array_list_pt dm_interfaces;  //protected by mutex
 
+    celix_bundle_context_t* context;
+    bool setCLanguageProperty;
     void* implementation;
 
     celix_dm_cmp_lifecycle_fpt callbackInit;
@@ -43,18 +42,12 @@ struct celix_dm_component_struct {
     celix_dm_cmp_lifecycle_fpt callbackStop;
     celix_dm_cmp_lifecycle_fpt callbackDeinit;
 
-    array_list_pt dependencies; //protected by mutex
-    pthread_mutex_t mutex;
+    celix_thread_mutex_t mutex; //protects below
+    celix_array_list_t* providedInterfaces;
+    celix_array_list_t* dependencies;
 
     celix_dm_component_state_t state;
     bool isStarted;
-    bool active;
-
-    bool setCLanguageProperty;
-
-    hash_map_pt dependencyEvents; //protected by mutex
-
-    dm_executor_pt executor;
 };
 
 typedef struct dm_interface_struct {
@@ -64,100 +57,53 @@ typedef struct dm_interface_struct {
     long svcId;
 } dm_interface_t;
 
-struct dm_executor_struct {
-    pthread_t runningThread;
-    bool runningThreadSet;
-    celix_array_list_t *workQueue;
-    pthread_mutex_t mutex;
-};
-
-typedef struct dm_executor_task_struct {
-    celix_dm_component_t *component;
-    void (*command)(void *command_ptr, void *data);
-    void *data;
-} dm_executor_task_t;
-
-typedef struct dm_handle_event_type_struct {
-	celix_dm_service_dependency_t *dependency;
-	dm_event_pt event;
-	dm_event_pt newEvent;
-} *dm_handle_event_type_pt;
-
-static celix_status_t executor_runTasks(dm_executor_pt executor, pthread_t  currentThread __attribute__((unused)));
-static celix_status_t executor_execute(dm_executor_pt executor);
-static celix_status_t executor_executeTask(dm_executor_pt executor, celix_dm_component_t *component, void (*command), void *data);
-static celix_status_t executor_schedule(dm_executor_pt executor, celix_dm_component_t *component, void (*command), void *data);
-static celix_status_t executor_create(celix_dm_component_t *component __attribute__((unused)), dm_executor_pt *executor);
-static void executor_destroy(dm_executor_pt executor);
-
-static celix_status_t component_invokeRemoveRequiredDependencies(celix_dm_component_t *component);
-static celix_status_t component_invokeRemoveInstanceBoundDependencies(celix_dm_component_t *component);
-static celix_status_t component_invokeRemoveOptionalDependencies(celix_dm_component_t *component);
 static celix_status_t component_registerServices(celix_dm_component_t *component);
 static celix_status_t component_unregisterServices(celix_dm_component_t *component);
-static celix_status_t component_invokeAddOptionalDependencies(celix_dm_component_t *component);
-static celix_status_t component_invokeAddRequiredInstanceBoundDependencies(celix_dm_component_t *component);
-static celix_status_t component_invokeAddRequiredDependencies(celix_dm_component_t *component);
-static celix_status_t component_invokeAutoConfigInstanceBoundDependencies(celix_dm_component_t *component);
-static celix_status_t component_invokeAutoConfigDependencies(celix_dm_component_t *component);
-static celix_status_t component_configureImplementation(celix_dm_component_t *component, celix_dm_service_dependency_t *dependency);
-static celix_status_t component_allInstanceBoundAvailable(celix_dm_component_t *component, bool *available);
-static celix_status_t component_allRequiredAvailable(celix_dm_component_t *component, bool *available);
+static bool component_areAllRequiredServiceDependenciesResolved(celix_dm_component_t *component);
 static celix_status_t component_performTransition(celix_dm_component_t *component, celix_dm_component_state_t oldState, celix_dm_component_state_t newState, bool *transition);
 static celix_status_t component_calculateNewState(celix_dm_component_t *component, celix_dm_component_state_t currentState, celix_dm_component_state_t *newState);
 static celix_status_t component_handleChange(celix_dm_component_t *component);
-static celix_status_t component_startDependencies(celix_dm_component_t *component __attribute__((unused)), array_list_pt dependencies);
-static celix_status_t component_getDependencyEvent(celix_dm_component_t *component, celix_dm_service_dependency_t *dependency, dm_event_pt *event_pptr);
-static celix_status_t component_updateInstance(celix_dm_component_t *component, celix_dm_service_dependency_t *dependency, dm_event_pt event, bool update, bool add);
-
-static celix_status_t component_addTask(celix_dm_component_t *component, celix_dm_service_dependency_t *dep);
-static celix_status_t component_startTask(celix_dm_component_t *component, void * data __attribute__((unused)));
-static celix_status_t component_stopTask(celix_dm_component_t *component, void * data __attribute__((unused)));
-static celix_status_t component_removeTask(celix_dm_component_t *component, celix_dm_service_dependency_t *dependency);
-static celix_status_t component_handleEventTask(celix_dm_component_t *component, dm_handle_event_type_pt data);
-
-static celix_status_t component_handleAdded(celix_dm_component_t *component, celix_dm_service_dependency_t *dependency, dm_event_pt event);
-static celix_status_t component_handleChanged(celix_dm_component_t *component, celix_dm_service_dependency_t *dependency, dm_event_pt event);
-static celix_status_t component_handleRemoved(celix_dm_component_t *component, celix_dm_service_dependency_t *dependency, dm_event_pt event);
-static celix_status_t component_handleSwapped(celix_dm_component_t *component, celix_dm_service_dependency_t *dependency, dm_event_pt event, dm_event_pt newEvent);
-
+static celix_status_t component_handleAdd(celix_dm_component_t *component, const celix_dm_event_t* event);
+static celix_status_t component_handleRemove(celix_dm_component_t *component, const celix_dm_event_t* event);
+static celix_status_t component_handleSet(celix_dm_component_t *component, const celix_dm_event_t* event);
+static celix_status_t component_startDependencies(celix_dm_component_t *component);
 static celix_status_t component_suspend(celix_dm_component_t *component, celix_dm_service_dependency_t *dependency);
 static celix_status_t component_resume(celix_dm_component_t *component, celix_dm_service_dependency_t *dependency);
 
+
 celix_dm_component_t* celix_dmComponent_create(bundle_context_t *context, const char* name) {
+    return celix_dmComponent_createWithUUID(context, name, NULL);
+}
+
+celix_dm_component_t* celix_dmComponent_createWithUUID(bundle_context_t *context, const char* name, const char *uuid) {
     celix_dm_component_t *component = calloc(1, sizeof(*component));
 
-    //gen uuid
-    uuid_t uid;
-    uuid_generate(uid);
-    uuid_unparse(uid, component->id);
-    //snprintf(component->id, DM_COMPONENT_MAX_ID_LENGTH, "%p", component);
+    char randomUUID[DM_COMPONENT_MAX_ID_LENGTH];
+    if (uuid == NULL) {
+        //gen uuid
+        uuid_t uid;
+        uuid_generate(uid);
+        uuid_unparse(uid, randomUUID);
+        uuid = randomUUID;
+    }
+    snprintf(component->uuid, DM_COMPONENT_MAX_ID_LENGTH, "%s", uuid);
+
 
     snprintf(component->name, DM_COMPONENT_MAX_NAME_LENGTH, "%s", name == NULL ? "n/a" : name);
 
     component->context = context;
-
-    arrayList_create(&component->dm_interfaces);
-    arrayList_create(&(component)->dependencies);
-    pthread_mutex_init(&(component)->mutex, NULL);
-
     component->implementation = NULL;
-
     component->callbackInit = NULL;
     component->callbackStart = NULL;
     component->callbackStop = NULL;
     component->callbackDeinit = NULL;
-
     component->state = DM_CMP_STATE_INACTIVE;
-    component->isStarted = false;
-    component->active = false;
-
     component->setCLanguageProperty = false;
 
-    component->dependencyEvents = hashMap_create(NULL, NULL, NULL, NULL);
-
-    component->executor = NULL;
-    executor_create(component, &component->executor);
+    component->providedInterfaces = celix_arrayList_create();
+    component->dependencies = celix_arrayList_create();
+    celixThreadMutex_create(&component->mutex, NULL);
+    component->isStarted = false;
     return component;
 }
 
@@ -178,35 +124,26 @@ void component_destroy(celix_dm_component_t *component) {
 
 void celix_dmComponent_destroy(celix_dm_component_t *component) {
 	if (component) {
-		unsigned int i;
+        celix_private_dmComponent_stop(component); //all service deregistered // all svc tracker stopped
+        //TODO for async wait till events are cleared (maintain a async count + condition?)
 
-		for (i = 0; i < arrayList_size(component->dm_interfaces); i++) {
-		    dm_interface_t *interface = arrayList_get(component->dm_interfaces, i);
+		for (int i = 0; i < celix_arrayList_size(component->providedInterfaces); ++i) {
+		    dm_interface_t *interface = celix_arrayList_get(component->providedInterfaces, i);
 
-			if(interface->properties!=NULL){
-				properties_destroy(interface->properties);
+			if (interface->properties != NULL) {
+                celix_properties_destroy(interface->properties);
 			}
-		    free (interface->serviceName);
-            free (interface);
+		    free(interface->serviceName);
+            free(interface);
 		}
-		arrayList_destroy(component->dm_interfaces);
+        celix_arrayList_destroy(component->providedInterfaces);
 
-		executor_destroy(component->executor);
-
-		hash_map_iterator_pt iter = hashMapIterator_create(component->dependencyEvents);
-		while(hashMapIterator_hasNext(iter)){
-			hash_map_entry_pt entry = hashMapIterator_nextEntry(iter);
-			celix_dm_service_dependency_t *sdep = (celix_dm_service_dependency_t*)hashMapEntry_getKey(entry);
-			array_list_pt eventList = (array_list_pt)hashMapEntry_getValue(entry);
-			serviceDependency_destroy(&sdep);
-			arrayList_destroy(eventList);
+		for (int i = 0; i < celix_arrayList_size(component->dependencies); ++i) {
+		    celix_dm_service_dependency_t* dep = celix_arrayList_get(component->dependencies, i);
+		    celix_dmServiceDependency_destroy(dep);
 		}
-		hashMapIterator_destroy(iter);
-
-		hashMap_destroy(component->dependencyEvents, false, false);
-
-		arrayList_destroy(component->dependencies);
-		pthread_mutex_destroy(&component->mutex);
+		celix_arrayList_destroy(component->dependencies);
+		celixThreadMutex_destroy(&component->mutex);
 
 		free(component);
 	}
@@ -217,41 +154,42 @@ celix_status_t component_addServiceDependency(celix_dm_component_t *component, c
 }
 
 celix_status_t celix_dmComponent_addServiceDependency(celix_dm_component_t *component, celix_dm_service_dependency_t *dep) {
-
     celix_status_t status = CELIX_SUCCESS;
+    celix_serviceDependency_setComponent(dep, component);
 
-	executor_executeTask(component->executor, component, component_addTask, dep);
-
-    return status;
-}
+    celixThreadMutex_lock(&component->mutex);
+    arrayList_add(component->dependencies, dep);
+    bool startDep = component->state != DM_CMP_STATE_INACTIVE;
 
 
-static celix_status_t component_addTask(celix_dm_component_t *component, celix_dm_service_dependency_t *dep) {
-    celix_status_t status = CELIX_SUCCESS;
+    celixThreadMutex_unlock(&component->mutex);
+    if (startDep) { //TODO race condition, fix with asyn branch -> async track services
+        celix_serviceDependency_start(dep);
+    }
+    celixThreadMutex_lock(&component->mutex);
 
-    array_list_pt bounds = NULL;
-    arrayList_create(&bounds);
+    component_handleChange(component);
+    celixThreadMutex_unlock(&component->mutex);
 
-    array_list_pt events = NULL;
-    arrayList_createWithEquals(event_equals, &events);
+    return status;
+}
 
-    pthread_mutex_lock(&component->mutex);
-    hashMap_put(component->dependencyEvents, dep, events);
-    arrayList_add(component->dependencies, dep);
-    pthread_mutex_unlock(&component->mutex);
+celix_status_t celix_dmComponent_removeServiceDependency(celix_dm_component_t *component, celix_dm_service_dependency_t *dep) {
 
-    serviceDependency_setComponent(dep, component);
+    celixThreadMutex_lock(&component->mutex);
+    arrayList_removeElement(component->dependencies, dep);
+    bool stopDependency = component->state != DM_CMP_STATE_INACTIVE;
 
-    if (component->state != DM_CMP_STATE_INACTIVE) {
-        serviceDependency_setInstanceBound(dep, true);
-        arrayList_add(bounds, dep);
+    celixThreadMutex_unlock(&component->mutex);
+    if (stopDependency) { //TODO race condition, fix with asyn branch -> async stop track services
+        celix_serviceDependency_stop(dep);
     }
-    component_startDependencies(component, bounds);
-    component_handleChange(component);
-
-    arrayList_destroy(bounds);
+    celix_dmServiceDependency_destroy(dep);
+    celixThreadMutex_lock(&component->mutex);
 
-    return status;
+    component_handleChange(component);
+    celixThreadMutex_unlock(&component->mutex);
+    return CELIX_SUCCESS;
 }
 
 celix_dm_component_state_t component_currentState(celix_dm_component_t *cmp) {
@@ -282,78 +220,26 @@ celix_status_t component_removeServiceDependency(celix_dm_component_t *component
     return celix_dmComponent_removeServiceDependency(component, dependency);
 }
 
-celix_status_t celix_dmComponent_removeServiceDependency(celix_dm_component_t *component, celix_dm_service_dependency_t *dependency) {
-    celix_status_t status = CELIX_SUCCESS;
-
-    executor_executeTask(component->executor, component, component_removeTask, dependency);
-
-    return status;
-}
-
-static celix_status_t component_removeTask(celix_dm_component_t *component, celix_dm_service_dependency_t *dependency) {
-    celix_status_t status = CELIX_SUCCESS;
-
-    pthread_mutex_lock(&component->mutex);
-    arrayList_removeElement(component->dependencies, dependency);
-    pthread_mutex_unlock(&component->mutex);
-
-    if (component->state != DM_CMP_STATE_INACTIVE) {
-        serviceDependency_stop(dependency);
-    }
-
-    pthread_mutex_lock(&component->mutex);
-    array_list_pt events = hashMap_remove(component->dependencyEvents, dependency);
-    pthread_mutex_unlock(&component->mutex);
-
-	serviceDependency_destroy(&dependency);
-
-    while (!arrayList_isEmpty(events)) {
-    	dm_event_pt event = arrayList_remove(events, 0);
-    	event_destroy(&event);
-    }
-    arrayList_destroy(events);
-
-    component_handleChange(component);
-
-    return status;
-}
-
 celix_status_t celix_private_dmComponent_start(celix_dm_component_t *component) {
-    celix_status_t status = CELIX_SUCCESS;
-
-    component->active = true;
-    executor_executeTask(component->executor, component, component_startTask, NULL);
-
-    return status;
-}
-
-celix_status_t component_startTask(celix_dm_component_t *component, void  *data __attribute__((unused))) {
-    celix_status_t status = CELIX_SUCCESS;
-
-    component->isStarted = true;
-    component_handleChange(component);
-
-    return status;
+    celixThreadMutex_lock(&component->mutex);
+    if (!component->isStarted) {
+        component->isStarted = true;
+        component_handleChange(component);
+    }
+    celixThreadMutex_unlock(&component->mutex);
+    return CELIX_SUCCESS;
 }
 
 celix_status_t celix_private_dmComponent_stop(celix_dm_component_t *component) {
-    celix_status_t status = CELIX_SUCCESS;
-
-    component->active = false;
-    executor_executeTask(component->executor, component, component_stopTask, NULL);
-
-    return status;
+    celixThreadMutex_lock(&component->mutex);
+    if (component->isStarted) {
+        component->isStarted = false;
+        component_handleChange(component);
+    }
+    celixThreadMutex_unlock(&component->mutex);
+    return CELIX_SUCCESS;
 }
 
-static celix_status_t component_stopTask(celix_dm_component_t *component, void *data __attribute__((unused))) {
-    celix_status_t status = CELIX_SUCCESS;
-
-    component->isStarted = false;
-    component_handleChange(component);
-    component->active = false;
-
-    return status;
-}
 
 celix_status_t component_setCLanguageProperty(celix_dm_component_t *component, bool setCLangProp) {
     return celix_dmComponent_setCLanguageProperty(component, setCLangProp);
@@ -368,7 +254,7 @@ celix_status_t component_addInterface(celix_dm_component_t *component, const cha
     return celix_dmComponent_addInterface(component, serviceName, serviceVersion, service, properties);
 }
 
-celix_status_t celix_dmComponent_addInterface(celix_dm_component_t *component, const char* serviceName, const char* serviceVersion, const void* service, properties_pt properties) {
+celix_status_t celix_dmComponent_addInterface(celix_dm_component_t *component, const char* serviceName, const char* serviceVersion, const void* service, celix_properties_t* properties) {
     celix_status_t status = CELIX_SUCCESS;
 
     dm_interface_t *interface = (dm_interface_t *) calloc(1, sizeof(*interface));
@@ -386,19 +272,19 @@ celix_status_t celix_dmComponent_addInterface(celix_dm_component_t *component, c
         celix_properties_set(properties, CELIX_FRAMEWORK_SERVICE_LANGUAGE, CELIX_FRAMEWORK_SERVICE_C_LANGUAGE);
     }
 
-    celix_properties_set(properties, CELIX_DM_COMPONENT_UUID, (char*)component->id);
+    celix_properties_set(properties, CELIX_DM_COMPONENT_UUID, (char*)component->uuid);
 
     if (interface && name) {
+        celixThreadMutex_lock(&component->mutex);
         interface->serviceName = name;
         interface->service = service;
         interface->properties = properties;
         interface->svcId= -1L;
-        celixThreadMutex_lock(&component->mutex);
-        arrayList_add(component->dm_interfaces, interface);
-        celixThreadMutex_unlock(&component->mutex);
+        celix_arrayList_add(component->providedInterfaces, interface);
         if (component->state == DM_CMP_STATE_TRACKING_OPTIONAL) {
             component_registerServices(component);
         }
+        celixThreadMutex_unlock(&component->mutex);
     } else {
         free(interface);
         free(name);
@@ -416,393 +302,182 @@ celix_status_t celix_dmComponent_removeInterface(celix_dm_component_t *component
     celix_status_t status = CELIX_ILLEGAL_ARGUMENT;
 
     celixThreadMutex_lock(&component->mutex);
-    int nof_interfaces = arrayList_size(component->dm_interfaces);
-    for (unsigned int i = 0; i < nof_interfaces; ++i) {
-        dm_interface_t *interface = (dm_interface_t *) arrayList_get(component->dm_interfaces, i);
+    int nof_interfaces = celix_arrayList_size(component->providedInterfaces);
+    dm_interface_t* removedInterface = NULL;
+    for (int i = 0; i < nof_interfaces; ++i) {
+        dm_interface_t *interface = celix_arrayList_get(component->providedInterfaces, i);
         if (interface->service == service) {
-            arrayList_remove(component->dm_interfaces, i);
-            if (component->state == DM_CMP_STATE_TRACKING_OPTIONAL) {
-                celixThreadMutex_unlock(&component->mutex);
-                component_unregisterServices(component);
-                component_registerServices(component);
-                celixThreadMutex_lock(&component->mutex);
-            }
-            status = CELIX_SUCCESS;
+            celix_arrayList_removeAt(component->providedInterfaces, i);
+            removedInterface = interface;
             break;
         }
     }
     celixThreadMutex_unlock(&component->mutex);
 
+    if (removedInterface != NULL) {
+        celix_bundleContext_unregisterService(component->context, removedInterface->svcId);
+        free(removedInterface->serviceName);
+        free(removedInterface);
+    }
+
     return status;
 }
 
-celix_status_t component_getInterfaces(celix_dm_component_t *component, array_list_pt *out) {
+celix_status_t component_getInterfaces(celix_dm_component_t *component, celix_array_list_t **out) {
     return celix_dmComponent_getInterfaces(component, out);
 }
 
-celix_status_t celix_dmComponent_getInterfaces(celix_dm_component_t *component, array_list_pt *out) {
-    celix_status_t status = CELIX_SUCCESS;
-    array_list_pt names = NULL;
-    arrayList_create(&names);
+celix_status_t celix_dmComponent_getInterfaces(celix_dm_component_t *component, celix_array_list_t **out) {
+    celix_array_list_t* names = celix_arrayList_create();
+
     celixThreadMutex_lock(&component->mutex);
-    int size = arrayList_size(component->dm_interfaces);
-    int i;
-    for (i = 0; i < size; i += 1) {
-        dm_interface_info_pt info = calloc(1, sizeof(*info));
-        dm_interface_t *interface = arrayList_get(component->dm_interfaces, i);
-        info->name = strdup(interface->serviceName);
-        properties_copy(interface->properties, &info->properties);
-        arrayList_add(names, info);
+    int size = celix_arrayList_size(component->providedInterfaces);
+    for (int i = 0; i < size; i += 1) {
+        dm_interface_info_t* info = calloc(1, sizeof(*info));
+        dm_interface_t *interface = celix_arrayList_get(component->providedInterfaces, i);
+        info->name = celix_utils_strdup(interface->serviceName);
+        info->properties = celix_properties_copy(interface->properties);
+        celix_arrayList_add(names, info);
     }
     celixThreadMutex_unlock(&component->mutex);
+    *out = names;
 
-    if (status == CELIX_SUCCESS) {
-        *out = names;
-    }
-
-    return status;
-}
-
-celix_status_t celix_private_dmComponent_handleEvent(celix_dm_component_t *component, celix_dm_service_dependency_t *dependency, dm_event_pt event) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	dm_handle_event_type_pt data = calloc(1, sizeof(*data));
-	data->dependency = dependency;
-	data->event = event;
-	data->newEvent = NULL;
-
-	status = executor_executeTask(component->executor, component, component_handleEventTask, data);
-//	component_handleEventTask(component, data);
-
-	return status;
+    return CELIX_SUCCESS;
 }
 
-static celix_status_t component_handleEventTask(celix_dm_component_t *component, dm_handle_event_type_pt data) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	switch (data->event->event_type) {
-		case DM_EVENT_ADDED:
-			component_handleAdded(component,data->dependency, data->event);
-			break;
-		case DM_EVENT_CHANGED:
-			component_handleChanged(component,data->dependency, data->event);
-			break;
-		case DM_EVENT_REMOVED:
-			component_handleRemoved(component,data->dependency, data->event);
-			break;
-		case DM_EVENT_SWAPPED:
-			component_handleSwapped(component,data->dependency, data->event, data->newEvent);
-			break;
-		default:
-			break;
-	}
-
-	free(data);
-
-	return status;
+celix_status_t celix_private_dmComponent_handleEvent(celix_dm_component_t *component, const celix_dm_event_t* event) {
+    celix_status_t status = CELIX_SUCCESS;
+    switch (event->eventType) {
+        case CELIX_DM_EVENT_SVC_ADD:
+            component_handleAdd(component, event);
+            break;
+        case CELIX_DM_EVENT_SVC_REM:
+            component_handleRemove(component, event);
+            break;
+        case CELIX_DM_EVENT_SVC_SET:
+            component_handleSet(component, event);
+            break;
+        default:
+            break;
+    }
+    return status;
 }
 
 static celix_status_t component_suspend(celix_dm_component_t *component, celix_dm_service_dependency_t *dependency) {
 	celix_status_t status = CELIX_SUCCESS;
-
-	dm_service_dependency_strategy_t strategy;
-	serviceDependency_getStrategy(dependency, &strategy);
+	dm_service_dependency_strategy_t strategy = celix_dmServiceDependency_getStrategy(dependency);
 	if (strategy == DM_SERVICE_DEPENDENCY_STRATEGY_SUSPEND &&  component->callbackStop != NULL) {
 		status = component->callbackStop(component->implementation);
 	}
-
 	return status;
 }
 
 static celix_status_t component_resume(celix_dm_component_t *component, celix_dm_service_dependency_t *dependency) {
 	celix_status_t status = CELIX_SUCCESS;
-
-	dm_service_dependency_strategy_t strategy;
-	serviceDependency_getStrategy(dependency, &strategy);
+    dm_service_dependency_strategy_t strategy = celix_dmServiceDependency_getStrategy(dependency);
 	if (strategy == DM_SERVICE_DEPENDENCY_STRATEGY_SUSPEND &&  component->callbackStop != NULL) {
 		status = component->callbackStart(component->implementation);
 	}
-
 	return status;
 }
 
-static celix_status_t component_handleAdded(celix_dm_component_t *component, celix_dm_service_dependency_t *dependency, dm_event_pt event) {
-    celix_status_t status = CELIX_SUCCESS;
-
-    pthread_mutex_lock(&component->mutex);
-    array_list_pt events = hashMap_get(component->dependencyEvents, dependency);
-    arrayList_add(events, event);
-    pthread_mutex_unlock(&component->mutex);
-
-    serviceDependency_setAvailable(dependency, true);
-
+static celix_status_t component_handleAdd(celix_dm_component_t *component, const celix_dm_event_t* event) {
+    celixThreadMutex_lock(&component->mutex);
     switch (component->state) {
-        case DM_CMP_STATE_WAITING_FOR_REQUIRED: {
-            serviceDependency_invokeSet(dependency, event);
-            bool required = false;
-            serviceDependency_isRequired(dependency, &required);
-            if (required) {
-                component_handleChange(component);
-            }
-            break;
-        }
-        case DM_CMP_STATE_INSTANTIATED_AND_WAITING_FOR_REQUIRED: {
-            bool instanceBound = false;
-            serviceDependency_isInstanceBound(dependency, &instanceBound);
-            bool required = false;
-            serviceDependency_isRequired(dependency, &required);
-            if (!instanceBound) {
-                if (required) {
-                    serviceDependency_invokeSet(dependency, event);
-                    serviceDependency_invokeAdd(dependency, event);
-                }
-                dm_event_pt event = NULL;
-                component_getDependencyEvent(component, dependency, &event);
-                component_updateInstance(component, dependency, event, false, true);
-            }
-
-            if (required) {
-                component_handleChange(component);
-            }
-            break;
-        }
         case DM_CMP_STATE_TRACKING_OPTIONAL:
-		    component_suspend(component,dependency);
-            serviceDependency_invokeSet(dependency, event);
-            serviceDependency_invokeAdd(dependency, event);
-		    component_resume(component,dependency);
-            dm_event_pt event = NULL;
-            component_getDependencyEvent(component, dependency, &event);
-            component_updateInstance(component, dependency, event, false, true);
+            if (celix_serviceDependency_hasAddCallback(event->dep)) { //if to prevent unneeded suspends
+                component_suspend(component, event->dep);
+                celix_serviceDependency_invokeAdd(event->dep, event->svc, event->props);
+                component_resume(component, event->dep);
+            }
             break;
-        default:
+        default: //DM_CMP_STATE_INACTIVE
+            celix_serviceDependency_invokeAdd(event->dep, event->svc, event->props);
             break;
     }
-
-    return status;
-}
-
-static celix_status_t component_handleChanged(celix_dm_component_t *component, celix_dm_service_dependency_t *dependency, dm_event_pt event) {
-    celix_status_t status = CELIX_SUCCESS;
-
-    pthread_mutex_lock(&component->mutex);
-    array_list_pt events = hashMap_get(component->dependencyEvents, dependency);
-    int index = arrayList_indexOf(events, event);
-    if (index < 0) {
-	pthread_mutex_unlock(&component->mutex);
-        status = CELIX_BUNDLE_EXCEPTION;
-    } else {
-        dm_event_pt old = arrayList_remove(events, (unsigned int) index);
-        arrayList_add(events, event);
-        pthread_mutex_unlock(&component->mutex);
-
-        serviceDependency_invokeSet(dependency, event);
-        switch (component->state) {
-            case DM_CMP_STATE_TRACKING_OPTIONAL:
-			    component_suspend(component,dependency);
-                serviceDependency_invokeChange(dependency, event);
-			    component_resume(component,dependency);
-                dm_event_pt hevent = NULL;
-                component_getDependencyEvent(component, dependency, &hevent);
-                component_updateInstance(component, dependency, hevent, true, false);
-                break;
-            case DM_CMP_STATE_INSTANTIATED_AND_WAITING_FOR_REQUIRED: {
-                bool instanceBound = false;
-                serviceDependency_isInstanceBound(dependency, &instanceBound);
-                if (!instanceBound) {
-                    serviceDependency_invokeChange(dependency, event);
-                    dm_event_pt hevent = NULL;
-                    component_getDependencyEvent(component, dependency, &hevent);
-                    component_updateInstance(component, dependency, hevent, true, false);
-                }
-                break;
-            }
-            default:
-                break;
-        }
-
-        event_destroy(&old);
-    }
-
-    return status;
+    component_handleChange(component);
+    celixThreadMutex_unlock(&component->mutex);
+    return CELIX_SUCCESS;
 }
 
-static celix_status_t component_handleRemoved(celix_dm_component_t *component, celix_dm_service_dependency_t *dependency, dm_event_pt event) {
-    celix_status_t status = CELIX_SUCCESS;
-
-    pthread_mutex_lock(&component->mutex);
-    array_list_pt events = hashMap_get(component->dependencyEvents, dependency);
-    int size = arrayList_size(events);
-    if (arrayList_contains(events, event)) {
-        size--;
-    }
-    pthread_mutex_unlock(&component->mutex);
-    serviceDependency_setAvailable(dependency, size > 0);
+static celix_status_t component_handleRemove(celix_dm_component_t *component, const celix_dm_event_t* event) {
+    celixThreadMutex_lock(&component->mutex);
     component_handleChange(component);
-
-    pthread_mutex_lock(&component->mutex);
-    int index = arrayList_indexOf(events, event);
-    if (index < 0) {
-	pthread_mutex_unlock(&component->mutex);
-        status = CELIX_BUNDLE_EXCEPTION;
-    } else {
-        dm_event_pt old = arrayList_remove(events, (unsigned int) index);
-        pthread_mutex_unlock(&component->mutex);
-
-
-        switch (component->state) {
-            case DM_CMP_STATE_INSTANTIATED_AND_WAITING_FOR_REQUIRED: {
-                serviceDependency_invokeSet(dependency, event);
-                bool instanceBound = false;
-                serviceDependency_isInstanceBound(dependency, &instanceBound);
-                if (!instanceBound) {
-                    bool required = false;
-                    serviceDependency_isRequired(dependency, &required);
-                    if (required) {
-                        serviceDependency_invokeRemove(dependency, event);
-                    }
-                    dm_event_pt hevent = NULL;
-                    component_getDependencyEvent(component, dependency, &hevent);
-                    component_updateInstance(component, dependency, hevent, false, false);
-                }
-                break;
+    switch (component->state) {
+        case DM_CMP_STATE_TRACKING_OPTIONAL:
+            if (celix_serviceDependency_hasRemoveCallback(event->dep)) { //if to prevent unneeded suspends
+                component_suspend(component, event->dep);
+                celix_serviceDependency_invokeRemove(event->dep, event->svc, event->props);
+                component_resume(component, event->dep);
             }
-            case DM_CMP_STATE_TRACKING_OPTIONAL:
-			    component_suspend(component,dependency);
-                serviceDependency_invokeSet(dependency, event);
-                serviceDependency_invokeRemove(dependency, event);
-			    component_resume(component,dependency);
-                dm_event_pt hevent = NULL;
-                component_getDependencyEvent(component, dependency, &hevent);
-                component_updateInstance(component, dependency, hevent, false, false);
-                break;
-            default:
-                break;
-        }
-
-        event_destroy(&event);
-        if (old) {
-            event_destroy(&old);
-        }
+            break;
+        default: //DM_CMP_STATE_INACTIVE
+            celix_serviceDependency_invokeRemove(event->dep, event->svc, event->props);
+            break;
     }
-
-    return status;
+    celixThreadMutex_unlock(&component->mutex);
+    return CELIX_SUCCESS;
 }
 
-static celix_status_t component_handleSwapped(celix_dm_component_t *component, celix_dm_service_dependency_t *dependency, dm_event_pt event, dm_event_pt newEvent) {
-    celix_status_t status = CELIX_SUCCESS;
 
-    pthread_mutex_lock(&component->mutex);
-    array_list_pt events = hashMap_get(component->dependencyEvents, dependency);
-    int index = arrayList_indexOf(events, event);
-    if (index < 0) {
-	pthread_mutex_unlock(&component->mutex);
-        status = CELIX_BUNDLE_EXCEPTION;
-    } else {
-        dm_event_pt old = arrayList_remove(events, (unsigned int) index);
-        arrayList_add(events, newEvent);
-        pthread_mutex_unlock(&component->mutex);
-
-        serviceDependency_invokeSet(dependency, event);
-
-        switch (component->state) {
-            case DM_CMP_STATE_WAITING_FOR_REQUIRED:
-                break;
-            case DM_CMP_STATE_INSTANTIATED_AND_WAITING_FOR_REQUIRED: {
-                bool instanceBound = false;
-                serviceDependency_isInstanceBound(dependency, &instanceBound);
-                if (!instanceBound) {
-                    bool required = false;
-                    serviceDependency_isRequired(dependency, &required);
-                    if (required) {
-                        serviceDependency_invokeSwap(dependency, event, newEvent);
-                    }
-                }
-                break;
+static celix_status_t component_handleSet(celix_dm_component_t *component, const celix_dm_event_t* event) {
+    celixThreadMutex_lock(&component->mutex);
+    if (event->svc == NULL) {
+        //note set with removes a service -> update state first
+        component_handleChange(component);
+    }
+    switch (component->state) {
+        case DM_CMP_STATE_TRACKING_OPTIONAL:
+            if (celix_serviceDependency_hasSetCallback(event->dep)) { //if to prevent unneeded suspends
+                component_suspend(component, event->dep);
+                celix_serviceDependency_invokeSet(event->dep, event->svc, event->props);
+                component_resume(component, event->dep);
             }
-            case DM_CMP_STATE_TRACKING_OPTIONAL:
-			    component_suspend(component,dependency);
-                serviceDependency_invokeSwap(dependency, event, newEvent);
-			    component_resume(component,dependency);
-                break;
-            default:
-                break;
-        }
-
-        event_destroy(&event);
-        if (old) {
-            event_destroy(&old);
-        }
+            break;
+        default: //DM_CMP_STATE_INACTIVE
+            celix_serviceDependency_invokeSet(event->dep, event->svc, event->props);
+            break;
     }
-
-    return status;
-}
-
-static celix_status_t component_updateInstance(celix_dm_component_t *component, celix_dm_service_dependency_t *dependency, dm_event_pt event, bool update, bool add) {
-    celix_status_t status = CELIX_SUCCESS;
-
-    bool autoConfig = false;
-
-    serviceDependency_isAutoConfig(dependency, &autoConfig);
-
-    if (autoConfig) {
-        const void *service = NULL;
-        const void **field = NULL;
-
-        if (event != NULL) {
-            event_getService(event, &service);
-        }
-        serviceDependency_getAutoConfig(dependency, &field);
-        serviceDependency_lock(dependency);
-        *field = service;
-        serviceDependency_unlock(dependency);
+    if (event->svc != NULL) {
+        component_handleChange(component);
     }
-
-    return status;
+    celixThreadMutex_unlock(&component->mutex);
+    return CELIX_SUCCESS;
 }
 
-static celix_status_t component_startDependencies(celix_dm_component_t *component __attribute__((unused)), array_list_pt dependencies) {
-    celix_status_t status = CELIX_SUCCESS;
-    array_list_pt required_dependencies = NULL;
-    arrayList_create(&required_dependencies);
-
-    for (unsigned int i = 0; i < arrayList_size(dependencies); i++) {
-        celix_dm_service_dependency_t *dependency = arrayList_get(dependencies, i);
-        bool required = false;
-        serviceDependency_isRequired(dependency, &required);
-        if (required) {
-            arrayList_add(required_dependencies, dependency);
-            continue;
+/**
+ * perform state transition. This call should be called with the component->mutex locked.
+ */
+static celix_status_t component_startDependencies(celix_dm_component_t *component) {
+    for (int i = 0; i < celix_arrayList_size(component->dependencies); i++) {
+        celix_dm_service_dependency_t *dependency = arrayList_get(component->dependencies, i);
+        if (!celix_dmServiceDependency_isStarted(dependency)) {
+            celixThreadMutex_unlock(&component->mutex);
+            celix_serviceDependency_start(dependency); //TODO race condition. unlock/lock can be removed with async branch -> async startServiceTracker
+            celixThreadMutex_lock(&component->mutex);
         }
-
-        serviceDependency_start(dependency);
-    }
-
-    for (unsigned int i = 0; i < arrayList_size(required_dependencies); i++) {
-        celix_dm_service_dependency_t *dependency = arrayList_get(required_dependencies, i);
-        serviceDependency_start(dependency);
     }
-
-    arrayList_destroy(required_dependencies);
-
-    return status;
+    return CELIX_SUCCESS;
 }
 
+/**
+ * perform state transition. This call should be called with the component->mutex locked.
+ */
 static celix_status_t component_stopDependencies(celix_dm_component_t *component) {
-    celix_status_t status = CELIX_SUCCESS;
-
-    pthread_mutex_lock(&component->mutex);
-    for (unsigned int i = 0; i < arrayList_size(component->dependencies); i++) {
+    for (int i = 0; i < celix_arrayList_size(component->dependencies); i++) {
         celix_dm_service_dependency_t *dependency = arrayList_get(component->dependencies, i);
-        pthread_mutex_unlock(&component->mutex);
-        serviceDependency_stop(dependency);
-        pthread_mutex_lock(&component->mutex);
+        if (celix_dmServiceDependency_isStarted(dependency)) {
+            celixThreadMutex_unlock(&component->mutex);
+            celix_serviceDependency_stop(dependency); //TODO race condition. unlock/lock can be removed with async branch -> async stopServiceTracker
+            celixThreadMutex_lock(&component->mutex);
+        }
     }
-    pthread_mutex_unlock(&component->mutex);
-
-    return status;
+    return CELIX_SUCCESS;
 }
 
+/**
+ * Calculate and handle state change. This call should be called with the component->mutex locked.
+ */
 static celix_status_t component_handleChange(celix_dm_component_t *component) {
     celix_status_t status = CELIX_SUCCESS;
 
@@ -814,8 +489,8 @@ static celix_status_t component_handleChange(celix_dm_component_t *component) {
         oldState = component->state;
         status = component_calculateNewState(component, oldState, &newState);
         if (status == CELIX_SUCCESS) {
-            component->state = newState;
             status = component_performTransition(component, oldState, newState, &transition);
+            component->state = newState;
         }
 
         if (status != CELIX_SUCCESS) {
@@ -826,9 +501,13 @@ static celix_status_t component_handleChange(celix_dm_component_t *component) {
     return status;
 }
 
+/**
+ * Calculate possible state change. This call should be called with the component->mutex locked.
+ */
 static celix_status_t component_calculateNewState(celix_dm_component_t *component, celix_dm_component_state_t currentState, celix_dm_component_state_t *newState) {
     celix_status_t status = CELIX_SUCCESS;
 
+    bool allResolved = component_areAllRequiredServiceDependenciesResolved(component);
     if (currentState == DM_CMP_STATE_INACTIVE) {
         if (component->isStarted) {
             *newState = DM_CMP_STATE_WAITING_FOR_REQUIRED;
@@ -839,10 +518,7 @@ static celix_status_t component_calculateNewState(celix_dm_component_t *componen
         if (!component->isStarted) {
             *newState = DM_CMP_STATE_INACTIVE;
         } else {
-            bool available = false;
-            component_allRequiredAvailable(component, &available);
-
-            if (available) {
+            if (allResolved) {
                 *newState = DM_CMP_STATE_INSTANTIATED_AND_WAITING_FOR_REQUIRED;
             } else {
                 *newState = currentState;
@@ -852,30 +528,14 @@ static celix_status_t component_calculateNewState(celix_dm_component_t *componen
         if (!component->isStarted) {
             *newState = DM_CMP_STATE_WAITING_FOR_REQUIRED;
         } else {
-            bool available = false;
-            component_allRequiredAvailable(component, &available);
-
-            if (available) {
-                bool instanceBoundAvailable = false;
-                component_allInstanceBoundAvailable(component, &instanceBoundAvailable);
-
-                if (instanceBoundAvailable) {
-                    *newState = DM_CMP_STATE_TRACKING_OPTIONAL;
-                } else {
-                    *newState = currentState;
-                }
+            if (allResolved) {
+                *newState = DM_CMP_STATE_TRACKING_OPTIONAL;
             } else {
                 *newState = currentState;
             }
         }
     } else if (currentState == DM_CMP_STATE_TRACKING_OPTIONAL) {
-        bool instanceBoundAvailable = false;
-        bool available = false;
-
-        component_allInstanceBoundAvailable(component, &instanceBoundAvailable);
-        component_allRequiredAvailable(component, &available);
-
-        if (component->isStarted && available && instanceBoundAvailable) {
+        if (component->isStarted && allResolved) {
             *newState = currentState;
         } else {
             *newState = DM_CMP_STATE_INSTANTIATED_AND_WAITING_FOR_REQUIRED;
@@ -889,26 +549,25 @@ static celix_status_t component_calculateNewState(celix_dm_component_t *componen
     return status;
 }
 
+/**
+ * perform state transition. This call should be called with the component->mutex locked.
+ */
 static celix_status_t component_performTransition(celix_dm_component_t *component, celix_dm_component_state_t oldState, celix_dm_component_state_t newState, bool *transition) {
     celix_status_t status = CELIX_SUCCESS;
-    //printf("performing transition for %s in thread %i from %i to %i\n", component->name, (int) pthread_self(), oldState, newState);
+    //TODO improve log (via bundle context?)
+    fw_log(component->context->framework->logger, CELIX_LOG_LEVEL_TRACE, "performing transition for component %s from state %i to state %i\n", component->name, oldState, newState);
 
     if (oldState == newState) {
         *transition = false;
     } else if (oldState == DM_CMP_STATE_INACTIVE && newState == DM_CMP_STATE_WAITING_FOR_REQUIRED) {
-        component_startDependencies(component, component->dependencies);
+        component_startDependencies(component);
         *transition = true;
     } else if (oldState == DM_CMP_STATE_WAITING_FOR_REQUIRED && newState == DM_CMP_STATE_INSTANTIATED_AND_WAITING_FOR_REQUIRED) {
-        component_invokeAddRequiredDependencies(component);
-        component_invokeAutoConfigDependencies(component);
         if (component->callbackInit) {
         	status = component->callbackInit(component->implementation);
         }
         *transition = true;
     } else if (oldState == DM_CMP_STATE_INSTANTIATED_AND_WAITING_FOR_REQUIRED && newState == DM_CMP_STATE_TRACKING_OPTIONAL) {
-        component_invokeAddRequiredInstanceBoundDependencies(component);
-        component_invokeAutoConfigInstanceBoundDependencies(component);
-		component_invokeAddOptionalDependencies(component);
         if (component->callbackStart) {
         	status = component->callbackStart(component->implementation);
         }
@@ -919,14 +578,11 @@ static celix_status_t component_performTransition(celix_dm_component_t *componen
         if (component->callbackStop) {
         	status = component->callbackStop(component->implementation);
         }
-		component_invokeRemoveOptionalDependencies(component);
-        component_invokeRemoveInstanceBoundDependencies(component);
         *transition = true;
     } else if (oldState == DM_CMP_STATE_INSTANTIATED_AND_WAITING_FOR_REQUIRED && newState == DM_CMP_STATE_WAITING_FOR_REQUIRED) {
     	if (component->callbackDeinit) {
     		status = component->callbackDeinit(component->implementation);
     	}
-        component_invokeRemoveRequiredDependencies(component);
         *transition = true;
     } else if (oldState == DM_CMP_STATE_WAITING_FOR_REQUIRED && newState == DM_CMP_STATE_INACTIVE) {
         component_stopDependencies(component);
@@ -936,355 +592,61 @@ static celix_status_t component_performTransition(celix_dm_component_t *componen
     return status;
 }
 
-static celix_status_t component_allRequiredAvailable(celix_dm_component_t *component, bool *available) {
-    celix_status_t status = CELIX_SUCCESS;
-
-    pthread_mutex_lock(&component->mutex);
-    *available = true;
-    for (unsigned int i = 0; i < arrayList_size(component->dependencies); i++) {
-        celix_dm_service_dependency_t *dependency = arrayList_get(component->dependencies, i);
-        bool required = false;
-        bool instanceBound = false;
-
-        serviceDependency_isRequired(dependency, &required);
-        serviceDependency_isInstanceBound(dependency, &instanceBound);
-
-        if (required && !instanceBound) {
-            bool isAvailable = false;
-            serviceDependency_isAvailable(dependency, &isAvailable);
-            if (!isAvailable) {
-                *available = false;
-                break;
-            }
-        }
-    }
-    pthread_mutex_unlock(&component->mutex);
-
-    return status;
-}
-
-static celix_status_t component_allInstanceBoundAvailable(celix_dm_component_t *component, bool *available) {
-    celix_status_t status = CELIX_SUCCESS;
-
-    pthread_mutex_lock(&component->mutex);
-    *available = true;
-    for (unsigned int i = 0; i < arrayList_size(component->dependencies); i++) {
-        celix_dm_service_dependency_t *dependency = arrayList_get(component->dependencies, i);
-        bool required = false;
-        bool instanceBound = false;
-
-        serviceDependency_isRequired(dependency, &required);
-        serviceDependency_isInstanceBound(dependency, &instanceBound);
-
-        if (required && instanceBound) {
-            bool isAvailable = false;
-            serviceDependency_isAvailable(dependency, &isAvailable);
-            if (!isAvailable) {
-                *available = false;
-                break;
-            }
-        }
-    }
-    pthread_mutex_unlock(&component->mutex);
-
-    return status;
-}
-
-static celix_status_t component_invokeAddRequiredDependencies(celix_dm_component_t *component) {
-    celix_status_t status = CELIX_SUCCESS;
-
-    pthread_mutex_lock(&component->mutex);
-    for (unsigned int i = 0; i < arrayList_size(component->dependencies); i++) {
-        celix_dm_service_dependency_t *dependency = arrayList_get(component->dependencies, i);
-
-        bool required = false;
-        bool instanceBound = false;
-
-        serviceDependency_isRequired(dependency, &required);
-        serviceDependency_isInstanceBound(dependency, &instanceBound);
-
-        if (required && !instanceBound) {
-            array_list_pt events = hashMap_get(component->dependencyEvents, dependency);
-            if (events) {
-				for (unsigned int j = 0; j < arrayList_size(events); j++) {
-					dm_event_pt event = arrayList_get(events, j);
-					serviceDependency_invokeAdd(dependency, event);
-				}
-            }
-        }
-    }
-    pthread_mutex_unlock(&component->mutex);
-
-    return status;
-}
-
-static celix_status_t component_invokeAutoConfigDependencies(celix_dm_component_t *component) {
-    celix_status_t status = CELIX_SUCCESS;
-
-    pthread_mutex_lock(&component->mutex);
-    for (unsigned int i = 0; i < arrayList_size(component->dependencies); i++) {
-        celix_dm_service_dependency_t *dependency = arrayList_get(component->dependencies, i);
-
-        bool autoConfig = false;
-        bool instanceBound = false;
-
-        serviceDependency_isAutoConfig(dependency, &autoConfig);
-        serviceDependency_isInstanceBound(dependency, &instanceBound);
-
-        if (autoConfig && !instanceBound) {
-            component_configureImplementation(component, dependency);
-        }
-    }
-    pthread_mutex_unlock(&component->mutex);
-
-    return status;
-}
-
-static celix_status_t component_invokeAutoConfigInstanceBoundDependencies(celix_dm_component_t *component) {
-    celix_status_t status = CELIX_SUCCESS;
-
-    pthread_mutex_lock(&component->mutex);
-    for (unsigned int i = 0; i < arrayList_size(component->dependencies); i++) {
-        celix_dm_service_dependency_t *dependency = arrayList_get(component->dependencies, i);
-
-        bool autoConfig = false;
-        bool instanceBound = false;
-
-        serviceDependency_isAutoConfig(dependency, &autoConfig);
-        serviceDependency_isInstanceBound(dependency, &instanceBound);
-
-        if (autoConfig && instanceBound) {
-            component_configureImplementation(component, dependency);
-        }
-    }
-    pthread_mutex_unlock(&component->mutex);
-
-    return status;
-}
-
-static celix_status_t component_invokeAddRequiredInstanceBoundDependencies(celix_dm_component_t *component) {
-    celix_status_t status = CELIX_SUCCESS;
-
-    pthread_mutex_lock(&component->mutex);
-    for (unsigned int i = 0; i < arrayList_size(component->dependencies); i++) {
-        celix_dm_service_dependency_t *dependency = arrayList_get(component->dependencies, i);
-
-        bool required = false;
-        bool instanceBound = false;
-
-        serviceDependency_isRequired(dependency, &required);
-        serviceDependency_isInstanceBound(dependency, &instanceBound);
-
-        if (instanceBound && required) {
-            array_list_pt events = hashMap_get(component->dependencyEvents, dependency);
-            if (events) {
-				for (unsigned int j = 0; j < arrayList_size(events); j++) {
-					dm_event_pt event = arrayList_get(events, j);
-					serviceDependency_invokeAdd(dependency, event);
-				}
-            }
-        }
-    }
-    pthread_mutex_unlock(&component->mutex);
-
-    return status;
-}
-
-static celix_status_t component_invokeAddOptionalDependencies(celix_dm_component_t *component) {
-    celix_status_t status = CELIX_SUCCESS;
-
-    pthread_mutex_lock(&component->mutex);
-    for (unsigned int i = 0; i < arrayList_size(component->dependencies); i++) {
-        celix_dm_service_dependency_t *dependency = arrayList_get(component->dependencies, i);
-
-        bool required = false;
-
-        serviceDependency_isRequired(dependency, &required);
-
-        if (!required) {
-            array_list_pt events = hashMap_get(component->dependencyEvents, dependency);
-            if (events) {
-				for (unsigned int j = 0; j < arrayList_size(events); j++) {
-					dm_event_pt event = arrayList_get(events, j);
-					serviceDependency_invokeAdd(dependency, event);
-				}
-            }
-        }
-    }
-    pthread_mutex_unlock(&component->mutex);
-
-    return status;
-}
-
-static celix_status_t component_invokeRemoveOptionalDependencies(celix_dm_component_t *component) {
-    celix_status_t status = CELIX_SUCCESS;
-
-    pthread_mutex_lock(&component->mutex);
-    for (unsigned int i = 0; i < arrayList_size(component->dependencies); i++) {
-        celix_dm_service_dependency_t *dependency = arrayList_get(component->dependencies, i);
-
-        bool required = false;
-
-        serviceDependency_isRequired(dependency, &required);
-
-        if (!required) {
-            array_list_pt events = hashMap_get(component->dependencyEvents, dependency);
-            if (events) {
-				for (unsigned int j = 0; j < arrayList_size(events); j++) {
-					dm_event_pt event = arrayList_get(events, j);
-					serviceDependency_invokeRemove(dependency, event);
-				}
-            }
-        }
-    }
-    pthread_mutex_unlock(&component->mutex);
-
-    return status;
-}
-
-static celix_status_t component_invokeRemoveInstanceBoundDependencies(celix_dm_component_t *component) {
-    celix_status_t status = CELIX_SUCCESS;
-
-    pthread_mutex_lock(&component->mutex);
-    for (unsigned int i = 0; i < arrayList_size(component->dependencies); i++) {
-        celix_dm_service_dependency_t *dependency = arrayList_get(component->dependencies, i);
-
-        bool instanceBound = false;
-
-        serviceDependency_isInstanceBound(dependency, &instanceBound);
-
-        if (instanceBound) {
-            array_list_pt events = hashMap_get(component->dependencyEvents, dependency);
-            if (events) {
-				for (unsigned int j = 0; j < arrayList_size(events); j++) {
-					dm_event_pt event = arrayList_get(events, j);
-					serviceDependency_invokeRemove(dependency, event);
-				}
-            }
-        }
-    }
-    pthread_mutex_unlock(&component->mutex);
-
-    return status;
-}
-
-static celix_status_t component_invokeRemoveRequiredDependencies(celix_dm_component_t *component) {
-    celix_status_t status = CELIX_SUCCESS;
-
-    pthread_mutex_lock(&component->mutex);
-    for (unsigned int i = 0; i < arrayList_size(component->dependencies); i++) {
-        celix_dm_service_dependency_t *dependency = arrayList_get(component->dependencies, i);
-
-        bool required = false;
-        bool instanceBound = false;
-
-        serviceDependency_isRequired(dependency, &required);
-        serviceDependency_isInstanceBound(dependency, &instanceBound);
-
-        if (!instanceBound && required) {
-            array_list_pt events = hashMap_get(component->dependencyEvents, dependency);
-            if (events) {
-				for (unsigned int j = 0; j < arrayList_size(events); j++) {
-					dm_event_pt event = arrayList_get(events, j);
-					serviceDependency_invokeRemove(dependency, event);
-				}
-            }
-        }
-    }
-    pthread_mutex_unlock(&component->mutex);
-
-    return status;
-}
-
-static celix_status_t component_getDependencyEvent(celix_dm_component_t *component, celix_dm_service_dependency_t *dependency, dm_event_pt *event_pptr) {
-    celix_status_t status = CELIX_SUCCESS;
-
-    array_list_pt events = hashMap_get(component->dependencyEvents, dependency);
-    *event_pptr = NULL;
-
-    if (events) {
-        for (unsigned int j = 0; j < arrayList_size(events); j++) {
-            dm_event_pt event_ptr = arrayList_get(events, j);
-            if (*event_pptr != NULL) {
-                int compare = 0;
-                event_compareTo(event_ptr, *event_pptr, &compare);
-                if (compare > 0) {
-                    *event_pptr = event_ptr;
-                }
-            } else {
-                *event_pptr = event_ptr;
-            }
-        }
-    }
-
-    return status;
-}
-
-static celix_status_t component_configureImplementation(celix_dm_component_t *component, celix_dm_service_dependency_t *dependency) {
-    celix_status_t status = CELIX_SUCCESS;
-
-    const void **field = NULL;
-
-    array_list_pt events = hashMap_get(component->dependencyEvents, dependency);
-    if (events) {
-        const void *service = NULL;
-        dm_event_pt event = NULL;
-        component_getDependencyEvent(component, dependency, &event);
-        if (event != NULL) {
-            event_getService(event, &service);
-            serviceDependency_getAutoConfig(dependency, &field);
-            serviceDependency_lock(dependency);
-            *field = service;
-            serviceDependency_unlock(dependency);
+/**
+ * Check if all required dependencies are resolved. This call should be called with the component->mutex locked.
+ */
+static bool component_areAllRequiredServiceDependenciesResolved(celix_dm_component_t *component) {
+    bool allResolved = true;
+    for (int i = 0; i < celix_arrayList_size(component->dependencies); i++) {
+        celix_dm_service_dependency_t *dependency = celix_arrayList_get(component->dependencies, i);
+        bool started = celix_dmServiceDependency_isStarted(dependency);
+        bool required = celix_dmServiceDependency_isRequired(dependency);
+        bool available = celix_serviceDependency_isAvailable(dependency);
+        if (started && required && !available) {
+            allResolved = false;
+            break;
         }
     }
-
-    return status;
+    return allResolved;
 }
 
+/**
+ * Register component services (if not already registered). This call should be called with the component->mutex locked.
+ */
 static celix_status_t component_registerServices(celix_dm_component_t *component) {
-    celix_status_t status = CELIX_SUCCESS;
-
-    if (component->context != NULL) {
-	    unsigned int i;
-        celixThreadMutex_lock(&component->mutex);
-        for (i = 0; i < arrayList_size(component->dm_interfaces); i++) {
-            dm_interface_t *interface = arrayList_get(component->dm_interfaces, i);
-            if (interface->svcId == -1L) {
-                celix_properties_t *regProps = celix_properties_copy(interface->properties);
-                celix_service_registration_options_t opts = CELIX_EMPTY_SERVICE_REGISTRATION_OPTIONS;
-                opts.properties = regProps;
-                opts.svc = (void*)interface->service;
-                opts.serviceName = interface->serviceName;
-                opts.serviceLanguage = celix_properties_get(regProps, CELIX_FRAMEWORK_SERVICE_LANGUAGE, NULL);
-                interface->svcId = celix_bundleContext_registerServiceWithOptions(component->context, &opts);
-            }
+    for (int i = 0; i < celix_arrayList_size(component->providedInterfaces); i++) {
+        dm_interface_t *interface = arrayList_get(component->providedInterfaces, i);
+        if (interface->svcId == -1L) {
+            celix_properties_t *regProps = celix_properties_copy(interface->properties);
+            celix_service_registration_options_t opts = CELIX_EMPTY_SERVICE_REGISTRATION_OPTIONS;
+            opts.properties = regProps;
+            opts.svc = (void*)interface->service;
+            opts.serviceName = interface->serviceName;
+            opts.serviceLanguage = celix_properties_get(regProps, CELIX_FRAMEWORK_SERVICE_LANGUAGE, NULL);
+            celixThreadMutex_unlock(&component->mutex);
+            long svcId = celix_bundleContext_registerServiceWithOptions(component->context, &opts); //TODO fix race condition with async branch -> registerAsync
+            celixThreadMutex_lock(&component->mutex);
+            interface->svcId = svcId;
         }
-        celixThreadMutex_unlock(&component->mutex);
     }
-
-    return status;
+    return CELIX_SUCCESS;
 }
 
+/**
+ * Unregister component services. This call should be called with the component->mutex locked.
+ */
 static celix_status_t component_unregisterServices(celix_dm_component_t *component) {
     celix_status_t status = CELIX_SUCCESS;
 
-    celix_array_list_t *ids = celix_arrayList_create();
-
-    celixThreadMutex_lock(&component->mutex);
-    for (int i = 0; i < celix_arrayList_size(component->dm_interfaces); ++i) {
-	    dm_interface_t *interface = arrayList_get(component->dm_interfaces, i);
-	    celix_arrayList_addLong(ids, interface->svcId);
+    for (int i = 0; i < celix_arrayList_size(component->providedInterfaces); ++i) {
+	    dm_interface_t *interface = arrayList_get(component->providedInterfaces, i);
+	    long svcId = interface->svcId;
 	    interface->svcId = -1L;
-    }
-    celixThreadMutex_unlock(&component->mutex);
-
-    for (int i = 0; i < celix_arrayList_size(ids); ++i) {
-        long svcId = celix_arrayList_getLong(ids, i);
-        celix_bundleContext_unregisterService(component->context, svcId);
+        celixThreadMutex_unlock(&component->mutex);
+        celix_bundleContext_unregisterService(component->context, svcId); //TODO fix race condition with async branch -> unregister async
+        celixThreadMutex_lock(&component->mutex);
     }
 
-    celix_arrayList_destroy(ids);
 
     return status;
 }
@@ -1294,9 +656,6 @@ celix_status_t component_setCallbacks(celix_dm_component_t *component, celix_dm_
 }
 
 celix_status_t celix_dmComponent_setCallbacks(celix_dm_component_t *component, celix_dm_cmp_lifecycle_fpt init, celix_dm_cmp_lifecycle_fpt start, celix_dm_cmp_lifecycle_fpt stop, celix_dm_cmp_lifecycle_fpt deinit) {
-	if (component->active) {
-		return CELIX_ILLEGAL_STATE;
-	}
 	component->callbackInit = init;
 	component->callbackStart = start;
 	component->callbackStop = stop;
@@ -1304,13 +663,6 @@ celix_status_t celix_dmComponent_setCallbacks(celix_dm_component_t *component, c
 	return CELIX_SUCCESS;
 }
 
-
-/*
-celix_status_t component_isAvailable(celix_dm_component_t *component, bool *available) {
-    *available = component->state == DM_CMP_STATE_TRACKING_OPTIONAL;
-    return CELIX_SUCCESS;
-}*/
-
 celix_status_t component_setImplementation(celix_dm_component_t *component, void *implementation) {
     return celix_dmComponent_setImplementation(component, implementation);
 }
@@ -1333,125 +685,6 @@ celix_bundle_context_t* celix_dmComponent_getBundleContext(celix_dm_component_t
     return result;
 }
 
-
-static celix_status_t executor_create(celix_dm_component_t *component __attribute__((unused)), dm_executor_pt *executor) {
-    celix_status_t status = CELIX_SUCCESS;
-
-    *executor = malloc(sizeof(**executor));
-    if (!*executor) {
-        status = CELIX_ENOMEM;
-    } else {
-        (*executor)->workQueue = celix_arrayList_create();
-        pthread_mutex_init(&(*executor)->mutex, NULL);
-        (*executor)->runningThreadSet = false;
-    }
-
-    return status;
-}
-
-static void executor_destroy(dm_executor_pt executor) {
-
-	if (executor) {
-		pthread_mutex_destroy(&executor->mutex);
-		celix_arrayList_destroy(executor->workQueue);
-
-		free(executor);
-	}
-}
-
-static celix_status_t executor_schedule(dm_executor_pt executor, celix_dm_component_t *component, void (*command), void *data) {
-    celix_status_t status = CELIX_SUCCESS;
-
-    dm_executor_task_t *task = NULL;
-    task = malloc(sizeof(*task));
-    if (!task) {
-        status = CELIX_ENOMEM;
-    } else {
-        task->component = component;
-        task->command = command;
-        task->data = data;
-
-        pthread_mutex_lock(&executor->mutex);
-        celix_arrayList_add(executor->workQueue, task);
-        pthread_mutex_unlock(&executor->mutex);
-    }
-
-    return status;
-}
-
-static celix_status_t executor_executeTask(dm_executor_pt executor, celix_dm_component_t *component, void (*command), void *data) {
-    celix_status_t status = CELIX_SUCCESS;
-
-    // Check thread and executor thread, if the same, execute immediately.
-//    bool execute = false;
-//    pthread_mutex_lock(&executor->mutex);
-//    pthread_t currentThread = pthread_self();
-//    if (pthread_equal(executor->runningThread, currentThread)) {
-//        execute = true;
-//    }
-//    pthread_mutex_unlock(&executor->mutex);
-
-    // For now, just schedule.
-    executor_schedule(executor, component, command, data);
-    executor_execute(executor);
-
-    return status;
-}
-
-static celix_status_t executor_execute(dm_executor_pt executor) {
-    celix_status_t status = CELIX_SUCCESS;
-    pthread_t currentThread = pthread_self();
-
-    pthread_mutex_lock(&executor->mutex);
-    bool execute = false;
-    if (!executor->runningThreadSet) {
-        executor->runningThread = currentThread;
-        executor->runningThreadSet = true;
-        execute = true;
-    }
-    pthread_mutex_unlock(&executor->mutex);
-    if (execute) {
-        executor_runTasks(executor, currentThread);
-    }
-
-    return status;
-}
-
-static celix_status_t executor_runTasks(dm_executor_pt executor, pthread_t currentThread __attribute__((unused))) {
-    celix_status_t status = CELIX_SUCCESS;
-//    bool execute = false;
-
-    dm_executor_task_t *entry = NULL;
-
-    pthread_mutex_lock(&executor->mutex);
-    if (celix_arrayList_size(executor->workQueue) > 0) {
-	    entry = celix_arrayList_get(executor->workQueue, 0);
-	    celix_arrayList_removeAt(executor->workQueue, 0);
-    }
-    pthread_mutex_unlock(&executor->mutex);
-
-    while (entry != NULL) {
-	    entry->command(entry->component, entry->data);
-	    free(entry);
-
-	    pthread_mutex_lock(&executor->mutex);
-	    if (celix_arrayList_size(executor->workQueue) > 0) {
-		    entry = celix_arrayList_get(executor->workQueue, 0);
-		    celix_arrayList_removeAt(executor->workQueue, 0);
-	    } else {
-		    entry = NULL;
-	    }
-	    pthread_mutex_unlock(&executor->mutex);
-    }
-
-
-    pthread_mutex_lock(&executor->mutex);
-    executor->runningThreadSet = false;
-    pthread_mutex_unlock(&executor->mutex);
-
-    return status;
-}
-
 celix_status_t component_getComponentInfo(celix_dm_component_t *component, dm_component_info_pt *out) {
     return celix_dmComponent_getComponentInfo(component, out);
 }
@@ -1470,7 +703,7 @@ celix_status_t celix_dmComponent_getComponentInfo(celix_dm_component_t *componen
     arrayList_create(&info->dependency_list);
     component_getInterfaces(component, &info->interfaces);
     info->active = false;
-    memcpy(info->id, component->id, DM_COMPONENT_MAX_ID_LENGTH);
+    memcpy(info->id, component->uuid, DM_COMPONENT_MAX_ID_LENGTH);
     memcpy(info->name, component->name, DM_COMPONENT_MAX_NAME_LENGTH);
 
     switch (component->state) {
@@ -1493,13 +726,13 @@ celix_status_t celix_dmComponent_getComponentInfo(celix_dm_component_t *componen
     }
 
     celixThreadMutex_lock(&component->mutex);
-    size = arrayList_size(component->dependencies);
+    size = celix_arrayList_size(component->dependencies);
     for (i = 0; i < size; i += 1) {
-        celix_dm_service_dependency_t *dep = arrayList_get(component->dependencies, i);
+        celix_dm_service_dependency_t *dep = celix_arrayList_get(component->dependencies, i);
         dm_service_dependency_info_pt depInfo = NULL;
         status = serviceDependency_getServiceDependencyInfo(dep, &depInfo);
         if (status == CELIX_SUCCESS) {
-            arrayList_add(info->dependency_list, depInfo);
+            celix_arrayList_add(info->dependency_list, depInfo);
         } else {
             break;
         }
@@ -1525,30 +758,30 @@ void celix_dmComponent_destroyComponentInfo(dm_component_info_pt info) {
         free(info->state);
 
         if (info->interfaces != NULL) {
-            size = arrayList_size(info->interfaces);
+            size = celix_arrayList_size(info->interfaces);
             for (i = 0; i < size; i += 1) {
-                dm_interface_info_pt intfInfo = arrayList_get(info->interfaces, i);
+                dm_interface_info_pt intfInfo = celix_arrayList_get(info->interfaces, i);
                 free(intfInfo->name);
                 properties_destroy(intfInfo->properties);
                 free(intfInfo);
             }
-            arrayList_destroy(info->interfaces);
+            celix_arrayList_destroy(info->interfaces);
         }
         if (info->dependency_list != NULL) {
-            size = arrayList_size(info->dependency_list);
+            size = celix_arrayList_size(info->dependency_list);
             for (i = 0; i < size; i += 1) {
-                dm_service_dependency_info_pt depInfo = arrayList_get(info->dependency_list, i);
+                dm_service_dependency_info_pt depInfo = celix_arrayList_get(info->dependency_list, i);
                 dependency_destroyDependencyInfo(depInfo);
             }
-            arrayList_destroy(info->dependency_list);
+            celix_arrayList_destroy(info->dependency_list);
         }
     }
     free(info);
 }
 
 bool celix_dmComponent_isActive(celix_dm_component_t *component) {
-    pthread_mutex_lock(&component->mutex);
+    celixThreadMutex_lock(&component->mutex);
     bool active = component->state == DM_CMP_STATE_TRACKING_OPTIONAL;
-    pthread_mutex_unlock(&component->mutex);
+    celixThreadMutex_unlock(&component->mutex);
     return active;
 }
diff --git a/libs/framework/src/dm_component_impl.h b/libs/framework/src/dm_component_impl.h
index db92d2b..897b0bc 100644
--- a/libs/framework/src/dm_component_impl.h
+++ b/libs/framework/src/dm_component_impl.h
@@ -33,13 +33,13 @@ extern "C" {
 
 #include "dm_component.h"
 #include "dm_service_dependency_impl.h"
-#include "dm_event.h"
+#include "celix_dm_event.h"
 
 celix_status_t celix_private_dmComponent_start(celix_dm_component_t *component);
 
 celix_status_t celix_private_dmComponent_stop(celix_dm_component_t *component);
 
-celix_status_t celix_private_dmComponent_handleEvent(celix_dm_component_t *component, celix_dm_service_dependency_t *dependency, dm_event_pt event);
+celix_status_t celix_private_dmComponent_handleEvent(celix_dm_component_t *component, const celix_dm_event_t* event);
 
 #ifdef __cplusplus
 }
diff --git a/libs/framework/src/dm_event.c b/libs/framework/src/dm_event.c
deleted file mode 100644
index de03f50..0000000
--- a/libs/framework/src/dm_event.c
+++ /dev/null
@@ -1,103 +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.
- */
-/**
- * dm_event.c
- *
- *  \date       18 Dec 2014
- *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright  Apache License, Version 2.0
- */
-
-#include <stdlib.h>
-#include "celix_constants.h"
-#include <utils.h>
-
-#include "dm_event.h"
-
-celix_status_t event_create(dm_event_type_e event_type, bundle_pt bundle, bundle_context_pt context, service_reference_pt reference, const void *service, dm_event_pt *event) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	*event = calloc(1, sizeof(**event));
-	if (!*event) {
-		status = CELIX_ENOMEM;
-	}
-
-	const char* serviceIdStr = NULL;
-	serviceReference_getProperty(reference, OSGI_FRAMEWORK_SERVICE_ID, &serviceIdStr);
-	unsigned long servId = strtoul(serviceIdStr,NULL,10);
-
-	const char* rankingStr = NULL;
-	serviceReference_getProperty(reference, OSGI_FRAMEWORK_SERVICE_RANKING, &rankingStr);
-	long ranking = rankingStr == NULL ? 0 : atol(rankingStr);
-
-	if (status == CELIX_SUCCESS) {
-		(*event)->bundle = bundle;
-		(*event)->event_type = event_type;
-		(*event)->context = context;
-		(*event)->reference = reference;
-		(*event)->service = service;
-		(*event)->serviceId = servId;
-		(*event)->ranking = ranking;
-	}
-
-	return status;
-}
-
-celix_status_t event_destroy(dm_event_pt *event) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	if (!*event) {
-		status = CELIX_ILLEGAL_ARGUMENT;
-	}
-
-	if (status == CELIX_SUCCESS) {
-		free(*event);
-		*event = NULL;
-	}
-
-	return status;
-}
-
-celix_status_t event_equals(const void *a, const void *b, bool *equals) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	if (!a || !b) {
-		*equals = false;
-	} else {
-		dm_event_pt a_ptr = (dm_event_pt)a;
-		dm_event_pt b_ptr = (dm_event_pt)b;
-
-		*equals = a_ptr->serviceId == b_ptr->serviceId;
-	}
-
-	return status;
-}
-
-celix_status_t event_compareTo(dm_event_pt event, dm_event_pt compareTo, int *compare) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	*compare = utils_compareServiceIdsAndRanking(event->serviceId, event->ranking, compareTo->serviceId, compareTo->ranking);
-
-	return status;
-}
-
-celix_status_t event_getService(dm_event_pt event, const void **service) {
-	*service = event->service;
-	return CELIX_SUCCESS;
-}
diff --git a/libs/framework/src/dm_event.h b/libs/framework/src/dm_event.h
deleted file mode 100644
index c2acf8d..0000000
--- a/libs/framework/src/dm_event.h
+++ /dev/null
@@ -1,72 +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.
- */
-/**
- * dm_event.h
- *
- *  \date       17 Oct 2014
- *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright  Apache License, Version 2.0
- */
-
-#ifndef DM_EVENT_H_
-#define DM_EVENT_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "service_reference.h"
-#include "bundle_context.h"
-#include "bundle.h"
-
-enum dm_event_type {
-	DM_EVENT_ADDED,
-	DM_EVENT_CHANGED,
-	DM_EVENT_REMOVED,
-	DM_EVENT_SWAPPED,
-};
-
-typedef enum dm_event_type dm_event_type_e;
-
-struct dm_event {
-	const void* service;
-	unsigned long serviceId;
-	long ranking;
-	service_reference_pt reference;
-	bundle_context_pt context;
-	bundle_pt bundle;
-	dm_event_type_e event_type;
-};
-
-typedef struct dm_event *dm_event_pt;
-
-
-celix_status_t event_create(dm_event_type_e event_type, bundle_pt bundle, bundle_context_pt context, service_reference_pt reference, const void* service, dm_event_pt *event);
-celix_status_t event_destroy(dm_event_pt* event);
-
-celix_status_t event_equals(const void* a, const void* b, bool* equals);
-
-celix_status_t event_getService(dm_event_pt event, const void** service);
-celix_status_t event_compareTo(dm_event_pt event, dm_event_pt compareTo, int* compare);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* DM_EVENT_H_ */
diff --git a/libs/framework/src/dm_service_dependency.c b/libs/framework/src/dm_service_dependency.c
index 52118d2..2a242c1 100644
--- a/libs/framework/src/dm_service_dependency.c
+++ b/libs/framework/src/dm_service_dependency.c
@@ -16,31 +16,23 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-/**
- * dm_service_dependency.c
- *
- *  \date       17 Oct 2014
- *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright  Apache License, Version 2.0
- */
 
-#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <limits.h>
-#include <assert.h>
 
 #include "celix_constants.h"
+#include "celix_utils.h"
 
 #include "dm_service_dependency_impl.h"
 #include "dm_component_impl.h"
+#include "bundle_context_private.h"
+#include "framework_private.h"
 
-#define DEFAULT_RANKING     0
 #define DM_SERVICE_DEPENDENCY_DEFAULT_STRATEGY DM_SERVICE_DEPENDENCY_STRATEGY_SUSPEND
 
-static celix_status_t serviceDependency_addedService(void *_ptr, service_reference_pt reference, void *service);
-static celix_status_t serviceDependency_modifiedService(void *_ptr, service_reference_pt reference, void *service);
-static celix_status_t serviceDependency_removedService(void *_ptr, service_reference_pt reference, void *service);
+static void serviceDependency_addServiceTrackerCallback(void *handle, void *svc, const celix_properties_t *props);
+static void serviceDependency_removeServiceTrackerCallback(void *handle, void *svc, const celix_properties_t *props);
+static void serviceDependency_setServiceTrackerCallback(void *handle, void *svc, const celix_properties_t *props);
 static void* serviceDependency_getCallbackHandle(celix_dm_service_dependency_t *dep);
 
 celix_status_t serviceDependency_create(celix_dm_service_dependency_t **dependency_ptr) {
@@ -68,23 +60,13 @@ celix_status_t serviceDependency_destroy(celix_dm_service_dependency_t **depende
 
 void celix_dmServiceDependency_destroy(celix_dm_service_dependency_t *dep) {
 	if (dep != NULL) {
-		free(dep->tracked_service);
-		free(dep->tracked_filter);
-		free(dep->tracked_filter_unmodified);
+        free(dep->serviceName);
+        free(dep->versionRange);
+        free(dep->filter);
 		free(dep);
 	}
 }
 
-celix_status_t serviceDependency_lock(celix_dm_service_dependency_t *dependency) {
-	celixThreadMutex_lock(&dependency->lock);
-	return CELIX_SUCCESS;
-}
-
-celix_status_t serviceDependency_unlock(celix_dm_service_dependency_t *dependency) {
-	celixThreadMutex_unlock(&dependency->lock);
-	return CELIX_SUCCESS;
-}
-
 celix_status_t serviceDependency_setRequired(celix_dm_service_dependency_t *dependency, bool required) {
 	return celix_dmServiceDependency_setRequired(dependency, required);
 }
@@ -117,15 +99,8 @@ celix_status_t serviceDependency_setStrategy(celix_dm_service_dependency_t *depe
 }
 
 celix_status_t celix_dmServiceDependency_setStrategy(celix_dm_service_dependency_t *dependency, dm_service_dependency_strategy_t strategy) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	if (!dependency) {
-		status = CELIX_ILLEGAL_ARGUMENT;
-	} else {
-		dependency->strategy = strategy;
-	}
-
-	return status;
+    dependency->strategy = strategy;
+	return CELIX_SUCCESS;
 }
 
 celix_status_t serviceDependency_getStrategy(celix_dm_service_dependency_t *dependency, dm_service_dependency_strategy_t* strategy) {
@@ -145,131 +120,21 @@ celix_status_t serviceDependency_setService(celix_dm_service_dependency_t *depen
 }
 
 celix_status_t celix_dmServiceDependency_setService(celix_dm_service_dependency_t *dependency, const char* serviceName, const char* serviceVersionRange, const char* filter) {
-	celix_status_t status = CELIX_SUCCESS;
-	if (!dependency || !serviceName) {
-		status = CELIX_ILLEGAL_ARGUMENT;
-	}
-
-	if (status == CELIX_SUCCESS) {
-		array_list_pt filterElements = NULL;
-		arrayList_create(&filterElements);
-
-		free(dependency->tracked_service);
-		dependency->tracked_service = strdup(serviceName);
-
-		if (serviceVersionRange != NULL) {
-			version_range_pt versionRange = NULL;
-
-			if (versionRange_parse(serviceVersionRange, &versionRange) == CELIX_SUCCESS) {
-				version_pt lowVersion = NULL;
-				version_pt highVersion = NULL;
-
-				if ((versionRange_getHighVersion(versionRange, &highVersion) == CELIX_SUCCESS) && (highVersion != NULL)) {
-					bool isHighInclusive;
-					char* highOperator;
-					char* highVersionStr = NULL;
-
-					versionRange_isHighInclusive(versionRange, &isHighInclusive);
-					version_toString(highVersion, &highVersionStr);
-
-					highOperator = isHighInclusive ? "<=" : "<";
-
-					if(highVersionStr != NULL){
-						size_t len = strlen(CELIX_FRAMEWORK_SERVICE_VERSION) + strlen(highVersionStr) + strlen(highOperator) + 3;
-						char serviceVersionFilter[len];
-						snprintf(serviceVersionFilter, len, "(%s%s%s)", CELIX_FRAMEWORK_SERVICE_VERSION, highOperator, highVersionStr);
-						arrayList_add(filterElements, strdup(serviceVersionFilter));
-						free(highVersionStr);
-					}
-				}
-
-				if ((versionRange_getLowVersion(versionRange, &lowVersion) == CELIX_SUCCESS) && (lowVersion != NULL)) {
-					bool isLowInclusive;
-					char* lowOperator;
-					char* lowVersionStr = NULL;
-
-					versionRange_isLowInclusive(versionRange, &isLowInclusive);
-					version_toString(lowVersion, &lowVersionStr);
-
-					lowOperator = isLowInclusive ? ">=" : ">";
-
-					if(lowVersionStr != NULL){
-						size_t len = strlen(CELIX_FRAMEWORK_SERVICE_VERSION) + strlen(lowVersionStr) + strlen(lowOperator) + 3;
-						char serviceVersionFilter[len];
-						snprintf(serviceVersionFilter, len, "(%s%s%s)", CELIX_FRAMEWORK_SERVICE_VERSION, lowOperator, lowVersionStr);
-						arrayList_add(filterElements, strdup(serviceVersionFilter));
-						free(lowVersionStr);
-					}
-				}
-			}
-
-			if(versionRange!=NULL){
-				versionRange_destroy(versionRange);
-			}
-		}
-
-		if (filter != NULL) {
-			free(dependency->tracked_filter_unmodified);
-			dependency->tracked_filter_unmodified = strdup(filter);
-			arrayList_add(filterElements, strdup(filter));
-		}
-
-
-
-        bool needLangFilter = true;
-		if (filter != NULL) {
-            char needle[128];
-            snprintf(needle, sizeof(needle), "(%s=", CELIX_FRAMEWORK_SERVICE_LANGUAGE);
-            if (strstr(filter, needle) != NULL) {
-                needLangFilter = false;
-            }
-        }
-
-        if (needLangFilter && dependency->addCLanguageFilter) {
-			char langFilter[128];
-			snprintf(langFilter, sizeof(langFilter), "(%s=%s)", CELIX_FRAMEWORK_SERVICE_LANGUAGE, CELIX_FRAMEWORK_SERVICE_C_LANGUAGE);
-            arrayList_add(filterElements, strdup(langFilter));
-		}
-
-		if (arrayList_size(filterElements) > 0) {
-			array_list_iterator_pt filterElementsIter = arrayListIterator_create(filterElements);
-
-			size_t len = strlen(serviceName) + strlen(OSGI_FRAMEWORK_OBJECTCLASS) + 4;
-			free(dependency->tracked_filter);
-			dependency->tracked_filter = calloc(len, sizeof(*dependency->tracked_filter));
-			snprintf(dependency->tracked_filter, len, "(%s=%s)", OSGI_FRAMEWORK_OBJECTCLASS, serviceName);
-
-			while (arrayListIterator_hasNext(filterElementsIter) == true) {
-				char* filterElement = (char*) arrayListIterator_next(filterElementsIter);
-				size_t len = strnlen(dependency->tracked_filter, 1024*1024) + strnlen(filterElement, 1024*1024) + 4;
-				char* newFilter = calloc(len, sizeof(*newFilter));
-
-				if (dependency->tracked_filter[0] == '(' && dependency->tracked_filter[1] == '&') {
-					//already have an & (AND) can combine with additional filter -> easier to read
-					size_t orgLen = strnlen(dependency->tracked_filter, 1024*1024);
-					snprintf(newFilter, len, "%.*s%s)", (int)orgLen -1, dependency->tracked_filter, filterElement);
-				} else {
-					snprintf(newFilter, len, "(&%s%s)", dependency->tracked_filter, filterElement);
-				}
-
-				free(dependency->tracked_filter);
-				free(filterElement);
-
-				dependency->tracked_filter = newFilter;
-			}
-
-			arrayListIterator_destroy(filterElementsIter);
-		}
-		else {
-			free(dependency->tracked_filter);
-			dependency->tracked_filter = NULL;
-		}
-
-		arrayList_destroy(filterElements);
-	}
-
-	return status;
+    if (dependency->serviceName != NULL) {
+        free(dependency->serviceName);
+    }
+    if (dependency->versionRange != NULL) {
+        free(dependency->versionRange);
+    }
+    if (dependency->filter != NULL) {
+        free(dependency->filter);
+    }
+    dependency->serviceName = celix_utils_strdup(serviceName);
+    dependency->versionRange = celix_utils_strdup(serviceVersionRange);
+    dependency->filter = celix_utils_strdup(filter);
+    return CELIX_SUCCESS;
 }
+
 celix_status_t serviceDependency_getFilter(celix_dm_service_dependency_t *dependency, const char** filter) {
 	const char *f =  celix_dmServiceDependency_getFilter(dependency);
 	if (filter != NULL) {
@@ -279,46 +144,14 @@ celix_status_t serviceDependency_getFilter(celix_dm_service_dependency_t *depend
 }
 
 const char* celix_dmServiceDependency_getFilter(celix_dm_service_dependency_t *dependency) {
-	return (const char*)dependency->tracked_filter;
+	return (const char*)dependency->filter;
 }
 
-celix_status_t serviceDependency_setCallbacks(celix_dm_service_dependency_t *dependency, service_set_fpt set, service_add_fpt add, service_change_fpt change, service_remove_fpt remove, service_swap_fpt swap) {
-	celix_status_t status = CELIX_SUCCESS;
-
-    //printf("Setting callbacks set %p, add %p, change %p, remove %p and swap %p\n", set, add, change, remove, swap);
-
-	if (!dependency) {
-		status = CELIX_ILLEGAL_ARGUMENT;
-	}
-
-	if (status == CELIX_SUCCESS) {
-		dependency->set = (celix_dm_service_update_fp)set;
-		dependency->add = (celix_dm_service_update_fp)add;
-		dependency->change = (celix_dm_service_update_fp)change;
-		dependency->remove = (celix_dm_service_update_fp)remove;
-		dependency->swap = (celix_dm_service_swap_fp)swap;
-	}
-
-	return status;
-}
-
-celix_status_t serviceDependency_setCallbacksWithServiceReference(celix_dm_service_dependency_t *dependency, service_set_with_ref_fpt set, service_add_with_ref_fpt add, service_change_with_ref_fpt change, service_remove_with_ref_fpt remove,
-		service_swap_with_ref_fpt swap) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	if (!dependency) {
-		status = CELIX_ILLEGAL_ARGUMENT;
-	}
-
-	if (status == CELIX_SUCCESS) {
-		dependency->set_with_ref = set;
-		dependency->add_with_ref = add;
-		dependency->change_with_ref = change;
-		dependency->remove_with_ref = remove;
-		dependency->swap_with_ref = swap;
-	}
-
-	return status;
+celix_status_t serviceDependency_setCallbacks(celix_dm_service_dependency_t *dependency, service_set_fpt set, service_add_fpt add, service_change_fpt change __attribute__((unused)), service_remove_fpt remove, service_swap_fpt swap  __attribute__((unused))) {
+    dependency->set = (celix_dm_service_update_fp)set;
+    dependency->add = (celix_dm_service_update_fp)add;
+    dependency->remove = (celix_dm_service_update_fp)remove;
+    return CELIX_SUCCESS;
 }
 
 celix_status_t celix_dmServiceDependency_setCallback(celix_dm_service_dependency_t *dependency, celix_dm_service_update_fp set) {
@@ -328,7 +161,7 @@ celix_status_t celix_dmServiceDependency_setCallback(celix_dm_service_dependency
 
 
 celix_status_t celix_dmServiceDependency_setCallbackWithProperties(celix_dm_service_dependency_t *dependency, celix_dm_service_update_with_props_fp set) {
-	dependency->set_with_props = set;
+	dependency->setWithProperties = set;
 	return CELIX_SUCCESS;
 }
 
@@ -337,486 +170,176 @@ celix_status_t celix_dmServiceDependency_setCallbacksWithOptions(celix_dm_servic
 	dependency->set = opts->set;
 	dependency->add = opts->add;
 	dependency->remove = opts->remove;
-	dependency->swap = opts->swap;
 
-	dependency->set_with_props = opts->setWithProps;
-	dependency->add_with_props = opts->addWithProps;
-	dependency->rem_with_props = opts->removeWithProps;
-	dependency->swap_with_props = opts->swapWithProps;
+	dependency->setWithProperties = opts->setWithProps;
+	dependency->addWithProperties = opts->addWithProps;
+	dependency->remWithProperties = opts->removeWithProps;
 	return CELIX_SUCCESS;
 }
 
-celix_status_t serviceDependency_setAutoConfigure(celix_dm_service_dependency_t *dependency, celix_thread_mutex_t *service_lock, const void **field) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	celix_thread_mutex_t lock;
-
-	if (!dependency) {
-		status = CELIX_ILLEGAL_ARGUMENT;
-	}
-
-	if (status == CELIX_SUCCESS) {
-		dependency->autoConfigure = field;
-		celixThreadMutex_create(&lock, NULL);
-		*service_lock = lock;
-		dependency->lock = lock;
-	}
-
-	return status;
-}
-
-celix_status_t serviceDependency_setComponent(celix_dm_service_dependency_t *dependency, celix_dm_component_t *component) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	if (!dependency) {
-		status = CELIX_ILLEGAL_ARGUMENT;
-	}
-
-	if (status == CELIX_SUCCESS) {
-		dependency->component = component;
-	}
-
-	return status;
-}
-
-celix_status_t serviceDependency_start(celix_dm_service_dependency_t *dependency) {
-	celix_status_t status = CELIX_SUCCESS;
-	bundle_context_pt context = NULL;
-
-	if (!dependency || !dependency->component || (!dependency->tracked_service && !dependency->tracked_filter)) {
-		status = CELIX_ILLEGAL_ARGUMENT;
-	}
-	if (status == CELIX_SUCCESS) {
-		status = component_getBundleContext(dependency->component, &context);
-		if (!context) {
-			status = CELIX_BUNDLE_EXCEPTION;
-		}
-	}
-	if (status == CELIX_SUCCESS) {
-		dependency->tracker_customizer = NULL;
-		status = serviceTrackerCustomizer_create(dependency, NULL, serviceDependency_addedService, serviceDependency_modifiedService, serviceDependency_removedService, &dependency->tracker_customizer);
-	}
-	if (status == CELIX_SUCCESS) {
-		if (dependency->tracked_filter) {
-			status = serviceTracker_createWithFilter(context, dependency->tracked_filter, dependency->tracker_customizer, &dependency->tracker);
-		} else if (dependency->tracked_service) {
-			status = serviceTracker_create(context, dependency->tracked_service, dependency->tracker_customizer, &dependency->tracker);
-		}
-	}
-
-	if (status == CELIX_SUCCESS) {
-		status = serviceTracker_open(dependency->tracker);
-	}
-
-	if (status == CELIX_SUCCESS) {
-		dependency->isStarted = true;
-	}
-
-	return status;
-}
-
-celix_status_t serviceDependency_stop(celix_dm_service_dependency_t *dependency) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	if (!dependency) {
-		status = CELIX_ILLEGAL_ARGUMENT;
-	}
-
-	if (status == CELIX_SUCCESS) {
-		dependency->isStarted = false;
-	}
-
-	if (status == CELIX_SUCCESS && dependency->tracker) {
-		status = serviceTracker_close(dependency->tracker);
-		if (status == CELIX_SUCCESS) {
-			serviceTracker_destroy(dependency->tracker);
-			dependency->tracker = NULL;
-		}
-	}
-
-	return status;
+celix_status_t celix_serviceDependency_setComponent(celix_dm_service_dependency_t *dependency, celix_dm_component_t *component) {
+    dependency->component = component;
+	return CELIX_SUCCESS;
 }
 
-celix_status_t serviceDependency_setInstanceBound(celix_dm_service_dependency_t *dependency, bool instanceBound) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	if (!dependency) {
-		status = CELIX_ILLEGAL_ARGUMENT;
-	}
-
-	if (status == CELIX_SUCCESS) {
-		dependency->instanceBound = instanceBound;
-	}
-
-	return status;
-}
+celix_status_t celix_serviceDependency_start(celix_dm_service_dependency_t *dependency) {
+    celix_bundle_context_t* ctx = celix_dmComponent_getBundleContext(dependency->component);
 
-celix_status_t serviceDependency_setAvailable(celix_dm_service_dependency_t *dependency, bool available) {
-	celix_status_t status = CELIX_SUCCESS;
+    if (dependency->serviceName == NULL && dependency->filter == NULL) {
+        //TODO improve log (via bundle context?)
+        fw_log(ctx->framework->logger, CELIX_LOG_LEVEL_ERROR,
+               "Cannot start a service dependency without a service name and filter");
+        return CELIX_ILLEGAL_ARGUMENT;
+    }
 
-	if (!dependency) {
-		status = CELIX_ILLEGAL_ARGUMENT;
-	}
+    celixThreadMutex_lock(&dependency->mutex);
+    bool open = dependency->isTrackerOpen;
+    dependency->isTrackerOpen = true;
+    celixThreadMutex_unlock(&dependency->mutex);
+
+    if (!open) {
+        celix_service_tracking_options_t opts = CELIX_EMPTY_SERVICE_TRACKING_OPTIONS;
+        opts.filter.filter = dependency->filter;
+        opts.filter.serviceName = dependency->serviceName;
+        opts.filter.versionRange = dependency->versionRange;
+        opts.callbackHandle = dependency;
+        opts.addWithProperties = serviceDependency_addServiceTrackerCallback;
+        opts.removeWithProperties = serviceDependency_removeServiceTrackerCallback;
+        opts.setWithProperties = serviceDependency_setServiceTrackerCallback;
+        if (dependency->addCLanguageFilter) {
+            opts.filter.ignoreServiceLanguage = false;
+            opts.filter.serviceLanguage = CELIX_FRAMEWORK_SERVICE_C_LANGUAGE;
+        } else {
+            opts.filter.ignoreServiceLanguage = true;
+        }
+        long newTrackerId = celix_bundleContext_trackServicesWithOptions(ctx, &opts);
 
-	if (status == CELIX_SUCCESS) {
-		dependency->available = available;
+        celixThreadMutex_lock(&dependency->mutex);
+        dependency->svcTrackerId = newTrackerId;
+        celixThreadMutex_unlock(&dependency->mutex);
 	}
 
-	return status;
+	return CELIX_SUCCESS;
 }
 
-celix_status_t serviceDependency_invokeSet(celix_dm_service_dependency_t *dependency, dm_event_pt event) {
-	celix_status_t status = CELIX_SUCCESS;
-	assert(dependency->isStarted == true);
-	array_list_pt serviceReferences = NULL;
-	int i;
-	int curRanking = INT_MIN;
-	service_reference_pt curServRef = NULL;
-	void *service = NULL;
-
-	serviceReferences = serviceTracker_getServiceReferences(dependency->tracker);
-
-	/* Find the service with the highest ranking */
-	for (i = 0; i < arrayList_size(serviceReferences); i++) {
-		service_reference_pt serviceReference = arrayList_get(serviceReferences, i);
-		const char* ranking_value;
-		int ranking = 0;
-
-		status = serviceReference_getProperty(serviceReference, ((char *) OSGI_FRAMEWORK_SERVICE_RANKING), &ranking_value);
-
-		if (status == CELIX_SUCCESS) {
-			if (ranking_value == NULL) {
-				ranking = DEFAULT_RANKING;
-			} else {
-				char *end;
-				ranking = strtol(ranking_value, &end, 10);
-				if (end == ranking_value) {
-					ranking = DEFAULT_RANKING;
-				}
-			}
-
-			if (ranking > curRanking) {
-				curRanking = ranking;
-				curServRef = serviceReference;
-			}
-		} else {
-			break;
-		}
-
-	}
+celix_status_t celix_serviceDependency_stop(celix_dm_service_dependency_t *dependency) {
+    celix_bundle_context_t* ctx = celix_dmComponent_getBundleContext(dependency->component);
 
-	arrayList_destroy(serviceReferences);
+    celixThreadMutex_lock(&dependency->mutex);
+    long stopTrackerId = dependency->svcTrackerId;
+    dependency->svcTrackerId = -1l;
+    bool open = dependency->isTrackerOpen;
+    dependency->isTrackerOpen = false;
+    celixThreadMutex_unlock(&dependency->mutex);
 
-	if (status == CELIX_SUCCESS) {
-		if (curServRef) {
-			status = bundleContext_getService(event->context, curServRef, &service);
-		} else {
-			service = NULL;
-		}
-
-		if (dependency->set) {
-			dependency->set(serviceDependency_getCallbackHandle(dependency), service);
-		}
-		if (dependency->set_with_ref) {
-			dependency->set_with_ref(serviceDependency_getCallbackHandle(dependency), curServRef, service);
-		}
-		if (dependency->set_with_props) {
-			service_registration_pt reg = NULL;
-			celix_properties_t *props = NULL;
-			serviceReference_getServiceRegistration(curServRef, &reg);
-			if (reg != NULL) {
-				serviceRegistration_getProperties(reg, &props);
-			}
-			dependency->set_with_props(serviceDependency_getCallbackHandle(dependency), service, props);
-		}
-
-		if (curServRef) {
-			bundleContext_ungetService(event->context, curServRef, NULL);
-		}
-	}
+    //TODO if async branch is available this can be done with the lock using a async stop service tracker call
+    if (open && stopTrackerId >= 0) {
+        celix_bundleContext_stopTracker(ctx, stopTrackerId);
+    }
 
-	return status;
+	return CELIX_SUCCESS;
 }
 
-celix_status_t serviceDependency_invokeAdd(celix_dm_service_dependency_t *dependency, dm_event_pt event) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	if (!dependency) {
-		status = CELIX_ILLEGAL_ARGUMENT;
-	}
-
-	if (status == CELIX_SUCCESS) {
-		if (dependency->add) {
-			dependency->add(serviceDependency_getCallbackHandle(dependency), (void*)event->service);
-		}
-		if (dependency->add_with_ref) {
-			dependency->add_with_ref(serviceDependency_getCallbackHandle(dependency), event->reference, (void*)event->service);
-		}
-		if (dependency->add_with_props) {
-			service_registration_pt reg = NULL;
-			celix_properties_t *props = NULL;
-			serviceReference_getServiceRegistration(event->reference, &reg);
-			if (reg != NULL) {
-				serviceRegistration_getProperties(reg, &props);
-			}
-			dependency->add_with_props(serviceDependency_getCallbackHandle(dependency), (void*)event->service, props);
-		}
-	}
+static void serviceDependency_setServiceTrackerCallback(void *handle, void *svc, const celix_properties_t *props) {
+    celix_dm_service_dependency_t* dependency = handle;
 
-	return status;
+    celix_dm_event_t event;
+    event.dep = dependency;
+    event.eventType = CELIX_DM_EVENT_SVC_SET;
+    event.svc = svc;
+    event.props = props;
+    celix_private_dmComponent_handleEvent(dependency->component, &event);
 }
 
-celix_status_t serviceDependency_invokeChange(celix_dm_service_dependency_t *dependency, dm_event_pt event) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	if (!dependency) {
-		status = CELIX_ILLEGAL_ARGUMENT;
-	}
-
-	if (status == CELIX_SUCCESS) {
-		if (dependency->change) {
-			dependency->change(serviceDependency_getCallbackHandle(dependency), (void*)event->service);
-		}
-		if (dependency->change_with_ref) {
-			dependency->change_with_ref(serviceDependency_getCallbackHandle(dependency), event->reference, event->service);
-		}
-	}
-
-	return status;
+celix_status_t celix_serviceDependency_invokeSet(celix_dm_service_dependency_t *dependency, void* svc, const celix_properties_t* props) {
+    if (dependency->set) {
+        dependency->set(serviceDependency_getCallbackHandle(dependency), svc);
+    }
+    if (dependency->setWithProperties) {
+        dependency->setWithProperties(serviceDependency_getCallbackHandle(dependency), svc, props);
+    }
+    return CELIX_SUCCESS;
 }
 
-celix_status_t serviceDependency_invokeRemove(celix_dm_service_dependency_t *dependency, dm_event_pt event) {
-	celix_status_t status = CELIX_SUCCESS;
+static void serviceDependency_addServiceTrackerCallback(void *handle, void *svc, const celix_properties_t *props) {
+    celix_dm_service_dependency_t* dependency = handle;
 
-	if (!dependency) {
-		status = CELIX_ILLEGAL_ARGUMENT;
-	}
-
-	if (status == CELIX_SUCCESS) {
-		if (dependency->remove) {
-			dependency->remove(serviceDependency_getCallbackHandle(dependency), (void*)event->service);
-		}
-		if (dependency->remove_with_ref) {
-			dependency->remove_with_ref(serviceDependency_getCallbackHandle(dependency), event->reference, event->service);
-		}
-		if (dependency->rem_with_props) {
-			service_registration_pt reg = NULL;
-			celix_properties_t *props = NULL;
-			serviceReference_getServiceRegistration(event->reference, &reg);
-			if (reg != NULL) {
-				serviceRegistration_getProperties(reg, &props);
-			}
-			dependency->rem_with_props(serviceDependency_getCallbackHandle(dependency), (void*)event->service, props);
-		}
-	}
+    celixThreadMutex_lock(&dependency->mutex);
+    dependency->trackedSvcCount += 1;
+    celixThreadMutex_unlock(&dependency->mutex);
 
-	return status;
+    celix_dm_event_t event;
+    event.dep = dependency;
+    event.eventType = CELIX_DM_EVENT_SVC_ADD;
+    event.svc = svc;
+    event.props = props;
+    celix_private_dmComponent_handleEvent(dependency->component, &event);
 }
 
-celix_status_t serviceDependency_invokeSwap(celix_dm_service_dependency_t *dependency, dm_event_pt event, dm_event_pt newEvent) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	if (!dependency) {
-		status = CELIX_ILLEGAL_ARGUMENT;
-	}
-
-	if (status == CELIX_SUCCESS) {
-		if (dependency->swap) {
-			dependency->swap(serviceDependency_getCallbackHandle(dependency), (void*)event->service, (void*)newEvent->service);
-		}
-		if (dependency->swap_with_ref) {
-			dependency->swap_with_ref(serviceDependency_getCallbackHandle(dependency), event->reference, event->service, newEvent->reference, newEvent->service);
-		}
-		if (dependency->swap_with_props) {
-			service_registration_pt reg = NULL;
-			celix_properties_t *props = NULL;
-			serviceReference_getServiceRegistration(newEvent->reference, &reg);
-			if (reg != NULL) {
-				serviceRegistration_getProperties(reg, &props);
-			}
-			dependency->swap_with_props(serviceDependency_getCallbackHandle(dependency),(void*) event->service, (void*)newEvent->service, props);
-		}
-	}
-
-	return status;
+celix_status_t celix_serviceDependency_invokeAdd(celix_dm_service_dependency_t *dependency, void* svc, const celix_properties_t* props) {
+    if (dependency->add) {
+        dependency->add(serviceDependency_getCallbackHandle(dependency), svc);
+    }
+    if (dependency->addWithProperties) {
+        dependency->addWithProperties(serviceDependency_getCallbackHandle(dependency), svc, props);
+    }
+    return CELIX_SUCCESS;
 }
 
-celix_status_t serviceDependency_isAvailable(celix_dm_service_dependency_t *dependency, bool *available) {
-	celix_status_t status = CELIX_SUCCESS;
+static void serviceDependency_removeServiceTrackerCallback(void *handle, void *svc, const celix_properties_t *props) {
+    celix_dm_service_dependency_t* dependency = handle;
 
-	if (!dependency) {
-		status = CELIX_ILLEGAL_ARGUMENT;
-	}
+    celixThreadMutex_lock(&dependency->mutex);
+    dependency->trackedSvcCount -= 1;
+    celixThreadMutex_unlock(&dependency->mutex);
 
-	if (status == CELIX_SUCCESS) {
-		*available = dependency->available;
-	}
-
-	return status;
+    celix_dm_event_t event;
+    event.dep = dependency;
+    event.eventType = CELIX_DM_EVENT_SVC_REM;
+    event.svc = svc;
+    event.props = props;
+    celix_private_dmComponent_handleEvent(dependency->component, &event);
 }
 
-celix_status_t serviceDependency_isRequired(celix_dm_service_dependency_t *dependency, bool *required) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	if (!dependency) {
-		status = CELIX_ILLEGAL_ARGUMENT;
-	}
-
-	if (status == CELIX_SUCCESS) {
-		*required = dependency->required;
-	}
-
-	return status;
+celix_status_t celix_serviceDependency_invokeRemove(celix_dm_service_dependency_t *dependency, void* svc, const celix_properties_t* props) {
+    if (dependency->remove) {
+        dependency->remove(serviceDependency_getCallbackHandle(dependency), svc);
+    }
+    if (dependency->remWithProperties) {
+        dependency->addWithProperties(serviceDependency_getCallbackHandle(dependency), svc, props);
+    }
+    return CELIX_SUCCESS;
 }
 
-celix_status_t serviceDependency_isInstanceBound(celix_dm_service_dependency_t *dependency, bool *instanceBound) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	if (!dependency) {
-		status = CELIX_ILLEGAL_ARGUMENT;
-	}
-
-	if (status == CELIX_SUCCESS) {
-		*instanceBound = dependency->instanceBound;
-	}
-
-	return status;
+bool celix_serviceDependency_hasSetCallback(const celix_dm_service_dependency_t *dependency) {
+    return dependency->set != NULL || dependency->setWithProperties != NULL;
 }
 
-celix_status_t serviceDependency_isAutoConfig(celix_dm_service_dependency_t *dependency, bool *autoConfig) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	if (!dependency) {
-		status = CELIX_ILLEGAL_ARGUMENT;
-	}
-
-	if (status == CELIX_SUCCESS) {
-		*autoConfig = dependency->autoConfigure != NULL;
-	}
-
-	return status;
+bool celix_serviceDependency_hasAddCallback(const celix_dm_service_dependency_t *dependency) {
+    return dependency->add != NULL || dependency->addWithProperties != NULL;
 }
 
-celix_status_t serviceDependency_getAutoConfig(celix_dm_service_dependency_t *dependency, const void*** autoConfigure) {
-	celix_status_t status = CELIX_SUCCESS;
-
-	if (!dependency) {
-		status = CELIX_ILLEGAL_ARGUMENT;
-	}
-
-	if (status == CELIX_SUCCESS) {
-		*autoConfigure = dependency->autoConfigure;
-	}
-
-	return status;
+bool celix_serviceDependency_hasRemoveCallback(const celix_dm_service_dependency_t *dependency) {
+    return dependency->remove != NULL || dependency->remWithProperties != NULL;
 }
 
-static celix_status_t serviceDependency_addedService(void *_ptr, service_reference_pt reference, void *service) {
-	celix_status_t status = CELIX_SUCCESS;
-	bundle_context_pt context = NULL;
-	bundle_pt bundle = NULL;
-	dm_event_pt event = NULL;
-	celix_dm_service_dependency_t *dependency = _ptr;
-
-	if (!dependency || !reference || !service) {
-		status = CELIX_ILLEGAL_ARGUMENT;
-	}
-
-	if (status == CELIX_SUCCESS) {
-		status = component_getBundleContext(dependency->component, &context);
-		if (!context) {
-			status = CELIX_BUNDLE_EXCEPTION;
-		}
-	}
-
-	if (status == CELIX_SUCCESS) {
-		status = bundleContext_getBundle(context, &bundle);
-		if (!bundle) {
-			status = CELIX_BUNDLE_EXCEPTION;
-		}
-	}
-
-	if (status == CELIX_SUCCESS) {
-		status = event_create(DM_EVENT_ADDED, bundle, context, reference, service, &event);
-	}
-
-	if (status == CELIX_SUCCESS) {
-		celix_private_dmComponent_handleEvent(dependency->component, dependency, event);
-	}
-
-	return status;
+bool celix_serviceDependency_isAvailable(celix_dm_service_dependency_t *dependency) {
+    bool avail;
+    celixThreadMutex_lock(&dependency->mutex);
+    avail = dependency->trackedSvcCount > 0;
+    celixThreadMutex_unlock(&dependency->mutex);
+    return avail;
 }
 
-static celix_status_t serviceDependency_modifiedService(void *_ptr, service_reference_pt reference, void *service) {
-	celix_status_t status = CELIX_SUCCESS;
-	bundle_context_pt context = NULL;
-	bundle_pt bundle = NULL;
-	dm_event_pt event = NULL;
-	celix_dm_service_dependency_t *dependency = _ptr;
-
-	if (!dependency || !reference || !service) {
-		status = CELIX_ILLEGAL_ARGUMENT;
-	}
-
-	if (status == CELIX_SUCCESS) {
-		status = component_getBundleContext(dependency->component, &context);
-		if (!context) {
-			status = CELIX_BUNDLE_EXCEPTION;
-		}
-	}
-
-	if (status == CELIX_SUCCESS) {
-		status = bundleContext_getBundle(context, &bundle);
-		if (!bundle) {
-			status = CELIX_BUNDLE_EXCEPTION;
-		}
-	}
-
-	if (status == CELIX_SUCCESS) {
-		status = event_create(DM_EVENT_CHANGED, bundle, context, reference, service, &event);
-	}
-
-	if (status == CELIX_SUCCESS) {
-		celix_private_dmComponent_handleEvent(dependency->component, dependency, event);
-	}
-
-	return status;
+bool celix_dmServiceDependency_isRequired(const celix_dm_service_dependency_t* dep) {
+    return dep->required;
 }
 
-static celix_status_t serviceDependency_removedService(void *_ptr, service_reference_pt reference, void *service) {
-	celix_status_t status = CELIX_SUCCESS;
-	bundle_context_pt context = NULL;
-	bundle_pt bundle = NULL;
-	dm_event_pt event = NULL;
-	celix_dm_service_dependency_t *dependency = _ptr;
-
-	if (!dependency || !reference || !service) {
-		status = CELIX_ILLEGAL_ARGUMENT;
-	}
-
-	if (status == CELIX_SUCCESS) {
-		status = component_getBundleContext(dependency->component, &context);
-		if (!context) {
-			status = CELIX_BUNDLE_EXCEPTION;
-		}
-	}
-
-	if (status == CELIX_SUCCESS) {
-		status = bundleContext_getBundle(context, &bundle);
-		if (!bundle) {
-			status = CELIX_BUNDLE_EXCEPTION;
-		}
-	}
-
-	if (status == CELIX_SUCCESS) {
-		status = event_create(DM_EVENT_REMOVED, bundle, context, reference, service, &event);
-	}
-
-	if (status == CELIX_SUCCESS) {
-		celix_private_dmComponent_handleEvent(dependency->component, dependency, event);
-	}
-
-	return status;
+bool celix_dmServiceDependency_isStarted(celix_dm_service_dependency_t* dependency) {
+    celixThreadMutex_lock(&dependency->mutex);
+    bool started = dependency->isTrackerOpen;
+    celixThreadMutex_unlock(&dependency->mutex);
+    return started;
 }
 
 celix_status_t serviceDependency_getServiceDependencyInfo(celix_dm_service_dependency_t *dep, dm_service_dependency_info_t **out) {
@@ -829,21 +352,14 @@ celix_status_t serviceDependency_getServiceDependencyInfo(celix_dm_service_depen
 dm_service_dependency_info_t* celix_dmServiceDependency_createInfo(celix_dm_service_dependency_t* dep) {
 	celix_dm_service_dependency_info_t *info = calloc(1, sizeof(*info));
 	if (info != NULL) {
-		celixThreadMutex_lock(&dep->lock);
-		info->available = dep->available;
-		info->filter = dep->tracked_filter != NULL ? strdup(dep->tracked_filter) : NULL;
-		if (info->filter == NULL) {
-			info->filter = dep->tracked_service != NULL ? strdup(dep->tracked_service) : NULL;
-		}
+		celixThreadMutex_lock(&dep->mutex);
+		info->available = dep->trackedSvcCount > 0;
+		info->serviceName = celix_utils_strdup(dep->serviceName);
+		info->filter = celix_utils_strdup(dep->filter);
+		info->versionRange = celix_utils_strdup(dep->versionRange);
 		info->required = dep->required;
-
-		array_list_pt refs = serviceTracker_getServiceReferences(dep->tracker);
-		if (refs != NULL) {
-			info->count = arrayList_size(refs);
-		}
-		arrayList_destroy(refs);
-
-		celixThreadMutex_unlock(&dep->lock);
+		info->count = dep->trackedSvcCount;
+		celixThreadMutex_unlock(&dep->mutex);
 	}
 	return info;
 }
@@ -855,7 +371,9 @@ void dependency_destroyDependencyInfo(dm_service_dependency_info_pt info) {
 
 void celix_dmServiceDependency_destroyInfo(celix_dm_service_dependency_t *dep __attribute__((unused)), dm_service_dependency_info_t *info) {
 	if (info != NULL) {
+	    free(info->serviceName);
 		free(info->filter);
+		free(info->versionRange);
 	}
 	free(info);
 }
@@ -869,6 +387,7 @@ celix_status_t celix_dmServiceDependency_setCallbackHandle(celix_dm_service_depe
     return CELIX_SUCCESS;
 }
 
+
 static void* serviceDependency_getCallbackHandle(celix_dm_service_dependency_t *dependency) {
     return dependency->callbackHandle == NULL ? component_getImplementation(dependency->component) : dependency->callbackHandle;
 }
diff --git a/libs/framework/src/dm_service_dependency_impl.h b/libs/framework/src/dm_service_dependency_impl.h
index a3aa6e1..bab5d7c 100644
--- a/libs/framework/src/dm_service_dependency_impl.h
+++ b/libs/framework/src/dm_service_dependency_impl.h
@@ -16,13 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-/**
- * dm_service_dependency_impl.h
- *
- *  \date       16 Oct 2015
- *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright  Apache License, Version 2.0
- */
+
 
 #ifndef DM_SERVICE_DEPENDENCY_IMPL_H_
 #define DM_SERVICE_DEPENDENCY_IMPL_H_
@@ -33,74 +27,59 @@ extern "C" {
 
 #include <stdbool.h>
 
-#include "dm_event.h"
+#include "celix_dm_event.h"
 #include "service_tracker.h"
 #include "service_tracker_customizer.h"
 
 #include "dm_service_dependency.h"
 #include "dm_component.h"
 
+struct celix_dm_service_dependency_svc_entry {
+    void *svc;
+    const celix_properties_t* props;
+};
+
 struct celix_dm_service_dependency {
 	celix_dm_component_t *component;
-	bool available;
-	bool instanceBound;
-	bool required;
-	dm_service_dependency_strategy_t strategy;
 
 	void* callbackHandle; //This handle can be set to be used instead of the component implementation
 	celix_dm_service_update_fp set;
 	celix_dm_service_update_fp add;
-	celix_dm_service_update_fp change;
 	celix_dm_service_update_fp remove;
-	celix_dm_service_swap_fp swap;
-
-	service_set_with_ref_fpt set_with_ref;
-	service_add_with_ref_fpt add_with_ref;
-	service_change_with_ref_fpt change_with_ref;
-	service_remove_with_ref_fpt remove_with_ref;
-	service_swap_with_ref_fpt swap_with_ref;
 
-	celix_dm_service_update_with_props_fp set_with_props;
-	celix_dm_service_update_with_props_fp add_with_props;
-	celix_dm_service_update_with_props_fp rem_with_props;
-	celix_dm_service_swap_with_props_fp swap_with_props;
+	celix_dm_service_update_with_props_fp setWithProperties;
+	celix_dm_service_update_with_props_fp addWithProperties;
+	celix_dm_service_update_with_props_fp remWithProperties;
+
+	char *serviceName;
+    char *filter;
+    char *versionRange;
+    bool required;
+    dm_service_dependency_strategy_t strategy;
+    bool addCLanguageFilter;
+
+    celix_thread_mutex_t mutex; //protects below
+    long svcTrackerId;
+    bool isTrackerOpen;
+    size_t trackedSvcCount;
+};
 
-	const void **autoConfigure;
-	celix_thread_mutex_t lock;
+celix_status_t celix_serviceDependency_start(celix_dm_service_dependency_t *dependency);
+celix_status_t celix_serviceDependency_stop(celix_dm_service_dependency_t *dependency);
 
-	bool isStarted;
+celix_status_t celix_serviceDependency_setComponent(celix_dm_service_dependency_t *dependency, celix_dm_component_t *component);
 
-	bool addCLanguageFilter;
-	char *tracked_service;
-	char *tracked_filter_unmodified;
-	char *tracked_filter;
+celix_status_t celix_serviceDependency_invokeSet(celix_dm_service_dependency_t *dependency, void* svc, const celix_properties_t* props);
+celix_status_t celix_serviceDependency_invokeAdd(celix_dm_service_dependency_t *dependency, void* svc, const celix_properties_t* props);
+celix_status_t celix_serviceDependency_invokeRemove(celix_dm_service_dependency_t *dependency, void* svc, const celix_properties_t* props);
 
-	service_tracker_pt tracker;
-	service_tracker_customizer_pt tracker_customizer;
-};
+bool celix_serviceDependency_hasSetCallback(const celix_dm_service_dependency_t *dependency);
+bool celix_serviceDependency_hasAddCallback(const celix_dm_service_dependency_t *dependency);
+bool celix_serviceDependency_hasRemoveCallback(const celix_dm_service_dependency_t *dependency);
 
-celix_status_t serviceDependency_start(celix_dm_service_dependency_t *dependency);
-celix_status_t serviceDependency_stop(celix_dm_service_dependency_t *dependency);
-celix_status_t serviceDependency_setInstanceBound(celix_dm_service_dependency_t *dependency, bool instanceBound);
-celix_status_t serviceDependency_setAutoConfig(celix_dm_service_dependency_t *dependency, void **autoConfigure);
-celix_status_t serviceDependency_setAvailable(celix_dm_service_dependency_t *dependency, bool available);
-
-celix_status_t serviceDependency_setComponent(celix_dm_service_dependency_t *dependency, celix_dm_component_t *component);
-//celix_status_t serviceDependency_removeComponent(celix_dm_service_dependency_t *dependency, celix_dm_component_t *component);
-
-celix_status_t serviceDependency_invokeSet(celix_dm_service_dependency_t *dependency, dm_event_pt event);
-celix_status_t serviceDependency_invokeAdd(celix_dm_service_dependency_t *dependency, dm_event_pt event);
-celix_status_t serviceDependency_invokeChange(celix_dm_service_dependency_t *dependency, dm_event_pt event);
-celix_status_t serviceDependency_invokeRemove(celix_dm_service_dependency_t *dependency, dm_event_pt event);
-celix_status_t serviceDependency_invokeSwap(celix_dm_service_dependency_t *dependency, dm_event_pt event, dm_event_pt newEvent);
-celix_status_t serviceDependency_isAvailable(celix_dm_service_dependency_t *dependency, bool *available);
-celix_status_t serviceDependency_isRequired(celix_dm_service_dependency_t *dependency, bool *required);
-celix_status_t serviceDependency_isInstanceBound(celix_dm_service_dependency_t *dependency, bool *instanceBound);
-celix_status_t serviceDependency_isAutoConfig(celix_dm_service_dependency_t *dependency, bool *autoConfig);
-
-celix_status_t serviceDependency_getAutoConfig(celix_dm_service_dependency_t *dependency, const void*** autoConfigure);
-celix_status_t serviceDependency_unlock(celix_dm_service_dependency_t *dependency);
-celix_status_t serviceDependency_lock(celix_dm_service_dependency_t *dependency);
+bool celix_serviceDependency_isAvailable(celix_dm_service_dependency_t *dependency);
+bool celix_dmServiceDependency_isRequired(const celix_dm_service_dependency_t* dependency);
+bool celix_dmServiceDependency_isStarted(celix_dm_service_dependency_t* dependency);
 
 #ifdef __cplusplus
 }
diff --git a/libs/framework/src/requirement.c b/libs/framework/src/requirement.c
index fc032ce..84efcaa 100644
--- a/libs/framework/src/requirement.c
+++ b/libs/framework/src/requirement.c
@@ -86,7 +86,7 @@ celix_status_t requirement_destroy(requirement_pt requirement) {
 	return CELIX_SUCCESS;
 }
 
-celix_status_t requirement_getVersionRange(requirement_pt requirement, version_range_pt *range) {
+celix_status_t requirement_getVersionRange(requirement_pt requirement, celix_version_range_t **range) {
 	*range = requirement->versionRange;
 	return CELIX_SUCCESS;
 }
diff --git a/libs/utils/CMakeLists.txt b/libs/utils/CMakeLists.txt
index 02b1e0a..6cc5825 100644
--- a/libs/utils/CMakeLists.txt
+++ b/libs/utils/CMakeLists.txt
@@ -110,9 +110,6 @@ if (ENABLE_TESTING)
     add_executable(filter_test private/test/filter_test.cpp)
     target_link_libraries(filter_test ${CppUTest_LIBRARY}  Celix::utils pthread)
 
-    add_executable(version_range_test private/test/version_range_test.cpp)
-    target_link_libraries(version_range_test ${CppUTest_LIBRARY} ${CppUTest_EXT_LIBRARIES}  Celix::utils pthread)
-
     add_executable(version_test private/test/version_test.cpp)
     target_link_libraries(version_test ${CppUTest_LIBRARY}  Celix::utils pthread)
 
@@ -126,7 +123,6 @@ if (ENABLE_TESTING)
     add_test(NAME run_utils_test COMMAND utils_test)
     add_test(NAME run_ip_utils_test COMMAND ip_utils_test)
     add_test(NAME filter_test COMMAND filter_test)
-    add_test(NAME version_range_test COMMAND version_range_test)
     add_test(NAME version_test COMMAND version_test)
 
     setup_target_for_coverage(array_list_test)
diff --git a/libs/utils/gtest/CMakeLists.txt b/libs/utils/gtest/CMakeLists.txt
index 697a3b0..b791c42 100644
--- a/libs/utils/gtest/CMakeLists.txt
+++ b/libs/utils/gtest/CMakeLists.txt
@@ -18,9 +18,11 @@
 
 add_executable(test_utils
         src/LogUtilsTestSuite.cc
+        src/VersionRangeTestSuite.cc
 )
 
 target_link_libraries(test_utils PRIVATE Celix::utils GTest::gtest GTest::gtest_main)
+target_include_directories(test_utils PRIVATE ../src) #for version_private (needs refactoring of test)
 
 add_test(NAME test_utils COMMAND test_utils)
 setup_target_for_coverage(test_utils SCAN_DIR ..)
diff --git a/libs/utils/gtest/src/VersionRangeTestSuite.cc b/libs/utils/gtest/src/VersionRangeTestSuite.cc
new file mode 100644
index 0000000..3659b39
--- /dev/null
+++ b/libs/utils/gtest/src/VersionRangeTestSuite.cc
@@ -0,0 +1,423 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <gtest/gtest.h>
+
+#include "version.h"
+#include "version_range.h" //NOTE testing celix_version_range through the deprecated version_range api.
+#include "celix_version_range.h"
+#include "version_private.h"
+
+class VersionRangeTestSuite : public ::testing::Test {};
+
+TEST_F(VersionRangeTestSuite, create) {
+    celix_status_t status = CELIX_SUCCESS;
+    version_range_pt range = nullptr;
+    version_pt low = celix_version_createEmptyVersion();
+    version_pt high = celix_version_createEmptyVersion();
+
+    status = versionRange_createVersionRange(low, false, high, true, &range);
+    EXPECT_EQ(CELIX_SUCCESS, status);
+    EXPECT_TRUE((range != nullptr));
+    EXPECT_EQ(true, celix_versionRange_isHighInclusive(range));
+    EXPECT_EQ(false, celix_versionRange_isLowInclusive(range));
+    EXPECT_EQ(low, celix_versionRange_getLowVersion(range));
+    EXPECT_EQ(high, celix_versionRange_getHighVersion(range));
+
+    versionRange_destroy(range);
+}
+
+TEST_F(VersionRangeTestSuite, createInfinite) {
+    celix_status_t status = CELIX_SUCCESS;
+    version_range_pt range = nullptr;
+    version_pt version = celix_version_createVersion(1,2, 3, nullptr);
+
+    status = versionRange_createInfiniteVersionRange(&range);
+    EXPECT_EQ(CELIX_SUCCESS, status);
+    EXPECT_TRUE(range != nullptr);
+    EXPECT_EQ(true, celix_versionRange_isHighInclusive(range));
+    EXPECT_EQ(true, celix_versionRange_isLowInclusive(range));
+    EXPECT_EQ(celix_version_getMajor(celix_versionRange_getLowVersion(range)), 0);
+    EXPECT_EQ(celix_version_getMinor(celix_versionRange_getLowVersion(range)), 0);
+    EXPECT_EQ(celix_version_getMicro(celix_versionRange_getLowVersion(range)), 0);
+    EXPECT_EQ(std::string{celix_version_getQualifier(celix_versionRange_getLowVersion(range))}, std::string{""});
+    EXPECT_EQ(nullptr, celix_versionRange_getHighVersion(range));
+
+    versionRange_destroy(range);
+    celix_version_destroy(version);
+}
+
+TEST_F(VersionRangeTestSuite, isInRange) {
+    bool result;
+    version_pt version = celix_version_createVersion(1, 2, 3, nullptr);
+
+    {
+        version_range_pt range = nullptr;
+
+        version_pt low = (version_pt) calloc(1, sizeof(*low));
+        low->major = 1;
+        low->minor = 2;
+        low->micro = 3;
+        low->qualifier = nullptr;
+
+        version_pt high = (version_pt) calloc(1, sizeof(*high));
+        high->major = 1;
+        high->minor = 2;
+        high->micro = 3;
+        high->qualifier = nullptr;
+
+        EXPECT_EQ(CELIX_SUCCESS, versionRange_createVersionRange(low, true, high, true, &range));
+        EXPECT_EQ(CELIX_SUCCESS, versionRange_isInRange(range, version, &result));
+        EXPECT_EQ(true, result);
+
+        versionRange_destroy(range);
+    }
+
+    {
+        version_range_pt range = nullptr;
+
+        version_pt low = (version_pt) calloc(1, sizeof(*low));
+        low->major = 1;
+        low->minor = 2;
+        low->micro = 3;
+
+        EXPECT_EQ(CELIX_SUCCESS, versionRange_createVersionRange(low, true, nullptr, true, &range));
+        EXPECT_EQ(CELIX_SUCCESS, versionRange_isInRange(range, version, &result));
+        EXPECT_EQ(true, result);
+
+        versionRange_destroy(range);
+    }
+
+    {
+        version_range_pt range = nullptr;
+
+        version_pt low = (version_pt) calloc(1, sizeof(*low));
+        low->major = 1;
+        low->minor = 2;
+        low->micro = 3;
+
+        version_pt high = (version_pt) calloc(1, sizeof(*high));
+        high->major = 1;
+        high->minor = 2;
+        high->micro = 3;
+
+        EXPECT_EQ(CELIX_SUCCESS, versionRange_createVersionRange(low, false, high, true, &range));
+        EXPECT_EQ(CELIX_SUCCESS, versionRange_isInRange(range, version, &result));
+        EXPECT_EQ(false, result);
+
+        versionRange_destroy(range);
+    }
+
+    {
+        version_range_pt range = nullptr;
+
+        version_pt low = (version_pt) calloc(1, sizeof(*low));
+        low->major = 1;
+        low->minor = 2;
+        low->micro = 3;
+
+        version_pt high = (version_pt) calloc(1, sizeof(*high));
+        high->major = 1;
+        high->minor = 2;
+        high->micro = 3;
+
+        EXPECT_EQ(CELIX_SUCCESS, versionRange_createVersionRange(low, true, high, false, &range));
+        EXPECT_EQ(CELIX_SUCCESS, versionRange_isInRange(range, version, &result));
+        EXPECT_EQ(false, result);
+
+        versionRange_destroy(range);
+    }
+
+    {
+        version_range_pt range = nullptr;
+
+        version_pt low = (version_pt) calloc(1, sizeof(*low));
+        low->major = 1;
+        low->minor = 2;
+        low->micro = 3;
+
+        version_pt high = (version_pt) calloc(1, sizeof(*high));
+        high->major = 1;
+        high->minor = 2;
+        high->micro = 3;
+
+        EXPECT_EQ(CELIX_SUCCESS, versionRange_createVersionRange(low, false, high, false, &range));
+        EXPECT_EQ(CELIX_SUCCESS, versionRange_isInRange(range, version, &result));
+        EXPECT_EQ(false, result);
+
+        versionRange_destroy(range);
+    }
+
+    celix_version_destroy(version);
+}
+
+TEST_F(VersionRangeTestSuite, parse) {
+    version_range_pt range = nullptr;
+    version_pt low = (version_pt) calloc(1, sizeof(*low));
+    version_pt high = (version_pt) calloc(1, sizeof(*high));
+    char * version = strdup("[1.2.3,7.8.9]");
+    low->major = 1;
+    low->minor = 2;
+    low->micro = 3;
+
+    high->major = 7;
+    high->minor = 8;
+    high->micro = 9;
+
+    EXPECT_EQ(CELIX_SUCCESS, versionRange_parse(version, &range));
+
+    versionRange_destroy(range);
+    free(version);
+    version = strdup("[1.2.3");
+
+    EXPECT_EQ(CELIX_ILLEGAL_ARGUMENT, versionRange_parse(version, &range));
+
+    free(version);
+
+    free(high);
+    free(low);
+}
+
+TEST_F(VersionRangeTestSuite, createLdapFilterInclusiveBoth) {
+    version_pt low = (version_pt) calloc(1, sizeof(*low));
+    low->major = 1;
+    low->minor = 2;
+    low->micro = 3;
+    low->qualifier = nullptr;
+
+    version_pt high = (version_pt) calloc(1, sizeof(*high));
+    high->major = 1;
+    high->minor = 2;
+    high->micro = 3;
+    high->qualifier = nullptr;
+
+    version_range_pt range = nullptr;
+    EXPECT_EQ(CELIX_SUCCESS, versionRange_createVersionRange(low, true, high, true, &range));
+
+    auto filter = versionRange_createLDAPFilter(range, "service.version");
+    EXPECT_EQ(std::string{filter}, std::string{"(&(service.version>=1.2.3)(service.version<=1.2.3))"});
+
+    versionRange_destroy(range);
+    free(filter);
+}
+
+TEST_F(VersionRangeTestSuite, createLdapFilterInclusiveLow) {
+    version_pt low = (version_pt) calloc(1, sizeof(*low));
+    low->major = 1;
+    low->minor = 2;
+    low->micro = 3;
+    low->qualifier = nullptr;
+
+    version_pt high = (version_pt) calloc(1, sizeof(*high));
+    high->major = 1;
+    high->minor = 2;
+    high->micro = 3;
+    high->qualifier = nullptr;
+
+    version_range_pt range = nullptr;
+    EXPECT_EQ(CELIX_SUCCESS, versionRange_createVersionRange(low, false, high, true, &range));
+
+    auto filter = versionRange_createLDAPFilter(range, "service.version");
+    EXPECT_STREQ(filter, "(&(service.version>1.2.3)(service.version<=1.2.3))");
+
+    versionRange_destroy(range);
+    free(filter);
+}
+
+TEST_F(VersionRangeTestSuite, createLdapFilterInclusiveHigh) {
+    version_pt low = (version_pt) calloc(1, sizeof(*low));
+    low->major = 1;
+    low->minor = 2;
+    low->micro = 3;
+    low->qualifier = nullptr;
+
+    version_pt high = (version_pt) calloc(1, sizeof(*high));
+    high->major = 1;
+    high->minor = 2;
+    high->micro = 3;
+    high->qualifier = nullptr;
+
+    version_range_pt range = nullptr;
+    EXPECT_EQ(CELIX_SUCCESS, versionRange_createVersionRange(low, true, high, false, &range));
+
+    auto filter = versionRange_createLDAPFilter(range, "service.version");
+    EXPECT_STREQ(filter, "(&(service.version>=1.2.3)(service.version<1.2.3))");
+
+    versionRange_destroy(range);
+    free(filter);
+}
+
+TEST_F(VersionRangeTestSuite, createLdapFilterExclusiveBoth) {
+    version_pt low = (version_pt) calloc(1, sizeof(*low));
+    low->major = 1;
+    low->minor = 2;
+    low->micro = 3;
+    low->qualifier = nullptr;
+
+    version_pt high = (version_pt) calloc(1, sizeof(*high));
+    high->major = 1;
+    high->minor = 2;
+    high->micro = 3;
+    high->qualifier = nullptr;
+
+    version_range_pt range = nullptr;
+    EXPECT_EQ(CELIX_SUCCESS, versionRange_createVersionRange(low, false, high, false, &range));
+
+    auto filter = versionRange_createLDAPFilter(range, "service.version");
+    EXPECT_STREQ(filter, "(&(service.version>1.2.3)(service.version<1.2.3))");
+
+    versionRange_destroy(range);
+    free(filter);
+}
+
+TEST_F(VersionRangeTestSuite, createLdapFilterInfinite) {
+    version_pt low = (version_pt) calloc(1, sizeof(*low));
+    low->major = 1;
+    low->minor = 2;
+    low->micro = 3;
+    low->qualifier = nullptr;
+
+    version_range_pt range = nullptr;
+    EXPECT_EQ(CELIX_SUCCESS, versionRange_createVersionRange(low, true, nullptr, true, &range));
+
+    auto filter = versionRange_createLDAPFilter(range, "service.version");
+    EXPECT_STREQ(filter, "(&(service.version>=1.2.3))");
+
+    versionRange_destroy(range);
+    free(filter);
+}
+
+TEST_F(VersionRangeTestSuite, createLdapFilterInPlaceInclusiveBoth) {
+    version_pt low = (version_pt) calloc(1, sizeof(*low));
+    low->major = 1;
+    low->minor = 2;
+    low->micro = 3;
+    low->qualifier = nullptr;
+
+    version_pt high = (version_pt) calloc(1, sizeof(*high));
+    high->major = 1;
+    high->minor = 2;
+    high->micro = 3;
+    high->qualifier = nullptr;
+
+    version_range_pt range = nullptr;
+    EXPECT_EQ(CELIX_SUCCESS, versionRange_createVersionRange(low, true, high, true, &range));
+    char buffer[100];
+    int bufferLen = sizeof(buffer) / sizeof(buffer[0]);
+
+    EXPECT_EQ(1, versionRange_createLDAPFilterInPlace(range, "service.version", buffer, bufferLen));
+
+    EXPECT_STREQ(buffer, "(&(service.version>=1.2.3)(service.version<=1.2.3))");
+
+    versionRange_destroy(range);
+}
+
+TEST_F(VersionRangeTestSuite, createLdapFilterInPlaceInclusiveLow) {
+    version_pt low = (version_pt) calloc(1, sizeof(*low));
+    low->major = 1;
+    low->minor = 2;
+    low->micro = 3;
+    low->qualifier = nullptr;
+
+    version_pt high = (version_pt) calloc(1, sizeof(*high));
+    high->major = 1;
+    high->minor = 2;
+    high->micro = 3;
+    high->qualifier = nullptr;
+
+    version_range_pt range = nullptr;
+    EXPECT_EQ(CELIX_SUCCESS, versionRange_createVersionRange(low, true, high, false, &range));
+    char buffer[100];
+    int bufferLen = sizeof(buffer) / sizeof(buffer[0]);
+
+    EXPECT_EQ(1, versionRange_createLDAPFilterInPlace(range, "service.version", buffer, bufferLen));
+
+    EXPECT_STREQ(buffer, "(&(service.version>=1.2.3)(service.version<1.2.3))");
+
+    versionRange_destroy(range);
+}
+
+TEST_F(VersionRangeTestSuite, createLdapFilterInPlaceInclusiveHigh) {
+    version_pt low = (version_pt) calloc(1, sizeof(*low));
+    low->major = 1;
+    low->minor = 2;
+    low->micro = 3;
+    low->qualifier = nullptr;
+
+    version_pt high = (version_pt) calloc(1, sizeof(*high));
+    high->major = 1;
+    high->minor = 2;
+    high->micro = 3;
+    high->qualifier = nullptr;
+
+    version_range_pt range = nullptr;
+    EXPECT_EQ(CELIX_SUCCESS, versionRange_createVersionRange(low, false, high, true, &range));
+    char buffer[100];
+    int bufferLen = sizeof(buffer) / sizeof(buffer[0]);
+
+    EXPECT_EQ(1, versionRange_createLDAPFilterInPlace(range, "service.version", buffer, bufferLen));
+
+    EXPECT_STREQ(buffer, "(&(service.version>1.2.3)(service.version<=1.2.3))");
+
+    versionRange_destroy(range);
+}
+
+TEST_F(VersionRangeTestSuite, createLdapFilterInPlaceExclusiveBoth) {
+    version_pt low = (version_pt) calloc(1, sizeof(*low));
+    low->major = 1;
+    low->minor = 2;
+    low->micro = 3;
+    low->qualifier = nullptr;
+
+    version_pt high = (version_pt) calloc(1, sizeof(*high));
+    high->major = 1;
+    high->minor = 2;
+    high->micro = 3;
+    high->qualifier = nullptr;
+
+    version_range_pt range = nullptr;
+    EXPECT_EQ(CELIX_SUCCESS, versionRange_createVersionRange(low, false, high, false, &range));
+    char buffer[100];
+    int bufferLen = sizeof(buffer) / sizeof(buffer[0]);
+
+    EXPECT_EQ(1, versionRange_createLDAPFilterInPlace(range, "service.version", buffer, bufferLen));
+
+    EXPECT_STREQ(buffer, "(&(service.version>1.2.3)(service.version<1.2.3))");
+
+    versionRange_destroy(range);
+}
+
+TEST_F(VersionRangeTestSuite, createLdapFilterInPlaceInfiniteHigh) {
+    version_pt low = (version_pt) calloc(1, sizeof(*low));
+    low->major = 1;
+    low->minor = 2;
+    low->micro = 3;
+    low->qualifier = nullptr;
+
+    version_range_pt range = nullptr;
+    EXPECT_EQ(CELIX_SUCCESS, versionRange_createVersionRange(low, false, nullptr, false, &range));
+    char buffer[100];
+    int bufferLen = sizeof(buffer) / sizeof(buffer[0]);
+
+    EXPECT_EQ(1, versionRange_createLDAPFilterInPlace(range, "service.version", buffer, bufferLen));
+
+    EXPECT_STREQ(buffer, "(&(service.version>1.2.3))");
+
+    versionRange_destroy(range);
+}
diff --git a/libs/utils/include/array_list.h b/libs/utils/include/array_list.h
index e862a8c..d74237b 100644
--- a/libs/utils/include/array_list.h
+++ b/libs/utils/include/array_list.h
@@ -16,13 +16,6 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-/**
- * array_list.h
- *
- *  \date       Aug 4, 2010
- *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright  Apache License, Version 2.0
- */
 
 #ifndef ARRAY_LIST_H_
 #define ARRAY_LIST_H_
diff --git a/libs/utils/include/celix_utils.h b/libs/utils/include/celix_utils.h
index 2a7ba35..b62395c 100644
--- a/libs/utils/include/celix_utils.h
+++ b/libs/utils/include/celix_utils.h
@@ -48,6 +48,11 @@ unsigned int celix_utils_stringHash(const char* string);
  */
 bool celix_utils_stringEquals(const char* a, const char* b);
 
+/**
+ * Check if a string is NULL or empty "".
+ */
+bool celix_utils_isStringNullOrEmpty(const char* s);
+
 
 
 /**
diff --git a/libs/utils/include/celix_version_range.h b/libs/utils/include/celix_version_range.h
new file mode 100644
index 0000000..b8ed66a
--- /dev/null
+++ b/libs/utils/include/celix_version_range.h
@@ -0,0 +1,144 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+#ifndef CELIX_VERSION_RANGE_H_
+#define CELIX_VERSION_RANGE_H_
+
+#include "celixbool.h"
+#include "celix_errno.h"
+#include "celix_version.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Type definition for the celix_version_range_t abstract data type.
+ */
+typedef struct celix_version_range celix_version_range_t;
+
+/**
+ * Creates a new <code>celix_version_range_t*</code>.
+ *
+ * @param low Lower bound version
+ * @param isLowInclusive True if lower bound should be included in the range
+ * @param high Upper bound version
+ * @param isHighInclusive True if upper bound should be included in the range
+ * @param versionRange The created range
+ * @return The service range or NULL if the service range could not be created
+ */
+celix_version_range_t*
+celix_versionRange_createVersionRange(celix_version_t* low, bool isLowInclusive, celix_version_t* high, bool isHighInclusive);
+
+/**
+ * Creates an infinite version range using ::version_createEmptyVersion for the low version,
+ *     NULL for the high version and high and low inclusive set to true.
+ *
+ * @return The created range
+ */
+celix_version_range_t* celix_versionRange_createInfiniteVersionRange();
+
+void celix_versionRange_destroy(celix_version_range_t* range);
+
+/**
+ * Determine if the specified version is part of the version range or not.
+ *
+ * @param versionRange The range to check <code>version</code> against.
+ * @param version The version to check.
+ * @return  True if the specified version is included in this version range, false otherwise.
+ */
+bool celix_versionRange_isInRange(const celix_version_range_t* versionRange, const celix_version_t* version);
+
+/**
+ * Determines whether the lower bound is included in the given range
+ *
+ * @param versionRange The range to check
+ * @return true in case, the lower bound the lower bound is included, otherwise false.
+ */
+bool celix_versionRange_isLowInclusive(const celix_version_range_t* versionRange);
+
+/**
+ * Determines whether the higher bound is included in the given range
+ *
+ * @param versionRange The range to check.
+ * @return true in case, the lower bound the higher bound is included, otherwise false.
+ */
+bool celix_versionRange_isHighInclusive(const celix_version_range_t* versionRange);
+
+/**
+ * Retrieves whether the lower bound version from the given range
+ *
+ * @param versionRange The range
+ * @param The lower bound version.
+ */
+celix_version_t* celix_versionRange_getLowVersion(const celix_version_range_t* versionRange);
+
+/**
+ * Retrieves whether the upper bound version from the given range
+ *
+ * @param versionRange The range
+ * @return The upper bound version.
+ */
+celix_version_t* celix_versionRange_getHighVersion(const celix_version_range_t* versionRange);
+
+/**
+ * Parses a version range from the specified string.
+ *
+ * <p>
+ * Here is the grammar for version range strings.
+ *
+ * <pre>
+ * version-range ::= interval | atleast
+ * interval ::= ( '[' | '(' ) floor ',' ceiling ( ']' | ')' )
+ * atleast ::= version
+ * floor ::= version
+ * ceiling ::= version
+ * </pre>
+ *
+ * Examples: "[1,2)", "[1.1,1.2)"
+ *
+ * @param rangeString String representation of the version range.
+ * @return The created celix_version_range_t or NULL if the range string was invalid.
+ */
+celix_version_range_t* celix_versionRange_parse(const char *rangeString);
+
+/**
+ * Returns the LDAP filter for a version range. Caller is owner of the returned string.
+ *
+ * @param range                         The version range used as input for the LDAP filer
+ * @param serviceVersionPropertyName    The service version name to be used in the filter (i.e. service.version)
+ * @return LDAP filter string if valid, NULL otherwise
+ */
+char* celix_versionRange_createLDAPFilter(const celix_version_range_t* range, const char *serviceVersionAttributeName);
+
+/**
+ * construct a LDAP filter for the provided version range.
+ * The string will be created in the provided buffer, if the buffer is big enough.
+ *
+ * @return True if parse successful, False otherwise.
+ */
+bool celix_versionRange_createLDAPFilterInPlace(const celix_version_range_t* range, const char *serviceVersionAttributeName, char* buffer, size_t bufferLength);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* CELIX_VERSION_RANGE_H_ */
diff --git a/libs/utils/include/version_range.h b/libs/utils/include/version_range.h
index c549699..8372d4e 100644
--- a/libs/utils/include/version_range.h
+++ b/libs/utils/include/version_range.h
@@ -34,10 +34,11 @@
 #ifdef __cplusplus
 extern "C" {
 #endif
+    
 /**
  * Type definition for the version_range_pt abstract data type.
  */
-typedef struct versionRange *version_range_pt;
+typedef struct celix_version_range *version_range_pt;
 
 /**
  * Creates a new <code>version_range_pt</code>.
@@ -53,7 +54,7 @@ typedef struct versionRange *version_range_pt;
  */
 celix_status_t
 versionRange_createVersionRange(version_pt low, bool isLowInclusive, version_pt high, bool isHighInclusive,
-                                version_range_pt *versionRange);
+                                version_range_pt *versionRange) ;
 
 /**
  * Creates an infinite version range using ::version_createEmptyVersion for the low version,
@@ -64,9 +65,9 @@ versionRange_createVersionRange(version_pt low, bool isLowInclusive, version_pt
  *         - CELIX_SUCCESS when no errors are encountered.
  *         - CELIX_ENOMEM If allocating memory for <code>range</code> failed.
  */
-celix_status_t versionRange_createInfiniteVersionRange(version_range_pt *range);
+celix_status_t versionRange_createInfiniteVersionRange(version_range_pt *range) ;
 
-celix_status_t versionRange_destroy(version_range_pt range);
+celix_status_t versionRange_destroy(version_range_pt range) ;
 
 /**
  * Determine if the specified version is part of the version range or not.
@@ -77,7 +78,7 @@ celix_status_t versionRange_destroy(version_range_pt range);
  * @return Status code indication failure or success:
  *         - CELIX_SUCCESS when no errors are encountered.
  */
-celix_status_t versionRange_isInRange(version_range_pt versionRange, version_pt version, bool *inRange);
+celix_status_t versionRange_isInRange(version_range_pt versionRange, version_pt version, bool *inRange) ;
 
 /**
  * Determines whether the lower bound is included in the given range
@@ -88,7 +89,7 @@ celix_status_t versionRange_isInRange(version_range_pt versionRange, version_pt
  *      - CELIX_SUCCESS when no errors are encountered.
  *      - CELIX_ILLEGAL_ARGUMENT in case the versionRange is NULL
  */
-celix_status_t versionRange_isLowInclusive(version_range_pt versionRange, bool *isLowInclusive);
+celix_status_t versionRange_isLowInclusive(version_range_pt versionRange, bool *isLowInclusive) ;
 
 /**
  * Determines whether the higher bound is included in the given range
@@ -99,7 +100,7 @@ celix_status_t versionRange_isLowInclusive(version_range_pt versionRange, bool *
  *      - CELIX_SUCCESS when no errors are encountered.
  *      - CELIX_ILLEGAL_ARGUMENT in case the versionRange is NULL
  */
-celix_status_t versionRange_isHighInclusive(version_range_pt versionRange, bool *isHighInclusive);
+celix_status_t versionRange_isHighInclusive(version_range_pt versionRange, bool *isHighInclusive) ;
 
 /**
  * Retrieves whether the lower bound version from the given range
@@ -110,7 +111,7 @@ celix_status_t versionRange_isHighInclusive(version_range_pt versionRange, bool
  *      - CELIX_SUCCESS when no errors are encountered.
  *      - CELIX_ILLEGAL_ARGUMENT in case the versionRange is NULL
  */
-celix_status_t versionRange_getLowVersion(version_range_pt versionRange, version_pt *lowVersion);
+celix_status_t versionRange_getLowVersion(version_range_pt versionRange, version_pt *lowVersion) ;
 
 /**
  * Retrieves whether the upper bound version from the given range
@@ -121,7 +122,7 @@ celix_status_t versionRange_getLowVersion(version_range_pt versionRange, version
  *      - CELIX_SUCCESS when no errors are encountered.
  *      - CELIX_ILLEGAL_ARGUMENT in case the versionRange is NULL
  */
-celix_status_t versionRange_getHighVersion(version_range_pt versionRange, version_pt *highVersion);
+celix_status_t versionRange_getHighVersion(version_range_pt versionRange, version_pt *highVersion) ;
 
 /**
  * Parses a version range from the specified string.
@@ -145,7 +146,7 @@ celix_status_t versionRange_getHighVersion(version_range_pt versionRange, versio
  *         - CELIX_ILLEGAL_ARGUMENT If the numerical components are negative,
  *               the qualifier string is invalid or <code>versionStr</code> is impropertly formatted.
  */
-celix_status_t versionRange_parse(const char *rangeStr, version_range_pt *range);
+celix_status_t versionRange_parse(const char *rangeStr, version_range_pt *range) ;
 
 /**
  * Returns the LDAP filter for a version range. Caller is owner of the returned string.
@@ -154,7 +155,7 @@ celix_status_t versionRange_parse(const char *rangeStr, version_range_pt *range)
  * @param serviceVersionPropertyName    The service version name to be used in the filter (i.e. service.version)
  * @return LDAP filter string if valid, NULL otherwise
  */
-char* versionRange_createLDAPFilter(version_range_pt range, const char *serviceVersionAttributeName);
+char* versionRange_createLDAPFilter(version_range_pt range, const char *serviceVersionAttributeName) ;
 
 /**
  * construct a LDAP filter for the provided version range.
@@ -162,7 +163,7 @@ char* versionRange_createLDAPFilter(version_range_pt range, const char *serviceV
  *
  * @return True if parse successful, False otherwise.
  */
-bool versionRange_createLDAPFilterInPlace(version_range_pt range, const char *serviceVersionAttributeName, char* buffer, size_t bufferLength);
+bool versionRange_createLDAPFilterInPlace(version_range_pt range, const char *serviceVersionAttributeName, char* buffer, size_t bufferLength) ;
 
 
 #ifdef __cplusplus
diff --git a/libs/utils/private/test/utils_test.cpp b/libs/utils/private/test/utils_test.cpp
index dfd9066..405bb06 100644
--- a/libs/utils/private/test/utils_test.cpp
+++ b/libs/utils/private/test/utils_test.cpp
@@ -362,3 +362,14 @@ TEST(utils, extractLocalNameAndNamespaceTest) {
     free(name);
     free(ns);
 }
+
+TEST(utils, isStringNullOrEmpty) {
+    bool empty = celix_utils_isStringNullOrEmpty(nullptr);
+    CHECK_TRUE(empty);
+    empty = celix_utils_isStringNullOrEmpty("");
+    CHECK_TRUE(empty);
+    empty = celix_utils_isStringNullOrEmpty(" ");
+    CHECK_FALSE(empty);
+    empty = celix_utils_isStringNullOrEmpty("foo");
+    CHECK_FALSE(empty);
+}
\ No newline at end of file
diff --git a/libs/utils/private/test/version_range_test.cpp b/libs/utils/private/test/version_range_test.cpp
deleted file mode 100644
index 796d916..0000000
--- a/libs/utils/private/test/version_range_test.cpp
+++ /dev/null
@@ -1,475 +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.
- */
-/**
- * version_range_test.cpp
- *
- *  \date       Dec 18, 2012
- *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright  Apache License, Version 2.0
- */
-
-#include "CppUTest/TestHarness.h"
-#include "CppUTest/TestHarness_c.h"
-#include "CppUTest/CommandLineTestRunner.h"
-#include "string.h"
-
-extern "C"
-{
-#include "version_range_private.h"
-#include "version_private.h"
-}
-
-int main(int argc, char** argv) {
-    MemoryLeakWarningPlugin::turnOffNewDeleteOverloads();
-    return RUN_ALL_TESTS(argc, argv);
-}
-
-static char* my_strdup(const char* s) {
-    if (s == NULL) {
-        return NULL;
-    }
-
-    size_t len = strlen(s);
-
-    char *d = (char*) calloc(len + 1, sizeof(char));
-
-    if (d == NULL) {
-        return NULL;
-    }
-
-    strncpy(d, s, len);
-    return d;
-}
-
-//----------------------TESTGROUP DEFINES----------------------
-
-TEST_GROUP(version_range) {
-
-    void setup(void) {
-    }
-
-    void teardown() {
-    }
-};
-
-TEST(version_range, create) {
-    celix_status_t status = CELIX_SUCCESS;
-    version_range_pt range = NULL;
-    version_pt low = (version_pt) calloc(1, sizeof(*low));
-    version_pt high = (version_pt) calloc(1, sizeof(*high));
-
-    status = versionRange_createVersionRange(low, false, high, true, &range);
-    LONGS_EQUAL(CELIX_SUCCESS, status);
-    CHECK_C((range != NULL));
-    LONGS_EQUAL(true, range->isHighInclusive);
-    LONGS_EQUAL(false, range->isLowInclusive);
-    POINTERS_EQUAL(low, range->low);
-    POINTERS_EQUAL(high, range->high);
-
-    versionRange_destroy(range);
-}
-
-TEST(version_range, createInfinite) {
-    celix_status_t status = CELIX_SUCCESS;
-    version_range_pt range = NULL;
-    version_pt version = (version_pt) calloc(1, sizeof(*version));
-    version->major = 1;
-    version->minor = 2;
-    version->micro = 3;
-
-    status = versionRange_createInfiniteVersionRange(&range);
-    LONGS_EQUAL(CELIX_SUCCESS, status);
-    CHECK_C(range != NULL);
-    LONGS_EQUAL(true, range->isHighInclusive);
-    LONGS_EQUAL(true, range->isLowInclusive);
-    LONGS_EQUAL(range->low->major, 0);
-    LONGS_EQUAL(range->low->minor, 0);
-    LONGS_EQUAL(range->low->micro, 0);
-    STRCMP_EQUAL(range->low->qualifier, "");
-    POINTERS_EQUAL(NULL, range->high);
-
-    versionRange_destroy(range);
-    free(version);
-}
-
-TEST(version_range, isInRange) {
-    bool result;
-    version_pt version = (version_pt) calloc(1, sizeof(*version));
-    version->major = 1;
-    version->minor = 2;
-    version->micro = 3;
-
-    {
-        version_range_pt range = NULL;
-
-        version_pt low = (version_pt) calloc(1, sizeof(*low));
-        low->major = 1;
-        low->minor = 2;
-        low->micro = 3;
-        low->qualifier = NULL;
-
-        version_pt high = (version_pt) calloc(1, sizeof(*high));
-        high->major = 1;
-        high->minor = 2;
-        high->micro = 3;
-        high->qualifier = NULL;
-
-        LONGS_EQUAL(CELIX_SUCCESS, versionRange_createVersionRange(low, true, high, true, &range));
-        LONGS_EQUAL(CELIX_SUCCESS, versionRange_isInRange(range, version, &result));
-        LONGS_EQUAL(true, result);
-
-        versionRange_destroy(range);
-    }
-
-    {
-        version_range_pt range = NULL;
-
-        version_pt low = (version_pt) calloc(1, sizeof(*low));
-        low->major = 1;
-        low->minor = 2;
-        low->micro = 3;
-
-        LONGS_EQUAL(CELIX_SUCCESS, versionRange_createVersionRange(low, true, NULL, true, &range));
-        LONGS_EQUAL(CELIX_SUCCESS, versionRange_isInRange(range, version, &result));
-        LONGS_EQUAL(true, result);
-
-        versionRange_destroy(range);
-    }
-
-    {
-        version_range_pt range = NULL;
-
-        version_pt low = (version_pt) calloc(1, sizeof(*low));
-        low->major = 1;
-        low->minor = 2;
-        low->micro = 3;
-
-        version_pt high = (version_pt) calloc(1, sizeof(*high));
-        high->major = 1;
-        high->minor = 2;
-        high->micro = 3;
-
-        LONGS_EQUAL(CELIX_SUCCESS, versionRange_createVersionRange(low, false, high, true, &range));
-        LONGS_EQUAL(CELIX_SUCCESS, versionRange_isInRange(range, version, &result));
-        LONGS_EQUAL(false, result);
-
-        versionRange_destroy(range);
-    }
-
-    {
-        version_range_pt range = NULL;
-
-        version_pt low = (version_pt) calloc(1, sizeof(*low));
-        low->major = 1;
-        low->minor = 2;
-        low->micro = 3;
-
-        version_pt high = (version_pt) calloc(1, sizeof(*high));
-        high->major = 1;
-        high->minor = 2;
-        high->micro = 3;
-
-        LONGS_EQUAL(CELIX_SUCCESS, versionRange_createVersionRange(low, true, high, false, &range));
-        LONGS_EQUAL(CELIX_SUCCESS, versionRange_isInRange(range, version, &result));
-        LONGS_EQUAL(false, result);
-
-        versionRange_destroy(range);
-    }
-
-    {
-        version_range_pt range = NULL;
-
-        version_pt low = (version_pt) calloc(1, sizeof(*low));
-        low->major = 1;
-        low->minor = 2;
-        low->micro = 3;
-
-        version_pt high = (version_pt) calloc(1, sizeof(*high));
-        high->major = 1;
-        high->minor = 2;
-        high->micro = 3;
-
-        LONGS_EQUAL(CELIX_SUCCESS, versionRange_createVersionRange(low, false, high, false, &range));
-        LONGS_EQUAL(CELIX_SUCCESS, versionRange_isInRange(range, version, &result));
-        LONGS_EQUAL(false, result);
-
-        versionRange_destroy(range);
-    }
-
-    free(version);
-}
-
-TEST(version_range, parse) {
-    version_range_pt range = NULL;
-    version_pt low = (version_pt) calloc(1, sizeof(*low));
-    version_pt high = (version_pt) calloc(1, sizeof(*high));
-    char * version = my_strdup("[1.2.3,7.8.9]");
-    low->major = 1;
-    low->minor = 2;
-    low->micro = 3;
-
-    high->major = 7;
-    high->minor = 8;
-    high->micro = 9;
-
-    LONGS_EQUAL(CELIX_SUCCESS, versionRange_parse(version, &range));
-
-    versionRange_destroy(range);
-    free(version);
-    version = my_strdup("[1.2.3");
-
-    LONGS_EQUAL(CELIX_ILLEGAL_ARGUMENT, versionRange_parse(version, &range));
-
-    free(version);
-
-    free(high);
-    free(low);
-}
-
-TEST(version_range, createLdapFilterInclusiveBoth) {
-    version_pt low = (version_pt) calloc(1, sizeof(*low));
-    low->major = 1;
-    low->minor = 2;
-    low->micro = 3;
-    low->qualifier = NULL;
-
-    version_pt high = (version_pt) calloc(1, sizeof(*high));
-    high->major = 1;
-    high->minor = 2;
-    high->micro = 3;
-    high->qualifier = NULL;
-
-    version_range_pt range = NULL;
-    LONGS_EQUAL(CELIX_SUCCESS, versionRange_createVersionRange(low, true, high, true, &range));
-
-    auto filter = versionRange_createLDAPFilter(range, "service.version");
-    STRCMP_EQUAL(filter, "(&(service.version>=1.2.3)(service.version<=1.2.3))");
-
-    versionRange_destroy(range);
-    free(filter);
-}
-
-TEST(version_range, createLdapFilterInclusiveLow) {
-    version_pt low = (version_pt) calloc(1, sizeof(*low));
-    low->major = 1;
-    low->minor = 2;
-    low->micro = 3;
-    low->qualifier = NULL;
-
-    version_pt high = (version_pt) calloc(1, sizeof(*high));
-    high->major = 1;
-    high->minor = 2;
-    high->micro = 3;
-    high->qualifier = NULL;
-
-    version_range_pt range = NULL;
-    LONGS_EQUAL(CELIX_SUCCESS, versionRange_createVersionRange(low, false, high, true, &range));
-
-    auto filter = versionRange_createLDAPFilter(range, "service.version");
-    STRCMP_EQUAL(filter, "(&(service.version>1.2.3)(service.version<=1.2.3))");
-
-    versionRange_destroy(range);
-    free(filter);
-}
-
-TEST(version_range, createLdapFilterInclusiveHigh) {
-    version_pt low = (version_pt) calloc(1, sizeof(*low));
-    low->major = 1;
-    low->minor = 2;
-    low->micro = 3;
-    low->qualifier = NULL;
-
-    version_pt high = (version_pt) calloc(1, sizeof(*high));
-    high->major = 1;
-    high->minor = 2;
-    high->micro = 3;
-    high->qualifier = NULL;
-
-    version_range_pt range = NULL;
-    LONGS_EQUAL(CELIX_SUCCESS, versionRange_createVersionRange(low, true, high, false, &range));
-
-    auto filter = versionRange_createLDAPFilter(range, "service.version");
-    STRCMP_EQUAL(filter, "(&(service.version>=1.2.3)(service.version<1.2.3))");
-
-    versionRange_destroy(range);
-    free(filter);
-}
-
-TEST(version_range, createLdapFilterExclusiveBoth) {
-    version_pt low = (version_pt) calloc(1, sizeof(*low));
-    low->major = 1;
-    low->minor = 2;
-    low->micro = 3;
-    low->qualifier = NULL;
-
-    version_pt high = (version_pt) calloc(1, sizeof(*high));
-    high->major = 1;
-    high->minor = 2;
-    high->micro = 3;
-    high->qualifier = NULL;
-
-    version_range_pt range = NULL;
-    LONGS_EQUAL(CELIX_SUCCESS, versionRange_createVersionRange(low, false, high, false, &range));
-
-    auto filter = versionRange_createLDAPFilter(range, "service.version");
-    STRCMP_EQUAL(filter, "(&(service.version>1.2.3)(service.version<1.2.3))");
-
-    versionRange_destroy(range);
-    free(filter);
-}
-
-TEST(version_range, createLdapFilterInfinite) {
-    version_pt low = (version_pt) calloc(1, sizeof(*low));
-    low->major = 1;
-    low->minor = 2;
-    low->micro = 3;
-    low->qualifier = NULL;
-
-    version_range_pt range = NULL;
-    LONGS_EQUAL(CELIX_SUCCESS, versionRange_createVersionRange(low, true, NULL, true, &range));
-
-    auto filter = versionRange_createLDAPFilter(range, "service.version");
-    STRCMP_EQUAL(filter, "(&(service.version>=1.2.3))");
-
-    versionRange_destroy(range);
-    free(filter);
-}
-
-TEST(version_range, createLdapFilterInPlaceInclusiveBoth) {
-    version_pt low = (version_pt) calloc(1, sizeof(*low));
-    low->major = 1;
-    low->minor = 2;
-    low->micro = 3;
-    low->qualifier = NULL;
-
-    version_pt high = (version_pt) calloc(1, sizeof(*high));
-    high->major = 1;
-    high->minor = 2;
-    high->micro = 3;
-    high->qualifier = NULL;
-
-    version_range_pt range = NULL;
-    LONGS_EQUAL(CELIX_SUCCESS, versionRange_createVersionRange(low, true, high, true, &range));
-    char buffer[100];
-    int bufferLen = sizeof(buffer) / sizeof(buffer[0]);
-
-    LONGS_EQUAL(1, versionRange_createLDAPFilterInPlace(range, "service.version", buffer, bufferLen));
-
-    STRCMP_EQUAL(buffer, "(&(service.version>=1.2.3)(service.version<=1.2.3))");
-
-    versionRange_destroy(range);
-}
-
-TEST(version_range, createLdapFilterInPlaceInclusiveLow) {
-    version_pt low = (version_pt) calloc(1, sizeof(*low));
-    low->major = 1;
-    low->minor = 2;
-    low->micro = 3;
-    low->qualifier = NULL;
-
-    version_pt high = (version_pt) calloc(1, sizeof(*high));
-    high->major = 1;
-    high->minor = 2;
-    high->micro = 3;
-    high->qualifier = NULL;
-
-    version_range_pt range = NULL;
-    LONGS_EQUAL(CELIX_SUCCESS, versionRange_createVersionRange(low, true, high, false, &range));
-    char buffer[100];
-    int bufferLen = sizeof(buffer) / sizeof(buffer[0]);
-
-    LONGS_EQUAL(1, versionRange_createLDAPFilterInPlace(range, "service.version", buffer, bufferLen));
-
-    STRCMP_EQUAL(buffer, "(&(service.version>=1.2.3)(service.version<1.2.3))");
-
-    versionRange_destroy(range);
-}
-
-TEST(version_range, createLdapFilterInPlaceInclusiveHigh) {
-    version_pt low = (version_pt) calloc(1, sizeof(*low));
-    low->major = 1;
-    low->minor = 2;
-    low->micro = 3;
-    low->qualifier = NULL;
-
-    version_pt high = (version_pt) calloc(1, sizeof(*high));
-    high->major = 1;
-    high->minor = 2;
-    high->micro = 3;
-    high->qualifier = NULL;
-
-    version_range_pt range = NULL;
-    LONGS_EQUAL(CELIX_SUCCESS, versionRange_createVersionRange(low, false, high, true, &range));
-    char buffer[100];
-    int bufferLen = sizeof(buffer) / sizeof(buffer[0]);
-
-    LONGS_EQUAL(1, versionRange_createLDAPFilterInPlace(range, "service.version", buffer, bufferLen));
-
-    STRCMP_EQUAL(buffer, "(&(service.version>1.2.3)(service.version<=1.2.3))");
-
-    versionRange_destroy(range);
-}
-
-TEST(version_range, createLdapFilterInPlaceExclusiveBoth) {
-    version_pt low = (version_pt) calloc(1, sizeof(*low));
-    low->major = 1;
-    low->minor = 2;
-    low->micro = 3;
-    low->qualifier = NULL;
-
-    version_pt high = (version_pt) calloc(1, sizeof(*high));
-    high->major = 1;
-    high->minor = 2;
-    high->micro = 3;
-    high->qualifier = NULL;
-
-    version_range_pt range = NULL;
-    LONGS_EQUAL(CELIX_SUCCESS, versionRange_createVersionRange(low, false, high, false, &range));
-    char buffer[100];
-    int bufferLen = sizeof(buffer) / sizeof(buffer[0]);
-
-    LONGS_EQUAL(1, versionRange_createLDAPFilterInPlace(range, "service.version", buffer, bufferLen));
-
-    STRCMP_EQUAL(buffer, "(&(service.version>1.2.3)(service.version<1.2.3))");
-
-    versionRange_destroy(range);
-}
-
-TEST(version_range, createLdapFilterInPlaceInfiniteHigh) {
-    version_pt low = (version_pt) calloc(1, sizeof(*low));
-    low->major = 1;
-    low->minor = 2;
-    low->micro = 3;
-    low->qualifier = NULL;
-
-    version_range_pt range = NULL;
-    LONGS_EQUAL(CELIX_SUCCESS, versionRange_createVersionRange(low, false, NULL, false, &range));
-    char buffer[100];
-    int bufferLen = sizeof(buffer) / sizeof(buffer[0]);
-
-    LONGS_EQUAL(1, versionRange_createLDAPFilterInPlace(range, "service.version", buffer, bufferLen));
-
-    STRCMP_EQUAL(buffer, "(&(service.version>1.2.3))");
-
-    versionRange_destroy(range);
-}
-
-
-
-
diff --git a/libs/utils/private/test/version_test.cpp b/libs/utils/private/test/version_test.cpp
index 666a0af..1fa59e7 100644
--- a/libs/utils/private/test/version_test.cpp
+++ b/libs/utils/private/test/version_test.cpp
@@ -401,3 +401,14 @@ TEST(version,semanticCompatibility) {
     version_destroy(incompatible_user_by_minor);
 }
 
+TEST(version, compareEmptyAndNullQualifier) {
+    //nullptr or "" qualifier should be the same
+    auto* v1 = celix_version_createVersion(0, 0, 0, nullptr);
+    auto* v2 = celix_version_createVersion(0, 0, 0, "");
+    CHECK_EQUAL(0, celix_version_compareTo(v1, v1));
+    CHECK_EQUAL(0, celix_version_compareTo(v1, v2));
+    CHECK_EQUAL(0, celix_version_compareTo(v2, v2));
+
+    celix_version_destroy(v1);
+    celix_version_destroy(v2);
+}
\ No newline at end of file
diff --git a/libs/utils/src/utils.c b/libs/utils/src/utils.c
index f82bd26..5d5a860 100644
--- a/libs/utils/src/utils.c
+++ b/libs/utils/src/utils.c
@@ -61,6 +61,10 @@ bool celix_utils_stringEquals(const char* a, const char* b) {
     }
 }
 
+bool celix_utils_isStringNullOrEmpty(const char* s) {
+    return s == NULL || strlen(s) == 0;
+}
+
 char * string_ndup(const char *s, size_t n) {
     size_t len = strlen(s);
     char *ret;
diff --git a/libs/utils/src/version.c b/libs/utils/src/version.c
index fc3ba9d..f67bacc 100644
--- a/libs/utils/src/version.c
+++ b/libs/utils/src/version.c
@@ -134,11 +134,7 @@ celix_version_t* celix_version_createVersion(int major, int minor, int micro, co
 
 void celix_version_destroy(celix_version_t* version) {
     if (version != NULL) {
-        version->major = 0;
-        version->minor = 0;
-        version->micro = 0;
         free(version->qualifier);
-        version->qualifier = NULL;
         free(version);
     }
 }
@@ -265,9 +261,9 @@ int celix_version_compareTo(const celix_version_t* version, const celix_version_
                 if (res != 0) {
                     result = res;
                 } else {
-                    if(version->qualifier == NULL && compare->qualifier == NULL) {
+                    if(celix_utils_isStringNullOrEmpty(version->qualifier) && celix_utils_isStringNullOrEmpty(version->qualifier)) {
                         result = 0;
-                    } else if (version->qualifier == NULL || compare->qualifier == NULL) {
+                    } else if (celix_utils_isStringNullOrEmpty(version->qualifier) || celix_utils_isStringNullOrEmpty(version->qualifier)) {
                         result = -1;
                     } else {
                         result = strcmp(version->qualifier, compare->qualifier);
diff --git a/libs/utils/src/version_range.c b/libs/utils/src/version_range.c
index 8d5a6ee..1a6a48a 100644
--- a/libs/utils/src/version_range.c
+++ b/libs/utils/src/version_range.c
@@ -16,13 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-/**
- * version_range.c
- *
- *  \date       Jul 12, 2010
- *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright  Apache License, Version 2.0
- */
+
 
 #include <stdlib.h>
 #include <string.h>
@@ -30,102 +24,34 @@
 #include <assert.h>
 
 #include "version_private.h"
+#include "version_range.h"
+#include "celix_version_range.h"
 #include "version_range_private.h"
+#include "celix_version_range.h"
 
 celix_status_t versionRange_createVersionRange(version_pt low, bool isLowInclusive,
             version_pt high, bool isHighInclusive, version_range_pt *range) {
-    assert(low != high);
-    celix_status_t status = CELIX_SUCCESS;
-    *range = (version_range_pt) malloc(sizeof(**range));
-    if (!*range) {
-        status = CELIX_ENOMEM;
-    } else {
-        (*range)->low = low;
-        (*range)->isLowInclusive = isLowInclusive;
-        (*range)->high = high;
-        (*range)->isHighInclusive = isHighInclusive;
-    }
-
-    return status;
+    *range = celix_versionRange_createVersionRange(low, isLowInclusive, high, isHighInclusive);
+    return CELIX_SUCCESS;
 }
 
 celix_status_t versionRange_destroy(version_range_pt range) {
-    if (range->high != NULL) {
-        version_destroy(range->high);
-    }
-    if (range->low != NULL) {
-        version_destroy(range->low);
-    }
-
-    range->high = NULL;
-    range->isHighInclusive = false;
-    range->low = NULL;
-    range->isLowInclusive = false;
-
-    free(range);
-
+    celix_versionRange_destroy(range);
     return CELIX_SUCCESS;
 }
 
 celix_status_t versionRange_createInfiniteVersionRange(version_range_pt *range) {
-    celix_status_t status;
-
-    version_pt version = NULL;
-    status = version_createEmptyVersion(&version);
-    if (status == CELIX_SUCCESS) {
-        status = versionRange_createVersionRange(version, true, NULL, true, range);
-    }
-
-    return status;
+    *range = celix_versionRange_createInfiniteVersionRange();
+    return CELIX_SUCCESS;
 }
 
 celix_status_t versionRange_isInRange(version_range_pt versionRange, version_pt version, bool *inRange) {
-    celix_status_t status;
-    if (versionRange->high == NULL) {
-        int cmp;
-        status = version_compareTo(version, versionRange->low, &cmp);
-        if (status == CELIX_SUCCESS) {
-            *inRange = (cmp >= 0);
-        }
-    } else if (versionRange->isLowInclusive && versionRange->isHighInclusive) {
-        int low, high;
-        status = version_compareTo(version, versionRange->low, &low);
-        if (status == CELIX_SUCCESS) {
-            status = version_compareTo(version, versionRange->high, &high);
-            if (status == CELIX_SUCCESS) {
-                *inRange = (low >= 0) && (high <= 0);
-            }
-        }
-    } else if (versionRange->isHighInclusive) {
-        int low, high;
-        status = version_compareTo(version, versionRange->low, &low);
-        if (status == CELIX_SUCCESS) {
-            status = version_compareTo(version, versionRange->high, &high);
-            if (status == CELIX_SUCCESS) {
-                *inRange = (low > 0) && (high <= 0);
-            }
-        }
-    } else if (versionRange->isLowInclusive) {
-        int low, high;
-        status = version_compareTo(version, versionRange->low, &low);
-        if (status == CELIX_SUCCESS) {
-            status = version_compareTo(version, versionRange->high, &high);
-            if (status == CELIX_SUCCESS) {
-                *inRange = (low >= 0) && (high < 0);
-            }
-        }
+    if (versionRange != NULL && version != NULL) {
+        *inRange = celix_versionRange_isInRange(versionRange, version);
+        return CELIX_SUCCESS;
     } else {
-        int low, high;
-        status = version_compareTo(version, versionRange->low, &low);
-        if (status == CELIX_SUCCESS) {
-            status = version_compareTo(version, versionRange->high, &high);
-            if (status == CELIX_SUCCESS) {
-                *inRange = (low > 0) && (high < 0);
-            }
-        }
+        return CELIX_ILLEGAL_ARGUMENT;
     }
-
-    return status;
 }
 
 celix_status_t versionRange_getLowVersion(version_range_pt versionRange, version_pt *lowVersion) {
@@ -182,61 +108,139 @@ celix_status_t versionRange_isHighInclusive(version_range_pt versionRange, bool
 
 
 celix_status_t versionRange_parse(const char * rangeStr, version_range_pt *range) {
-    celix_status_t status;
-    if (strchr(rangeStr, ',') != NULL) {
-            int vlowL = strcspn(rangeStr+1, ",");
-            char * vlow = (char *) malloc(sizeof(char) * (vlowL + 1));
-            if (!vlow) {
-                status = CELIX_ENOMEM;
-            } else {
-                int vhighL;
-                char * vhigh;
-                vlow = strncpy(vlow, rangeStr+1, vlowL);
-                vlow[vlowL] = '\0';
-                vhighL = strlen(rangeStr+1) - vlowL - 2;
-                vhigh = (char *) malloc(sizeof(char) * (vhighL+1));
-                if (!vhigh) {
-                    status = CELIX_ENOMEM;
-                } else {                    
-                    version_pt versionLow = NULL;
-                    int rangeL = strlen(rangeStr);
-                    char start = rangeStr[0];
-                    char end = rangeStr[rangeL-1];
-
-                    vhigh = strncpy(vhigh, rangeStr+vlowL+2, vhighL);
-                    vhigh[vhighL] = '\0';
-                    status = version_createVersionFromString(vlow, &versionLow);
-                    if (status == CELIX_SUCCESS) {
-                        version_pt versionHigh = NULL;
-                        status = version_createVersionFromString(vhigh, &versionHigh);
-                        if (status == CELIX_SUCCESS) {
-                            status = versionRange_createVersionRange(
-                                    versionLow,
-                                    start == '[',
-                                    versionHigh,
-                                    end ==']',
-                                    range
-                                );
-                        }
-                    }
-                    free(vhigh);
-                }
-                free(vlow);
+    *range = celix_versionRange_parse(rangeStr);
+    if (*range == NULL) {
+        return CELIX_ILLEGAL_ARGUMENT;
+    } else {
+        return CELIX_SUCCESS;
+    }
+}
 
+char* versionRange_createLDAPFilter(version_range_pt range, const char *serviceVersionAttributeName) {
+    return celix_versionRange_createLDAPFilter(range, serviceVersionAttributeName);
+}
+
+
+
+bool versionRange_createLDAPFilterInPlace(version_range_pt range, const char *serviceVersionAttributeName, char* buffer, size_t bufferLength) {
+    return celix_versionRange_createLDAPFilterInPlace(range, serviceVersionAttributeName, buffer, bufferLength);
+}
+
+celix_version_range_t* celix_versionRange_createVersionRange(celix_version_t* low, bool isLowInclusive, celix_version_t* high, bool isHighInclusive) {
+    assert(low != high);
+    celix_version_range_t* range = malloc(sizeof(*range));
+    range->low = low;
+    range->isLowInclusive = isLowInclusive;
+    range->high = high;
+    range->isHighInclusive = isHighInclusive;
+    return range;
+}
+
+
+celix_version_range_t* celix_versionRange_createInfiniteVersionRange() {
+    return celix_versionRange_createVersionRange(celix_version_createEmptyVersion(), true, NULL, true);
+}
+
+void celix_versionRange_destroy(celix_version_range_t* range) {
+    if (range->high != NULL) {
+        celix_version_destroy(range->high);
+    }
+    if (range->low != NULL) {
+        celix_version_destroy(range->low);
+    }
+    free(range);
+}
+
+
+bool celix_versionRange_isInRange(const celix_version_range_t* versionRange, const celix_version_t* version) {
+    bool inRange = false;
+    int high;
+    int low;
+    if (versionRange->high != NULL) {
+        high = celix_version_compareTo(version, versionRange->high);
+    }
+    if (versionRange->low != NULL) {
+        low = celix_version_compareTo(version, versionRange->low);
+    }
+
+    if (versionRange->high == NULL) {
+        inRange = (low >= 0);
+    } else if (versionRange->isLowInclusive && versionRange->isHighInclusive) {
+        inRange = (low >= 0) && (high <= 0);
+    } else if (versionRange->isHighInclusive) {
+        inRange = (low > 0) && (high <= 0);
+    } else if (versionRange->isLowInclusive) {
+        inRange = (low >= 0) && (high < 0);
+    } else {
+        inRange = (low > 0) && (high < 0);
+    }
+
+    return inRange;
+}
+
+
+bool celix_versionRange_isLowInclusive(const celix_version_range_t* versionRange) {
+    return versionRange->isLowInclusive;
+}
+
+
+bool celix_versionRange_isHighInclusive(const celix_version_range_t* versionRange) {
+    return versionRange->isHighInclusive;
+}
+
+
+celix_version_t* celix_versionRange_getLowVersion(const celix_version_range_t* versionRange) {
+    return versionRange->low;
+}
+
+
+celix_version_t* celix_versionRange_getHighVersion(const celix_version_range_t* versionRange) {
+    return versionRange->high;
+}
+
+celix_version_range_t* celix_versionRange_parse(const char *rangeString) {
+    celix_version_range_t* range = NULL;
+    if (strchr(rangeString, ',') != NULL) {
+        int vlowL = strcspn(rangeString+1, ",");
+        char * vlow = malloc(sizeof(char) * (vlowL + 1));
+        int vhighL;
+        char * vhigh;
+        vlow = strncpy(vlow, rangeString+1, vlowL);
+        vlow[vlowL] = '\0';
+        vhighL = strlen(rangeString+1) - vlowL - 2;
+        vhigh = (char *) malloc(sizeof(char) * (vhighL+1));
+        int rangeL = strlen(rangeString);
+        char start = rangeString[0];
+        char end = rangeString[rangeL-1];
+
+        vhigh = strncpy(vhigh, rangeString+vlowL+2, vhighL);
+        vhigh[vhighL] = '\0';
+        celix_version_t* versionLow = celix_version_createVersionFromString(vlow);
+        if (versionLow != NULL) {
+            celix_version_t* versionHigh = celix_version_createVersionFromString(vhigh);
+            if (versionHigh != NULL) {
+                range = celix_versionRange_createVersionRange(
+                        versionLow,
+                        start == '[',
+                        versionHigh,
+                        end ==']'
+                );
+            }
         }
+        free(vhigh);
+        free(vlow);
     } else {
-        version_pt version = NULL;
-        status = version_createVersionFromString(rangeStr, &version);
-        if (status == CELIX_SUCCESS) {
-            status = versionRange_createVersionRange(version, true, NULL, false, range);
+        celix_version_t* version = celix_version_createVersionFromString(rangeString);
+        if (version != NULL) {
+            range = celix_versionRange_createVersionRange(version, true, NULL, false);
         }
     }
 
-    return status;
+    return range;
 }
 
-char* versionRange_createLDAPFilter(version_range_pt range, const char *serviceVersionAttributeName) {
-    char *output;
+char* celix_versionRange_createLDAPFilter(const celix_version_range_t* range, const char *serviceVersionAttributeName) {
+    char *output = NULL;
 
     int ret = -1;
     if(range->high == NULL) {
@@ -258,9 +262,7 @@ char* versionRange_createLDAPFilter(version_range_pt range, const char *serviceV
     return output;
 }
 
-
-
-bool versionRange_createLDAPFilterInPlace(version_range_pt range, const char *serviceVersionAttributeName, char* buffer, size_t bufferLength) {
+bool celix_versionRange_createLDAPFilterInPlace(const celix_version_range_t* range, const char *serviceVersionAttributeName, char* buffer, size_t bufferLength) {
     if(buffer == NULL || bufferLength == 0) {
         return false;
     }
diff --git a/libs/utils/src/version_range_private.h b/libs/utils/src/version_range_private.h
index bcd8296..757090f 100644
--- a/libs/utils/src/version_range_private.h
+++ b/libs/utils/src/version_range_private.h
@@ -16,23 +16,16 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-/**
- * version_range_private.h
- *
- *  \date       Dec 18, 2012
- *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
- *  \copyright  Apache License, Version 2.0
- */
 
 #ifndef VERSION_RANGE_PRIVATE_H_
 #define VERSION_RANGE_PRIVATE_H_
 
-#include "version_range.h"
+#include "celix_version.h"
 
-struct versionRange {
-    version_pt low;
+struct celix_version_range {
+    celix_version_t* low;
     bool isLowInclusive;
-    version_pt high;
+    celix_version_t* high;
     bool isHighInclusive;
 };