celix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pnol...@apache.org
Subject [4/4] celix git commit: CELIX-210: renamed dep man 2 -> dep man 2. Fixed whiteboard dep man example
Date Mon, 12 Oct 2015 10:53:31 GMT
CELIX-210: renamed dep man 2 -> dep man 2. Fixed whiteboard dep man example


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

Branch: refs/heads/feature/CELIX-269_depman
Commit: cc6fd432219484218bcb462e7974ee48c77930b4
Parents: a135fad
Author: Pepijn Noltes <pepijnnoltes@gmail.com>
Authored: Mon Oct 12 10:45:10 2015 +0200
Committer: Pepijn Noltes <pepijnnoltes@gmail.com>
Committed: Mon Oct 12 10:45:10 2015 +0200

----------------------------------------------------------------------
 CMakeLists.txt                                  |    2 +-
 dependency_manager/CMakeLists.txt               |   61 +
 .../private/include/dm_component_impl.h         |   84 ++
 .../private/include/dm_dependency.h             |   34 +
 dependency_manager/private/include/dm_event.h   |   63 +
 .../include/dm_service_dependency_impl.h        |   90 ++
 .../private/src/dm_activator_base.c             |   98 ++
 .../private/src/dm_component_impl.c             | 1277 ++++++++++++++++++
 .../private/src/dm_dependency_manager_impl.c    |   91 ++
 dependency_manager/private/src/dm_event.c       |   92 ++
 .../private/src/dm_service_dependency.c         |  564 ++++++++
 .../public/include/dm_activator_base.h          |   41 +
 .../public/include/dm_component.h               |   54 +
 .../public/include/dm_dependency_manager.h      |   45 +
 .../public/include/dm_service_dependency.h      |   55 +
 dependency_manager_2/CMakeLists.txt             |   61 -
 .../private/include/dm_component_impl.h         |   84 --
 .../private/include/dm_dependency.h             |   34 -
 dependency_manager_2/private/include/dm_event.h |   63 -
 .../include/dm_service_dependency_impl.h        |   90 --
 .../private/src/dm_activator_base.c             |   98 --
 .../private/src/dm_component_impl.c             | 1277 ------------------
 .../private/src/dm_dependency_manager_impl.c    |   91 --
 dependency_manager_2/private/src/dm_event.c     |   92 --
 .../private/src/dm_service_dependency.c         |  564 --------
 .../public/include/dm_activator_base.h          |   41 -
 .../public/include/dm_component.h               |   54 -
 .../public/include/dm_dependency_manager.h      |   45 -
 .../public/include/dm_service_dependency.h      |   55 -
 .../whiteboard/tracker_depman/CMakeLists.txt    |    8 +-
 .../private/src/dependency_activator.c          |    6 +-
 .../tracker_depman/private/src/tracker.c        |   44 +-
 32 files changed, 2679 insertions(+), 2679 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/cc6fd432/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/CMakeLists.txt b/CMakeLists.txt
index a885df5..6db8dd1 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -77,7 +77,7 @@ add_subdirectory(log_writer)
 add_subdirectory(log_service)
 
 add_subdirectory(event_admin)
-add_subdirectory(dependency_manager_2)
+add_subdirectory(dependency_manager)
 
 add_subdirectory(launcher)
 add_subdirectory(framework)

http://git-wip-us.apache.org/repos/asf/celix/blob/cc6fd432/dependency_manager/CMakeLists.txt
----------------------------------------------------------------------
diff --git a/dependency_manager/CMakeLists.txt b/dependency_manager/CMakeLists.txt
new file mode 100644
index 0000000..6b76658
--- /dev/null
+++ b/dependency_manager/CMakeLists.txt
@@ -0,0 +1,61 @@
+# 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.
+
+celix_subproject(DEPENDENCY_MANAGER "Option to build the dependency manager static library" ON DEPS framework)
+if (DEPENDENCY_MANAGER) 
+    # Add -fPIC for x86_64 Unix platforms; this lib will be linked to a shared lib
+    if(UNIX AND NOT WIN32)
+      find_program(CMAKE_UNAME uname /bin /usr/bin /usr/local/bin )
+      if(CMAKE_UNAME)
+        exec_program(uname ARGS -m OUTPUT_VARIABLE CMAKE_SYSTEM_PROCESSOR)
+        set(CMAKE_SYSTEM_PROCESSOR ${CMAKE_SYSTEM_PROCESSOR} CACHE INTERNAL "processor type (i386 and x86_64)")
+         if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
+          add_definitions(-fPIC)
+        endif(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
+      endif(CMAKE_UNAME)
+    endif(UNIX AND NOT WIN32)
+    
+    CELIX_ADD_COMPONENT(dependency_manager
+    	DISPLAY_NAME Dependency Manager
+        DESCRIPTION "The Apache Celix dependency manager (static) library"
+        GROUP all
+    )
+    
+    add_library(dependency_manager STATIC 
+    	private/src/dm_activator_base 
+    	private/src/dm_component_impl 
+    	private/src/dm_service_dependency
+    	private/src/dm_event
+    	private/src/dm_dependency_manager_impl)
+   	include_directories("public/include")
+   	include_directories("private/include")
+    include_directories("${PROJECT_SOURCE_DIR}/utils/public/include")
+    target_link_libraries(dependency_manager celix_framework)
+    
+    install(
+    	FILES
+    	    public/include/dm_activator_base.h
+            public/include/dm_component.h
+            public/include/dm_dependency_manager.h
+            public/include/dm_service_dependency.h
+		DESTINATION 
+			include/celix/dependency_manager
+		COMPONENT 
+			dependency_manager
+	)
+    install(TARGETS dependency_manager DESTINATION lib COMPONENT dependency_manager)
+endif (DEPENDENCY_MANAGER)

http://git-wip-us.apache.org/repos/asf/celix/blob/cc6fd432/dependency_manager/private/include/dm_component_impl.h
----------------------------------------------------------------------
diff --git a/dependency_manager/private/include/dm_component_impl.h b/dependency_manager/private/include/dm_component_impl.h
new file mode 100644
index 0000000..133ef06
--- /dev/null
+++ b/dependency_manager/private/include/dm_component_impl.h
@@ -0,0 +1,84 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * dm_component_impl.h
+ *
+ *  \date       22 Feb 2014
+ *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright  Apache License, Version 2.0
+ */
+
+#ifndef COMPONENT_IMPL_H_
+#define COMPONENT_IMPL_H_
+
+#include "dm_component.h"
+
+#include "dm_service_dependency_impl.h"
+
+#include "dm_event.h"
+
+typedef enum dm_component_state {
+    DM_CMP_STATE_INACTIVE = 1,
+    DM_CMP_STATE_WAITING_FOR_REQUIRED,
+    DM_CMP_STATE_INSTANTIATED_AND_WAITING_FOR_REQUIRED,
+    DM_CMP_STATE_TRACKING_OPTIONAL,
+} dm_component_state_pt;
+
+typedef struct dm_executor * dm_executor_pt;
+
+typedef struct dm_interface_struct {
+    char *serviceName;
+    void *service;
+    properties_pt properties;
+    service_registration_pt registration;
+} dm_interface;
+
+struct dm_component {
+    bundle_context_pt context;
+    dm_dependency_manager_pt manager;
+
+    array_list_pt dm_interface;
+
+    void *implementation;
+
+    init_fpt callbackInit;
+    start_fpt callbackStart;
+    stop_fpt callbackStop;
+    destroy_fpt callbackDestroy;
+
+    array_list_pt dependencies;
+    pthread_mutex_t mutex;
+
+    dm_component_state_pt state;
+    bool isStarted;
+    bool active;
+
+    hash_map_pt dependencyEvents;
+
+    dm_executor_pt executor;
+};
+
+celix_status_t component_start(dm_component_pt component);
+celix_status_t component_stop(dm_component_pt component);
+
+celix_status_t component_getBundleContext(dm_component_pt component, bundle_context_pt *context);
+
+celix_status_t component_handleEvent(dm_component_pt component, dm_service_dependency_pt dependency, dm_event_pt event);
+
+#endif /* COMPONENT_IMPL_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/cc6fd432/dependency_manager/private/include/dm_dependency.h
----------------------------------------------------------------------
diff --git a/dependency_manager/private/include/dm_dependency.h b/dependency_manager/private/include/dm_dependency.h
new file mode 100644
index 0000000..e7ad5fb
--- /dev/null
+++ b/dependency_manager/private/include/dm_dependency.h
@@ -0,0 +1,34 @@
+/**
+ *Licensed to the Apache Software Foundation (ASF) under one
+ *or more contributor license agreements.  See the NOTICE file
+ *distributed with this work for additional information
+ *regarding copyright ownership.  The ASF licenses this file
+ *to you under the Apache License, Version 2.0 (the
+ *"License"); you may not use this file except in compliance
+ *with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *Unless required by applicable law or agreed to in writing,
+ *software distributed under the License is distributed on an
+ *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ *specific language governing permissions and limitations
+ *under the License.
+ */
+/*
+ * dm_dependency.h
+ *
+ *  \date       22 Feb 2014
+ *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright  Apache License, Version 2.0
+ */
+
+#ifndef DM_DEPENDENCY_H_
+#define DM_DEPENDENCY_H_
+
+
+
+
+
+#endif /* DM_DEPENDENCY_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/cc6fd432/dependency_manager/private/include/dm_event.h
----------------------------------------------------------------------
diff --git a/dependency_manager/private/include/dm_event.h b/dependency_manager/private/include/dm_event.h
new file mode 100644
index 0000000..8e23721
--- /dev/null
+++ b/dependency_manager/private/include/dm_event.h
@@ -0,0 +1,63 @@
+/**
+ *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_
+
+#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 {
+	void *service;
+	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, void *service, dm_event_pt *event);
+celix_status_t event_destroy(dm_event_pt *event);
+
+celix_status_t event_equals(void *a, void *b, bool *equals);
+
+celix_status_t event_getService(dm_event_pt event, void **service);
+celix_status_t event_compareTo(dm_event_pt event, dm_event_pt compareTo, int *compare);
+
+
+#endif /* DM_EVENT_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/cc6fd432/dependency_manager/private/include/dm_service_dependency_impl.h
----------------------------------------------------------------------
diff --git a/dependency_manager/private/include/dm_service_dependency_impl.h b/dependency_manager/private/include/dm_service_dependency_impl.h
new file mode 100644
index 0000000..1396f31
--- /dev/null
+++ b/dependency_manager/private/include/dm_service_dependency_impl.h
@@ -0,0 +1,90 @@
+/**
+ *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_service_dependency_impl.h
+ *
+ *  \date       8 Oct 2014
+ *  \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_
+
+#include <stdbool.h>
+
+#include "dm_event.h"
+#include "service_tracker.h"
+#include "service_tracker_customizer.h"
+
+#include "dm_service_dependency.h"
+
+struct dm_service_dependency {
+	dm_component_pt component;
+	bool available;
+	bool instanceBound;
+	bool required;
+
+	service_add_fpt add;
+	service_change_fpt change;
+	service_remove_fpt remove;
+	service_swap_fpt swap;
+
+	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;
+
+	void **autoConfigure;
+	celix_thread_mutex_t lock;
+
+	bool isStarted;
+
+	char *tracked_service_name;
+	char *tracked_filter_unmodified;
+	char *tracked_filter;
+
+	service_tracker_pt tracker;
+	service_tracker_customizer_pt tracker_customizer;
+};
+
+celix_status_t serviceDependency_start(dm_service_dependency_pt dependency);
+celix_status_t serviceDependency_stop(dm_service_dependency_pt dependency);
+celix_status_t serviceDependency_setInstanceBound(dm_service_dependency_pt dependency, bool instanceBound);
+celix_status_t serviceDependency_setAutoConfig(dm_service_dependency_pt dependency, void **autoConfigure);
+celix_status_t serviceDependency_setAvailable(dm_service_dependency_pt dependency, bool available);
+
+celix_status_t serviceDependency_setComponent(dm_service_dependency_pt dependency, dm_component_pt component);
+//celix_status_t serviceDependency_removeComponent(dm_service_dependency_pt dependency, dm_component_pt component);
+
+celix_status_t serviceDependency_invokeAdd(dm_service_dependency_pt dependency, dm_event_pt event);
+celix_status_t serviceDependency_invokeChange(dm_service_dependency_pt dependency, dm_event_pt event);
+celix_status_t serviceDependency_invokeRemove(dm_service_dependency_pt dependency, dm_event_pt event);
+celix_status_t serviceDependency_invokeSwap(dm_service_dependency_pt dependency, dm_event_pt event, dm_event_pt newEvent);
+celix_status_t serviceDependency_isAvailable(dm_service_dependency_pt dependency, bool *available);
+celix_status_t serviceDependency_isRequired(dm_service_dependency_pt dependency, bool *required);
+celix_status_t serviceDependency_isInstanceBound(dm_service_dependency_pt dependency, bool *instanceBound);
+celix_status_t serviceDependency_isAutoConfig(dm_service_dependency_pt dependency, bool *autoConfig);
+
+celix_status_t serviceDependency_getAutoConfig(dm_service_dependency_pt dependency, void ***autoConfigure);
+celix_status_t serviceDependency_unlock(dm_service_dependency_pt dependency);
+celix_status_t serviceDependency_lock(dm_service_dependency_pt dependency);
+
+
+#endif /* DM_SERVICE_DEPENDENCY_IMPL_H_ */

http://git-wip-us.apache.org/repos/asf/celix/blob/cc6fd432/dependency_manager/private/src/dm_activator_base.c
----------------------------------------------------------------------
diff --git a/dependency_manager/private/src/dm_activator_base.c b/dependency_manager/private/src/dm_activator_base.c
new file mode 100644
index 0000000..a97194e
--- /dev/null
+++ b/dependency_manager/private/src/dm_activator_base.c
@@ -0,0 +1,98 @@
+/**
+ * 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_activator_base.c
+ *
+ *  \date       26 Jul 2014
+ *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright  Apache License, Version 2.0
+ */
+
+
+#include <stdlib.h>
+
+#include "bundle_activator.h"
+#include "dm_activator_base.h"
+
+
+struct dm_dependency_activator_base {
+	dm_dependency_manager_pt manager;
+	bundle_context_pt context;
+	void* userData;
+};
+
+typedef struct dm_dependency_activator_base * dependency_activator_base_pt;
+
+celix_status_t bundleActivator_create(bundle_context_pt context, void **userData) {
+	celix_status_t status = CELIX_ENOMEM;
+
+	dependency_activator_base_pt dependency_activator = calloc(1, sizeof(struct dm_dependency_activator_base));
+
+	if (dependency_activator) {
+		dependency_activator->context = context;
+		dm_create(context, &dependency_activator->userData);
+
+		(*userData) = dependency_activator;
+
+		status = CELIX_SUCCESS;
+	}
+
+	return status;
+}
+
+celix_status_t bundleActivator_start(void * userData, bundle_context_pt context) {
+	celix_status_t status;
+	dependency_activator_base_pt dependency_activator = (dependency_activator_base_pt) userData;
+
+	status = dependencyManager_create(dependency_activator->context, &dependency_activator->manager);
+
+	if (status == CELIX_SUCCESS) {
+		dm_init(dependency_activator->userData, context, dependency_activator->manager);
+	}
+
+	return status;
+}
+
+celix_status_t bundleActivator_stop(void * userData, bundle_context_pt context __attribute__((unused))) {
+	celix_status_t status = CELIX_SUCCESS;
+	dependency_activator_base_pt dependency_activator = (dependency_activator_base_pt) userData;
+
+	dm_deinit(dependency_activator->userData, dependency_activator->context, dependency_activator->manager);
+
+	dependencyManager_destroy(&dependency_activator->manager);
+
+	dependency_activator->userData = NULL;
+	dependency_activator->manager = NULL;
+
+	return status;
+}
+
+celix_status_t bundleActivator_destroy(void * userData, bundle_context_pt context __attribute__((unused))) {
+	celix_status_t status = CELIX_SUCCESS;
+	dependency_activator_base_pt dependency_activator = (dependency_activator_base_pt) userData;
+
+	dm_destroy(dependency_activator->userData, dependency_activator->context, dependency_activator->manager);
+
+	free(dependency_activator);
+
+	return status;
+}
+
+

http://git-wip-us.apache.org/repos/asf/celix/blob/cc6fd432/dependency_manager/private/src/dm_component_impl.c
----------------------------------------------------------------------
diff --git a/dependency_manager/private/src/dm_component_impl.c b/dependency_manager/private/src/dm_component_impl.c
new file mode 100644
index 0000000..72fe7eb
--- /dev/null
+++ b/dependency_manager/private/src/dm_component_impl.c
@@ -0,0 +1,1277 @@
+/**
+ *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_component_impl.c
+ *
+ *  \date       9 Oct 2014
+ *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright  Apache License, Version 2.0
+ */
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "dm_component_impl.h"
+#include "../../../framework/private/include/framework_private.h"
+
+struct dm_executor {
+    pthread_t runningThread;
+    bool runningThreadSet;
+    linked_list_pt workQueue;
+
+    pthread_mutex_t mutex;
+};
+
+struct dm_executor_task {
+    dm_component_pt component;
+    void (*command)(void *command_ptr, void *data);
+    void *data;
+};
+
+struct dm_handle_event_type {
+	dm_service_dependency_pt dependency;
+	dm_event_pt event;
+	dm_event_pt newEvent;
+};
+
+typedef struct dm_handle_event_type *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, dm_component_pt component, void (*command), void *data);
+static celix_status_t executor_schedule(dm_executor_pt executor, dm_component_pt component, void (*command), void *data);
+static celix_status_t executor_create(dm_component_pt component __attribute__((unused)), dm_executor_pt *executor);
+static celix_status_t executor_destroy(dm_executor_pt *executor);
+
+static celix_status_t component_destroyComponent(dm_component_pt component);
+static celix_status_t component_invokeRemoveRequiredDependencies(dm_component_pt component);
+static celix_status_t component_invokeRemoveInstanceBoundDependencies(dm_component_pt component);
+static celix_status_t component_invokeRemoveOptionalDependencies(dm_component_pt component);
+static celix_status_t component_registerService(dm_component_pt component);
+static celix_status_t component_unregisterService(dm_component_pt component);
+static celix_status_t component_invokeAddOptionalDependencies(dm_component_pt component);
+static celix_status_t component_invokeAddRequiredInstanceBoundDependencies(dm_component_pt component);
+static celix_status_t component_invokeAddRequiredDependencies(dm_component_pt component);
+static celix_status_t component_invokeAutoConfigInstanceBoundDependencies(dm_component_pt component);
+static celix_status_t component_invokeAutoConfigDependencies(dm_component_pt component);
+static celix_status_t component_configureImplementation(dm_component_pt component, dm_service_dependency_pt dependency);
+static celix_status_t component_allInstanceBoundAvailable(dm_component_pt component, bool *available);
+static celix_status_t component_allRequiredAvailable(dm_component_pt component, bool *available);
+static celix_status_t component_performTransition(dm_component_pt component, dm_component_state_pt oldState, dm_component_state_pt newState, bool *transition);
+static celix_status_t component_calculateNewState(dm_component_pt component, dm_component_state_pt currentState, dm_component_state_pt *newState);
+static celix_status_t component_handleChange(dm_component_pt component);
+static celix_status_t component_startDependencies(dm_component_pt component __attribute__((unused)), array_list_pt dependencies);
+static celix_status_t component_getDependencyEvent(dm_component_pt component, dm_service_dependency_pt dependency, dm_event_pt *event_pptr);
+static celix_status_t component_updateInstance(dm_component_pt component, dm_service_dependency_pt dependency, dm_event_pt event, bool update, bool add);
+
+static celix_status_t component_addTask(dm_component_pt component, array_list_pt dependencies);
+static celix_status_t component_startTask(dm_component_pt component, void * data __attribute__((unused)));
+static celix_status_t component_stopTask(dm_component_pt component, void * data __attribute__((unused)));
+static celix_status_t component_removeTask(dm_component_pt component, dm_service_dependency_pt dependency);
+static celix_status_t component_handleEventTask(dm_component_pt component, dm_handle_event_type_pt data);
+
+static celix_status_t component_handleAdded(dm_component_pt component, dm_service_dependency_pt dependency, dm_event_pt event);
+static celix_status_t component_handleChanged(dm_component_pt component, dm_service_dependency_pt dependency, dm_event_pt event);
+static celix_status_t component_handleRemoved(dm_component_pt component, dm_service_dependency_pt dependency, dm_event_pt event);
+static celix_status_t component_handleSwapped(dm_component_pt component, dm_service_dependency_pt dependency, dm_event_pt event, dm_event_pt newEvent);
+
+celix_status_t component_create(bundle_context_pt context, dm_dependency_manager_pt manager, dm_component_pt *component) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    *component = malloc(sizeof(**component));
+    if (!*component) {
+        status = CELIX_ENOMEM;
+    } else {
+        (*component)->context = context;
+        (*component)->manager = manager;
+
+	arrayList_create(&((*component)->dm_interface));
+
+        (*component)->implementation = NULL;
+
+        (*component)->callbackInit = NULL;
+        (*component)->callbackStart = NULL;
+        (*component)->callbackStop = NULL;
+        (*component)->callbackDestroy = NULL;
+
+
+        arrayList_create(&(*component)->dependencies);
+        pthread_mutex_init(&(*component)->mutex, NULL);
+
+        (*component)->state = DM_CMP_STATE_INACTIVE;
+        (*component)->isStarted = false;
+        (*component)->active = false;
+
+        (*component)->dependencyEvents = hashMap_create(NULL, NULL, NULL, NULL);
+
+        (*component)->executor = NULL;
+        executor_create(*component, &(*component)->executor);
+    }
+
+    return status;
+}
+
+celix_status_t component_destroy(dm_component_pt *component_ptr) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	if (!*component_ptr) {
+		status = CELIX_ILLEGAL_ARGUMENT;
+	}
+
+	if (status == CELIX_SUCCESS) {
+		unsigned int i;
+
+		for (i = 0; i < arrayList_size((*component_ptr)->dm_interface); i++) {
+		    dm_interface *interface = arrayList_get((*component_ptr)->dm_interface, i);
+
+		    free (interface->serviceName);
+		}
+		arrayList_destroy((*component_ptr)->dm_interface);
+
+		// #TODO destroy dependencies?
+		executor_destroy(&(*component_ptr)->executor);
+		hashMap_destroy((*component_ptr)->dependencyEvents, false, false);
+		pthread_mutex_destroy(&(*component_ptr)->mutex);
+		arrayList_destroy((*component_ptr)->dependencies);
+
+		free(*component_ptr);
+		*component_ptr = NULL;
+	}
+
+	return status;
+}
+
+celix_status_t component_addServiceDependency(dm_component_pt component, ...) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    array_list_pt dependenciesList = NULL;
+    arrayList_create(&dependenciesList);
+
+    va_list dependencies;
+    va_start(dependencies, component);
+    dm_service_dependency_pt dependency = va_arg(dependencies, dm_service_dependency_pt);
+    while (dependency != NULL) {
+        arrayList_add(dependenciesList, dependency);
+
+
+        dependency = va_arg(dependencies, dm_service_dependency_pt);
+    }
+
+    va_end(dependencies);
+
+	executor_executeTask(component->executor, component, component_addTask, dependenciesList);
+//    component_addTask(component, dependenciesList);
+
+    return status;
+}
+
+
+celix_status_t component_addTask(dm_component_pt component, array_list_pt dependencies) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    array_list_pt bounds = NULL;
+    arrayList_create(&bounds);
+    for (unsigned int i = 0; i < arrayList_size(dependencies); i++) {
+        dm_service_dependency_pt dependency = arrayList_get(dependencies, i);
+
+        pthread_mutex_lock(&component->mutex);
+        array_list_pt events = NULL;
+        arrayList_createWithEquals(event_equals, &events);
+        hashMap_put(component->dependencyEvents, dependency, events);
+
+        arrayList_add(component->dependencies, dependency);
+        pthread_mutex_unlock(&component->mutex);
+
+        serviceDependency_setComponent(dependency, component);
+        if (component->state != DM_CMP_STATE_INACTIVE) {
+            serviceDependency_setInstanceBound(dependency, true);
+            arrayList_add(bounds, dependency);
+        }
+        component_startDependencies(component, bounds);
+        component_handleChange(component);
+    }
+
+    arrayList_destroy(bounds);
+    arrayList_destroy(dependencies);
+
+    return status;
+}
+
+celix_status_t component_removeServiceDependency(dm_component_pt component, dm_service_dependency_pt dependency) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    executor_executeTask(component->executor, component, component_removeTask, dependency);
+//    component_removeTask(component, dependency);
+
+    return status;
+}
+
+celix_status_t component_removeTask(dm_component_pt component, dm_service_dependency_pt 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);
+    for (unsigned int i = arrayList_size(events); i > 0; i--) {
+    	dm_event_pt event = arrayList_remove(events, i - 1);
+    	event_destroy(&event);
+    }
+    arrayList_destroy(events);
+    pthread_mutex_unlock(&component->mutex);
+
+    component_handleChange(component);
+
+    return status;
+}
+
+celix_status_t component_start(dm_component_pt component) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    component->active = true;
+    executor_executeTask(component->executor, component, component_startTask, NULL);
+//    component_startTask(component, NULL);
+
+    return status;
+}
+
+celix_status_t component_startTask(dm_component_pt component, void  *data __attribute__((unused))) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    component->isStarted = true;
+    component_handleChange(component);
+
+    return status;
+}
+
+celix_status_t component_stop(dm_component_pt component) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    component->active = false;
+    executor_executeTask(component->executor, component, component_stopTask, NULL);
+//    component_stopTask(component, NULL);
+
+    return status;
+}
+
+celix_status_t component_stopTask(dm_component_pt 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_addInterface(dm_component_pt component, char *serviceName, void *service, properties_pt properties) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    if (component->active) {
+        return CELIX_ILLEGAL_STATE;
+    } else {
+	dm_interface *interface = (dm_interface *) malloc (sizeof (dm_interface));
+	char *name = strdup (serviceName);
+
+	if (interface && name) {
+            interface->serviceName = name;
+            interface->service = service;
+            interface->properties = properties;
+            interface->registration = NULL;
+	    arrayList_add(component->dm_interface, interface);
+	}
+	else {
+	   free (interface);
+	   free (name);
+	   status = CELIX_ENOMEM;
+	}
+    }
+
+    return status;
+}
+
+celix_status_t component_handleEvent(dm_component_pt component, dm_service_dependency_pt 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;
+}
+
+celix_status_t component_handleEventTask(dm_component_pt 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 component_handleAdded(dm_component_pt component, dm_service_dependency_pt 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);
+
+    switch (component->state) {
+        case DM_CMP_STATE_WAITING_FOR_REQUIRED: {
+            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);
+            if (!instanceBound) {
+                bool required = false;
+                serviceDependency_isRequired(dependency, &required);
+                if (required) {
+                    serviceDependency_invokeAdd(dependency, event);
+                }
+                dm_event_pt event = NULL;
+                component_getDependencyEvent(component, dependency, &event);
+                component_updateInstance(component, dependency, event, false, true);
+            } else {
+                bool required = false;
+                serviceDependency_isRequired(dependency, &required);
+                if (required) {
+                    component_handleChange(component);
+                }
+            }
+            break;
+        }
+        case DM_CMP_STATE_TRACKING_OPTIONAL:
+            serviceDependency_invokeAdd(dependency, event);
+            dm_event_pt event = NULL;
+            component_getDependencyEvent(component, dependency, &event);
+            component_updateInstance(component, dependency, event, false, true);
+            break;
+        default:
+            break;
+    }
+
+    return status;
+}
+
+celix_status_t component_handleChanged(dm_component_pt component, dm_service_dependency_pt 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) {
+        status = CELIX_BUNDLE_EXCEPTION;
+    } else {
+        dm_event_pt old = arrayList_remove(events, (unsigned int) index);
+        arrayList_add(events, event);
+        pthread_mutex_unlock(&component->mutex);
+
+        switch (component->state) {
+            case DM_CMP_STATE_TRACKING_OPTIONAL:
+                serviceDependency_invokeChange(dependency, event);
+                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;
+}
+
+celix_status_t component_handleRemoved(dm_component_pt component, dm_service_dependency_pt 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);
+    component_handleChange(component);
+
+    pthread_mutex_lock(&component->mutex);
+    int index = arrayList_indexOf(events, event);
+    if (index < 0) {
+        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: {
+                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;
+            }
+            case DM_CMP_STATE_TRACKING_OPTIONAL:
+                serviceDependency_invokeRemove(dependency, event);
+                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);
+        }
+    }
+
+    return status;
+}
+
+celix_status_t component_handleSwapped(dm_component_pt component, dm_service_dependency_pt 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) {
+        status = CELIX_BUNDLE_EXCEPTION;
+    } else {
+        dm_event_pt old = arrayList_remove(events, (unsigned int) index);
+        arrayList_add(events, newEvent);
+        pthread_mutex_unlock(&component->mutex);
+
+        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;
+            }
+            case DM_CMP_STATE_TRACKING_OPTIONAL:
+                serviceDependency_invokeSwap(dependency, event, newEvent);
+                break;
+            default:
+                break;
+        }
+
+        event_destroy(&event);
+        if (old) {
+            event_destroy(&old);
+        }
+    }
+
+    return status;
+}
+
+celix_status_t component_updateInstance(dm_component_pt component, dm_service_dependency_pt dependency, dm_event_pt event, bool update, bool add) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    bool autoConfig = false;
+
+    serviceDependency_isAutoConfig(dependency, &autoConfig);
+
+    if (autoConfig) {
+        void *service = NULL;
+        void **field = NULL;
+
+        if (event != NULL) {
+            event_getService(event, &service);
+        }
+        serviceDependency_getAutoConfig(dependency, &field);
+        serviceDependency_lock(dependency);
+        *field = service;
+        serviceDependency_unlock(dependency);
+    }
+
+    return status;
+}
+
+celix_status_t component_startDependencies(dm_component_pt 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++) {
+        dm_service_dependency_pt dependency = arrayList_get(dependencies, i);
+        bool required = false;
+        serviceDependency_isRequired(dependency, &required);
+        if (required) {
+            arrayList_add(required_dependencies, dependency);
+            continue;
+        }
+
+        serviceDependency_start(dependency);
+    }
+
+    for (unsigned int i = 0; i < arrayList_size(required_dependencies); i++) {
+        dm_service_dependency_pt dependency = arrayList_get(required_dependencies, i);
+        serviceDependency_start(dependency);
+    }
+
+    arrayList_destroy(required_dependencies);
+
+    return status;
+}
+
+celix_status_t component_stopDependencies(dm_component_pt component) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    pthread_mutex_lock(&component->mutex);
+    for (unsigned int i = 0; i < arrayList_size(component->dependencies); i++) {
+        dm_service_dependency_pt dependency = arrayList_get(component->dependencies, i);
+        pthread_mutex_unlock(&component->mutex);
+        serviceDependency_stop(dependency);
+        pthread_mutex_lock(&component->mutex);
+    }
+    pthread_mutex_unlock(&component->mutex);
+
+    return status;
+}
+
+celix_status_t component_handleChange(dm_component_pt component) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    dm_component_state_pt oldState;
+    dm_component_state_pt newState;
+
+    bool cont = false;
+    do {
+        oldState = component->state;
+        component_calculateNewState(component, oldState, &newState);
+        component->state = newState;
+        component_performTransition(component, oldState, newState, &cont);
+    } while (cont);
+
+    return status;
+}
+
+celix_status_t component_calculateNewState(dm_component_pt component, dm_component_state_pt currentState, dm_component_state_pt *newState) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    if (currentState == DM_CMP_STATE_INACTIVE) {
+        if (component->isStarted) {
+            *newState = DM_CMP_STATE_WAITING_FOR_REQUIRED;
+            return status;
+        }
+    }
+    if (currentState == DM_CMP_STATE_WAITING_FOR_REQUIRED) {
+        if (!component->isStarted) {
+            *newState = DM_CMP_STATE_INACTIVE;
+            return status;
+        }
+
+        bool available = false;
+        component_allRequiredAvailable(component, &available);
+
+        if (available) {
+            *newState = DM_CMP_STATE_INSTANTIATED_AND_WAITING_FOR_REQUIRED;
+            return status;
+        }
+    }
+    if (currentState == DM_CMP_STATE_INSTANTIATED_AND_WAITING_FOR_REQUIRED) {
+        bool available = false;
+        component_allRequiredAvailable(component, &available);
+
+        if (component->isStarted && available) {
+            bool instanceBoundAvailable = false;
+            component_allInstanceBoundAvailable(component, &instanceBoundAvailable);
+
+            if (instanceBoundAvailable) {
+                *newState = DM_CMP_STATE_TRACKING_OPTIONAL;
+                return status;
+            }
+
+            *newState = currentState;
+            return status;
+        }
+        *newState = DM_CMP_STATE_WAITING_FOR_REQUIRED;
+        return status;
+    }
+    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) {
+            *newState = currentState;
+            return status;
+        }
+
+        *newState = DM_CMP_STATE_INSTANTIATED_AND_WAITING_FOR_REQUIRED;
+        return status;
+    }
+
+    *newState = currentState;
+
+    return status;
+}
+
+celix_status_t component_performTransition(dm_component_pt component, dm_component_state_pt oldState, dm_component_state_pt newState, bool *transition) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    if (oldState == DM_CMP_STATE_INACTIVE && newState == DM_CMP_STATE_WAITING_FOR_REQUIRED) {
+        component_startDependencies(component, component->dependencies);
+//        #TODO Add listener support
+//        notifyListeners(newState);
+        *transition = true;
+        return status;
+    }
+
+    if (oldState == DM_CMP_STATE_WAITING_FOR_REQUIRED && newState == DM_CMP_STATE_INSTANTIATED_AND_WAITING_FOR_REQUIRED) {
+        // #TODO Remove
+//        component_instantiateComponent(component);
+        component_invokeAddRequiredDependencies(component);
+        component_invokeAutoConfigDependencies(component);
+        dm_component_state_pt stateBeforeCallingInit = component->state;
+        if (component->callbackInit) {
+        	component->callbackInit(component->implementation);
+        }
+        if (stateBeforeCallingInit == component->state) {
+//            #TODO Add listener support
+//            notifyListeners(newState); // init did not change current state, we can notify about this new state
+        }
+        *transition = true;
+        return status;
+    }
+
+    if (oldState == DM_CMP_STATE_INSTANTIATED_AND_WAITING_FOR_REQUIRED && newState == DM_CMP_STATE_TRACKING_OPTIONAL) {
+        component_invokeAddRequiredInstanceBoundDependencies(component);
+        component_invokeAutoConfigInstanceBoundDependencies(component);
+        if (component->callbackStart) {
+        	component->callbackStart(component->implementation);
+        }
+        component_invokeAddOptionalDependencies(component);
+        component_registerService(component);
+//            #TODO Add listener support
+//        notifyListeners(newState);
+        return true;
+    }
+
+    if (oldState == DM_CMP_STATE_TRACKING_OPTIONAL && newState == DM_CMP_STATE_INSTANTIATED_AND_WAITING_FOR_REQUIRED) {
+        component_unregisterService(component);
+        component_invokeRemoveOptionalDependencies(component);
+        if (component->callbackStop) {
+        	component->callbackStop(component->implementation);
+        }
+        component_invokeRemoveInstanceBoundDependencies(component);
+//            #TODO Add listener support
+//        notifyListeners(newState);
+        *transition = true;
+        return status;
+    }
+
+    if (oldState == DM_CMP_STATE_INSTANTIATED_AND_WAITING_FOR_REQUIRED && newState == DM_CMP_STATE_WAITING_FOR_REQUIRED) {
+    	if (component->callbackDestroy) {
+    		component->callbackDestroy(component->implementation);
+    	}
+        component_invokeRemoveRequiredDependencies(component);
+//            #TODO Add listener support
+//        notifyListeners(newState);
+//        bool needInstance = false;
+//        component_someDependenciesNeedInstance(component, &needInstance);
+//        if (!needInstance) {
+            component_destroyComponent(component);
+//        }
+        *transition = true;
+        return status;
+    }
+
+    if (oldState == DM_CMP_STATE_WAITING_FOR_REQUIRED && newState == DM_CMP_STATE_INACTIVE) {
+        component_stopDependencies(component);
+        component_destroyComponent(component);
+//            #TODO Add listener support
+//        notifyListeners(newState);
+        *transition = true;
+        return status;
+    }
+
+    *transition = false;
+    return status;
+}
+
+celix_status_t component_allRequiredAvailable(dm_component_pt 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++) {
+        dm_service_dependency_pt 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;
+}
+
+celix_status_t component_allInstanceBoundAvailable(dm_component_pt 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++) {
+        dm_service_dependency_pt 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;
+}
+
+celix_status_t component_invokeAddRequiredDependencies(dm_component_pt component) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    pthread_mutex_lock(&component->mutex);
+    for (unsigned int i = 0; i < arrayList_size(component->dependencies); i++) {
+        dm_service_dependency_pt 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;
+}
+
+celix_status_t component_invokeAutoConfigDependencies(dm_component_pt component) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    pthread_mutex_lock(&component->mutex);
+    for (unsigned int i = 0; i < arrayList_size(component->dependencies); i++) {
+        dm_service_dependency_pt 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;
+}
+
+celix_status_t component_invokeAutoConfigInstanceBoundDependencies(dm_component_pt component) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    pthread_mutex_lock(&component->mutex);
+    for (unsigned int i = 0; i < arrayList_size(component->dependencies); i++) {
+        dm_service_dependency_pt 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;
+}
+
+celix_status_t component_invokeAddRequiredInstanceBoundDependencies(dm_component_pt component) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    pthread_mutex_lock(&component->mutex);
+    for (unsigned int i = 0; i < arrayList_size(component->dependencies); i++) {
+        dm_service_dependency_pt 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;
+}
+
+celix_status_t component_invokeAddOptionalDependencies(dm_component_pt component) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    pthread_mutex_lock(&component->mutex);
+    for (unsigned int i = 0; i < arrayList_size(component->dependencies); i++) {
+        dm_service_dependency_pt 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;
+}
+
+celix_status_t component_invokeRemoveOptionalDependencies(dm_component_pt component) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    pthread_mutex_lock(&component->mutex);
+    for (unsigned int i = 0; i < arrayList_size(component->dependencies); i++) {
+        dm_service_dependency_pt 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;
+}
+
+celix_status_t component_invokeRemoveInstanceBoundDependencies(dm_component_pt component) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    pthread_mutex_lock(&component->mutex);
+    for (unsigned int i = 0; i < arrayList_size(component->dependencies); i++) {
+        dm_service_dependency_pt 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;
+}
+
+celix_status_t component_invokeRemoveRequiredDependencies(dm_component_pt component) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    pthread_mutex_lock(&component->mutex);
+    for (unsigned int i = 0; i < arrayList_size(component->dependencies); i++) {
+        dm_service_dependency_pt 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;
+}
+
+celix_status_t component_getDependencyEvent(dm_component_pt component, dm_service_dependency_pt 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;
+}
+
+celix_status_t component_configureImplementation(dm_component_pt component, dm_service_dependency_pt dependency) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    void **field = NULL;
+
+    array_list_pt events = hashMap_get(component->dependencyEvents, dependency);
+    if (events) {
+        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);
+        }
+    }
+
+    return status;
+}
+
+celix_status_t component_destroyComponent(dm_component_pt component) {
+    celix_status_t status = CELIX_SUCCESS;
+
+//    component->implementation = NULL;
+
+    return status;
+}
+
+celix_status_t component_registerService(dm_component_pt component) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    if (component->context) {
+	unsigned int i;
+
+	for (i = 0; i < arrayList_size(component->dm_interface); i++) {
+	    dm_interface *interface = arrayList_get(component->dm_interface, i);
+
+            bundleContext_registerService(component->context, interface->serviceName, interface->service, interface->properties, &interface->registration);
+	}
+    }
+
+    return status;
+}
+
+celix_status_t component_unregisterService(dm_component_pt component) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    unsigned int i;
+
+    for (i = 0; i < arrayList_size(component->dm_interface); i++) {
+	dm_interface *interface = arrayList_get(component->dm_interface, i);
+
+	serviceRegistration_unregister(interface->registration);
+	interface->registration = NULL;
+    }
+
+    return status;
+}
+
+celix_status_t component_setCallbacks(dm_component_pt component, init_fpt init, start_fpt start, stop_fpt stop, destroy_fpt destroy) {
+	if (component->active) {
+		return CELIX_ILLEGAL_STATE;
+	}
+	component->callbackInit = init;
+	component->callbackStart = start;
+	component->callbackStop = stop;
+	component->callbackDestroy = destroy;
+	return CELIX_SUCCESS;
+}
+
+celix_status_t component_isAvailable(dm_component_pt component, bool *available) {
+    *available = component->state == DM_CMP_STATE_TRACKING_OPTIONAL;
+    return CELIX_SUCCESS;
+}
+
+celix_status_t component_setImplementation(dm_component_pt component, void *implementation) {
+    component->implementation = implementation;
+    return CELIX_SUCCESS;
+}
+
+celix_status_t component_getBundleContext(dm_component_pt component, bundle_context_pt *context) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	if (!component) {
+		status = CELIX_ILLEGAL_ARGUMENT;
+	}
+
+	if (status == CELIX_SUCCESS) {
+		*context = component->context;
+	}
+
+	return status;
+}
+
+
+celix_status_t executor_create(dm_component_pt component __attribute__((unused)), dm_executor_pt *executor) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    *executor = malloc(sizeof(**executor));
+    if (!*executor) {
+        status = CELIX_ENOMEM;
+    } else {
+        linkedList_create(&(*executor)->workQueue);
+        pthread_mutex_init(&(*executor)->mutex, NULL);
+        (*executor)->runningThreadSet = false;
+    }
+
+    return status;
+}
+
+celix_status_t executor_destroy(dm_executor_pt *executor) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	if (!*executor) {
+		status = CELIX_ILLEGAL_ARGUMENT;
+	}
+
+	if (status == CELIX_SUCCESS) {
+		pthread_mutex_destroy(&(*executor)->mutex);
+		linkedList_destroy((*executor)->workQueue);
+
+		free(*executor);
+		*executor = NULL;
+	}
+
+	return status;
+}
+
+celix_status_t executor_schedule(dm_executor_pt executor, dm_component_pt component, void (*command), void *data) {
+    celix_status_t status = CELIX_SUCCESS;
+
+    struct dm_executor_task *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);
+        linkedList_addLast(executor->workQueue, task);
+        pthread_mutex_unlock(&executor->mutex);
+    }
+
+    return status;
+}
+
+celix_status_t executor_executeTask(dm_executor_pt executor, dm_component_pt 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;
+}
+
+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;
+}
+
+celix_status_t executor_runTasks(dm_executor_pt executor, pthread_t currentThread __attribute__((unused))) {
+    celix_status_t status = CELIX_SUCCESS;
+//    bool execute = false;
+
+    do {
+        struct dm_executor_task *entry = NULL;
+        pthread_mutex_lock(&executor->mutex);
+        while ((entry = linkedList_removeFirst(executor->workQueue)) != NULL) {
+            pthread_mutex_unlock(&executor->mutex);
+
+            entry->command(entry->component, entry->data);
+
+            pthread_mutex_lock(&executor->mutex);
+
+            free(entry);
+        }
+        executor->runningThreadSet = false;
+        pthread_mutex_unlock(&executor->mutex);
+
+//        pthread_mutex_lock(&executor->mutex);
+//        if (executor->runningThread == NULL) {
+//            executor->runningThread = currentThread;
+//            execute = true;
+//        }
+//        pthread_mutex_unlock(&executor->mutex);
+    } while (!linkedList_isEmpty(executor->workQueue)); // && execute
+
+    return status;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/cc6fd432/dependency_manager/private/src/dm_dependency_manager_impl.c
----------------------------------------------------------------------
diff --git a/dependency_manager/private/src/dm_dependency_manager_impl.c b/dependency_manager/private/src/dm_dependency_manager_impl.c
new file mode 100644
index 0000000..28b49e9
--- /dev/null
+++ b/dependency_manager/private/src/dm_dependency_manager_impl.c
@@ -0,0 +1,91 @@
+/**
+ * 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_dependency_manager_impl.c
+ *
+ *  \date       26 Jul 2014
+ *  \author     <a href="mailto:dev@celix.apache.org">Apache Celix Project Team</a>
+ *  \copyright  Apache License, Version 2.0
+ */
+
+
+#include <pthread.h>
+#include <stdlib.h>
+
+#include "bundle_context.h"
+#include "dm_component_impl.h"
+
+struct dm_dependency_manager {
+	array_list_pt components;
+
+	pthread_mutex_t mutex;
+};
+
+celix_status_t dependencyManager_create(bundle_context_pt context __attribute__((unused)), dm_dependency_manager_pt *manager) {
+	celix_status_t status = CELIX_ENOMEM;
+
+	(*manager) = calloc(1, sizeof(**manager));
+
+	if (*manager) {
+		arrayList_create(&(*manager)->components);
+
+		status = CELIX_SUCCESS;
+	}
+
+	return status;
+
+}
+
+celix_status_t dependencyManager_destroy(dm_dependency_manager_pt *manager) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	arrayList_destroy((*manager)->components);
+
+	free(*manager);
+	(*manager) = NULL;
+
+	return status;
+}
+
+celix_status_t dependencyManager_add(dm_dependency_manager_pt manager, dm_component_pt component) {
+	celix_status_t status;
+
+	arrayList_add(manager->components, component);
+	status = component_start(component);
+
+	return status;
+}
+
+celix_status_t dependencyManager_remove(dm_dependency_manager_pt manager, dm_component_pt component) {
+	celix_status_t status;
+
+	arrayList_removeElement(manager->components, component);
+	status = component_stop(component);
+
+	return status;
+}
+
+celix_status_t dependencyManager_getComponents(dm_dependency_manager_pt manager, array_list_pt* components) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	(*components) = manager->components;
+
+	return status;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/cc6fd432/dependency_manager/private/src/dm_event.c
----------------------------------------------------------------------
diff --git a/dependency_manager/private/src/dm_event.c b/dependency_manager/private/src/dm_event.c
new file mode 100644
index 0000000..60b7892
--- /dev/null
+++ b/dependency_manager/private/src/dm_event.c
@@ -0,0 +1,92 @@
+/**
+ * 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 "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, void *service, dm_event_pt *event) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	*event = calloc(1, sizeof(**event));
+	if (!*event) {
+		status = CELIX_ENOMEM;
+	}
+
+	if (status == CELIX_SUCCESS) {
+		(*event)->bundle = bundle;
+		(*event)->event_type = event_type;
+		(*event)->context = context;
+		(*event)->reference = reference;
+		(*event)->service = service;
+	}
+
+	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(void *a, void *b, bool *equals) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	if (!a || !b) {
+		*equals = false;
+	} else {
+		dm_event_pt a_ptr = a;
+		dm_event_pt b_ptr = b;
+
+		status = serviceReference_equals(a_ptr->reference, b_ptr->reference, equals);
+	}
+
+	return status;
+}
+
+celix_status_t event_compareTo(dm_event_pt event, dm_event_pt compareTo, int *compare) {
+	celix_status_t status;
+
+	status = serviceReference_compareTo(event->reference, compareTo->reference, compare);
+
+	return status;
+}
+
+celix_status_t event_getService(dm_event_pt event, void **service) {
+	*service = event->service;
+	return CELIX_SUCCESS;
+}

http://git-wip-us.apache.org/repos/asf/celix/blob/cc6fd432/dependency_manager/private/src/dm_service_dependency.c
----------------------------------------------------------------------
diff --git a/dependency_manager/private/src/dm_service_dependency.c b/dependency_manager/private/src/dm_service_dependency.c
new file mode 100644
index 0000000..8f65ddb
--- /dev/null
+++ b/dependency_manager/private/src/dm_service_dependency.c
@@ -0,0 +1,564 @@
+/**
+ *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_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 "constants.h"
+
+#include "dm_service_dependency_impl.h"
+#include "dm_component_impl.h"
+
+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);
+
+celix_status_t serviceDependency_create(dm_service_dependency_pt *dependency_ptr) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	*dependency_ptr = calloc(1, sizeof(**dependency_ptr));
+	if (!*dependency_ptr) {
+		status = CELIX_ENOMEM;
+	} else {
+		(*dependency_ptr)->component = NULL;
+		(*dependency_ptr)->available = false;
+		(*dependency_ptr)->instanceBound = false;
+		(*dependency_ptr)->required = false;
+
+		(*dependency_ptr)->add = NULL;
+		(*dependency_ptr)->change = NULL;
+		(*dependency_ptr)->remove = NULL;
+		(*dependency_ptr)->swap = NULL;
+
+		(*dependency_ptr)->add_with_ref = NULL;
+		(*dependency_ptr)->change_with_ref = NULL;
+		(*dependency_ptr)->remove_with_ref = NULL;
+		(*dependency_ptr)->swap_with_ref = NULL;
+
+		(*dependency_ptr)->autoConfigure = NULL;
+
+		(*dependency_ptr)->isStarted = false;
+
+		(*dependency_ptr)->tracked_service_name = NULL;
+		(*dependency_ptr)->tracked_filter_unmodified = NULL;
+		(*dependency_ptr)->tracked_filter = NULL;
+
+		(*dependency_ptr)->tracker = NULL;
+		(*dependency_ptr)->tracker_customizer = NULL;
+	}
+
+	return status;
+}
+
+celix_status_t serviceDependency_destroy(dm_service_dependency_pt *dependency_ptr) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	if (!*dependency_ptr) {
+		status = CELIX_ENOMEM;
+	}
+
+	if (status == CELIX_SUCCESS) {
+		free((*dependency_ptr)->tracked_service_name);
+		free((*dependency_ptr)->tracked_filter);
+		free((*dependency_ptr)->tracked_filter_unmodified);
+		free(*dependency_ptr);
+		*dependency_ptr = NULL;
+	}
+
+	return status;
+}
+
+celix_status_t serviceDependency_lock(dm_service_dependency_pt dependency) {
+	celixThreadMutex_lock(&dependency->lock);
+	return CELIX_SUCCESS;
+}
+
+celix_status_t serviceDependency_unlock(dm_service_dependency_pt dependency) {
+	celixThreadMutex_unlock(&dependency->lock);
+	return CELIX_SUCCESS;
+}
+
+celix_status_t serviceDependency_setRequired(dm_service_dependency_pt dependency, bool required) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	if (!dependency) {
+		status = CELIX_ILLEGAL_ARGUMENT;
+	}
+
+	if (status == CELIX_SUCCESS) {
+		dependency->required = required;
+	}
+
+	return status;
+}
+
+celix_status_t serviceDependency_setService(dm_service_dependency_pt dependency, char *serviceName, char *filter) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	if (!dependency) {
+		status = CELIX_ILLEGAL_ARGUMENT;
+	}
+
+	if (status == CELIX_SUCCESS) {
+		if (serviceName != NULL) {
+			dependency->tracked_service_name = strdup(serviceName);
+		}
+		if (filter != NULL) {
+			dependency->tracked_filter_unmodified = strdup(filter);
+			if (serviceName == NULL) {
+				dependency->tracked_filter = strdup(filter);
+			} else {
+				size_t len = strlen(serviceName) + strlen(OSGI_FRAMEWORK_OBJECTCLASS) + strlen(filter) + 7;
+				char new_filter[len];
+				snprintf(new_filter, len, "(&(%s=%s)%s)", OSGI_FRAMEWORK_OBJECTCLASS, serviceName, filter);
+				dependency->tracked_filter = strdup(new_filter);
+			}
+		} else {
+			dependency->tracked_filter_unmodified = NULL;
+			dependency->tracked_filter = NULL;
+		}
+	}
+
+	return status;
+}
+
+celix_status_t serviceDependency_setCallbacks(dm_service_dependency_pt dependency, service_add_fpt add, service_change_fpt change, service_remove_fpt remove, service_swap_fpt swap) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	if (!dependency) {
+		status = CELIX_ILLEGAL_ARGUMENT;
+	}
+
+	if (status == CELIX_SUCCESS) {
+		dependency->add = add;
+		dependency->change = change;
+		dependency->remove = remove;
+		dependency->swap = swap;
+	}
+
+	return status;
+}
+
+celix_status_t serviceDependency_setCallbacksWithServiceReference(dm_service_dependency_pt dependency, 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->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_setAutoConfigure(dm_service_dependency_pt dependency, celix_thread_mutex_t *service_lock, 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(dm_service_dependency_pt dependency, dm_component_pt 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(dm_service_dependency_pt dependency) {
+	celix_status_t status = CELIX_SUCCESS;
+	bundle_context_pt context = NULL;
+
+	if (!dependency || !dependency->component || (!dependency->tracked_service_name && !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_name) {
+			status = serviceTracker_create(context, dependency->tracked_service_name, 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(dm_service_dependency_pt dependency) {
+	celix_status_t status = CELIX_SUCCESS;
+    celix_status_t tmp_status;
+
+	if (!dependency) {
+		status = CELIX_ILLEGAL_ARGUMENT;
+	}
+
+	if (status == CELIX_SUCCESS) {
+		if (dependency->tracker) {
+            tmp_status = serviceTracker_close(dependency->tracker);
+            if (tmp_status != CELIX_SUCCESS) {
+                status = tmp_status;
+            }
+			tmp_status = serviceTracker_destroy(dependency->tracker);
+            if (tmp_status != CELIX_SUCCESS && status == CELIX_SUCCESS) {
+                status = tmp_status;
+            }
+		}
+	}
+
+	if (status == CELIX_SUCCESS) {
+		dependency->isStarted = false;
+	}
+
+	return status;
+}
+
+celix_status_t serviceDependency_setInstanceBound(dm_service_dependency_pt 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 serviceDependency_setAvailable(dm_service_dependency_pt dependency, bool available) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	if (!dependency) {
+		status = CELIX_ILLEGAL_ARGUMENT;
+	}
+
+	if (status == CELIX_SUCCESS) {
+		dependency->available = available;
+	}
+
+	return status;
+}
+
+celix_status_t serviceDependency_invokeAdd(dm_service_dependency_pt 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(dependency->component->implementation, event->service);
+		}
+		if (dependency->add_with_ref) {
+			dependency->add_with_ref(dependency->component->implementation, event->reference, event->service);
+		}
+	}
+
+	return status;
+}
+
+celix_status_t serviceDependency_invokeChange(dm_service_dependency_pt 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(dependency->component->implementation, event->service);
+		}
+		if (dependency->change_with_ref) {
+			dependency->change_with_ref(dependency->component->implementation, event->reference, event->service);
+		}
+	}
+
+	return status;
+}
+
+celix_status_t serviceDependency_invokeRemove(dm_service_dependency_pt dependency, dm_event_pt event) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	if (!dependency) {
+		status = CELIX_ILLEGAL_ARGUMENT;
+	}
+
+	if (status == CELIX_SUCCESS) {
+		if (dependency->remove) {
+			dependency->remove(dependency->component->implementation, event->service);
+		}
+		if (dependency->remove_with_ref) {
+			dependency->remove_with_ref(dependency->component->implementation, event->reference, event->service);
+		}
+	}
+
+	return status;
+}
+
+celix_status_t serviceDependency_invokeSwap(dm_service_dependency_pt 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(dependency->component->implementation, event->service, newEvent->service);
+		}
+		if (dependency->swap_with_ref) {
+			dependency->swap_with_ref(dependency->component->implementation, event->reference, event->service, newEvent->reference, newEvent->service);
+		}
+	}
+
+	return status;
+}
+
+celix_status_t serviceDependency_isAvailable(dm_service_dependency_pt dependency, bool *available) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	if (!dependency) {
+		status = CELIX_ILLEGAL_ARGUMENT;
+	}
+
+	if (status == CELIX_SUCCESS) {
+		*available = dependency->available;
+	}
+
+	return status;
+}
+
+celix_status_t serviceDependency_isRequired(dm_service_dependency_pt 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 serviceDependency_isInstanceBound(dm_service_dependency_pt dependency, bool *instanceBound) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	if (!dependency) {
+		status = CELIX_ILLEGAL_ARGUMENT;
+	}
+
+	if (status == CELIX_SUCCESS) {
+		*instanceBound = dependency->instanceBound;
+	}
+
+	return status;
+}
+
+celix_status_t serviceDependency_isAutoConfig(dm_service_dependency_pt 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;
+}
+
+celix_status_t serviceDependency_getAutoConfig(dm_service_dependency_pt dependency, void ***autoConfigure) {
+	celix_status_t status = CELIX_SUCCESS;
+
+	if (!dependency) {
+		status = CELIX_ILLEGAL_ARGUMENT;
+	}
+
+	if (status == CELIX_SUCCESS) {
+		*autoConfigure = dependency->autoConfigure;
+	}
+
+	return status;
+}
+
+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;
+	dm_service_dependency_pt 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) {
+		component_handleEvent(dependency->component, dependency, event);
+	}
+
+	return status;
+}
+
+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;
+	dm_service_dependency_pt 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) {
+		component_handleEvent(dependency->component, dependency, event);
+	}
+
+	return status;
+}
+
+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;
+	dm_service_dependency_pt 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) {
+		component_handleEvent(dependency->component, dependency, event);
+	}
+
+	return status;
+}


Mime
View raw message