You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@celix.apache.org by pn...@apache.org on 2018/07/02 18:34:44 UTC

[1/4] celix git commit: CELIX-449: Restructure of some parts of the documentation to make it easier to integrate with the celix-site.

Repository: celix
Updated Branches:
  refs/heads/develop 67794980f -> 3f24edf0b


http://git-wip-us.apache.org/repos/asf/celix/blob/3f24edf0/documents/roadmap/roadmap.md
----------------------------------------------------------------------
diff --git a/documents/roadmap/roadmap.md b/documents/roadmap/roadmap.md
deleted file mode 100644
index a3100be..0000000
--- a/documents/roadmap/roadmap.md
+++ /dev/null
@@ -1,123 +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.
--->
-
-# Roadmap
-
-Note this roadmap is still a draft.
-
-# Apache Celix 2.0.1 
-
-Date: TBD (juli/aug 2017?)
-
-## Improve PubSub (CELIX-407)
-
-1. Finalize introduction serializer services  
-1. Ensure code coverage of ~ 70% 
-
-## Finalize Runtime Creation (CELIX-408)
-
-1. Ensure that the runtime command are used for testing some distributed test (e.g. pubsub)
-
-## Add Support for running Celix as a single executable (TODO issue)
-For different reasons it could be interesting to support running bundles from a single executable.
-Primarily security, but also startup performance.
-
-To start this can be achieved by creating static version of the celix provided bundles. These static 
-bundles should have unique symbols, e.g  shell_bundleActivator_create instead of a 
-"normal" bundleActivator_create. The normal  activator functions should then 
-only be used (using a define or separated source file) when building a shared library bundle.
-A additional property (e.g. "cosgi.auto.static.start=shell, shell_tui") can be used to specify which 
-symbol prefixes to use.
-
-Note that if this is implemented it would also be a good moment to add a compile option / launcher option
-to disable dynamic loading of libraries. This way shared library based bundles can be used during 
-development, but for production a static executable with no capability to add bundles runtime 
-could be used if preferable. 
-
-# Apache Celix 2.1.0
-
-Date: TBD (Jan 2018)
-
-Note a short comming is that there is still no good support for export and import libraries between
-bundles. For Linux dlmopen is a solution, but for a more broader UNIX support a more "creative" 
-solution is needed (e.g. Just in time replacing the SONAME and NEEDED values in the respective shared libraries)
-
-## Extend Dependency Manager C/C++ (CELIX-409)
-
-The dependency manager offers declarative API for working with services and is arguable more easier 
-to use than the official OSGi Api. Extend the DM so that in can be used for virtually any bundle 
-without directly using the bundle context, bundle, module, service ref, service registration, etc API.
-This provided a much smaller API providing almost the same functionality.
-
-This means:
-1. Add support for service factory 
-1. Add support for providing listener hooks. Note that this is already supported by registering 
-   a `listener_hook_service` service, but maybe a more abstracted way.
-1. Add support looking up and opening resources in the bundle.
-1. Replace add,remove, etc callbacks which uses the service reference, with callbacks using properties
-1. Test if the dm correctly works when adding / removing provided services and service dependencies after a component is started.
-1. Getting framework properties (e.g. bundleContext_getProperty)
-1. Support for getting basic info from bundle (version, symbolic name, manifest)
-
-## Add framework services (TODO issue)
-Apache Celix is a framework for service oriented programming, this should also include for interacting with the 
-framework itself. Create framework services for:
-
-1. bundle management: installing, Starting, Stopping, deinstalling, listing, etc bundles.
-1. service registry info: nr of service registered, nr of service listeners, etc.
-1. framework listenerL start, stop, error events (whiteboard)
-1. bundle listener: installed, start, stop, deinstalled events (whiteboard)
-
-## Support dependency manager from framework (TODO issue)
-Because the dependency manager is actual the preferred way to write bundles, this should be support
-like "normal" activators" directly from the framework without using a static library.
-
-## Refactor Celix provided bundles to use dependency manager and framework services (TODO issue)
-Refactor Celix bundles (shell, shell_tuu, RSA, etc) to use the dependency manager instead of a "vanilla" 
-bundle activator. The dependency manager should be the preferred way to handle services. 
-Also instead of directly using the API from bundle_context, bundle, module, etc the framework services
-should be used.
-
-## Create dfi descriptor generator (TODO issue)
-Create a descriptor generator which can parse type and service headers. 
-This can be relatively easy  achieved by (e.g.) using the libclang library. 
-Also extend the CMake add_bundle command and create a CMake bundle_add_descriptors command to be able
-to add the descriptors to the bundle
-
-## Use dfi descriptor in service registrations/references (TODO issue)
-When available dfi descriptors can be used in Celix to validate if service are compatible and
-in case of the provided service having more functions than the consumer needs, create a (cast to) 
-a compatible consumer version.
-
-# Apache Celix 3.0.0
-
-Date: TBD (aug 2018)
-
-## Remove support for "vanilla" bundle activators (TODO issue)
-When all Celix provided bundles are using the dependency manager and framework services support for
-the "vanilla"  bundle activator can be dropped. Also a lot internals can be refactored because the public
-API should have shrunk quite a bit; This should lead to smaller code base -> less complex, easier to maintain
-and a smaller footprint.
-
-  
-## Refactor service registry to a single threaded design (TODO issue)
-Celix currently has some nested lock. It would be preferable to remove these, but this is difficult 
-because they are used to sync events which react on registering/unregistering services. Specially when 
-a unregister/register event leads to other services being registered/unregisterd. One way to deal with 
-this sync problem is to remove it by adding a single thread which handle al interaction between bundles 
-and the service registry.
-

http://git-wip-us.apache.org/repos/asf/celix/blob/3f24edf0/documents/subprojects/readme.md
----------------------------------------------------------------------
diff --git a/documents/subprojects/readme.md b/documents/subprojects/readme.md
index 2853912..e9ca378 100644
--- a/documents/subprojects/readme.md
+++ b/documents/subprojects/readme.md
@@ -19,25 +19,18 @@ limitations under the License.
 
 Apache Celix is organized into several subprojects. The following subproject are currently available:
 
-* [Framework](../../libs/framework) - The Apache Celix framework, an implementation of OSGi adapted to C.
-* [C Dependency Manager](../../libs/dependency_manager) - A C component/dependency model for use through an API provided as library.
-* [C++ Dependency Manager](../../libs/dependency_manager_cxx) - A C++ component/dependency model for use through an API provided as library.
-* [Device Access](../../bundles/device_access) - An implementation of the OSGi Device Access specification adapted to C.
-* [Etcd library](../../libs/etcdlib) - A C library that interfaces with ETCD.
-* [Examples](../../examples) - A Selection of examples showing how the framework can be used.
-* [Log Service](../../bundles/log_service) - An implementation of the OSGi Log Service adapated to C.
-* [Log Writer](../../bundles/log_writer) - A simple log writer for use in combination with the Log Service.
-* [Remote Service Admin](../../bundles/remote_services) - An implementation of the OSGi Remote Service Admin Service - for several protocols - adapted to C.
-    * [Remote Service Admin HTTP](../../bundles/remote_services/remote_service_admin_http) - A HTTP implementation of the RSA.
-    * [Remote Service Admin DFI](../../bundles/remote_services/remote_service_admin_dfi) - A Dynamic Function Interface (DFI) implementation of the RSA.
-    * [Remote Service Admin SHM](../../bundles/remote_services/remote_service_admin_shm) - A shared memory implementation of the RSA.
-    * [Topology Manager](../../bundles/remote_services/topology_manager) - A (scoped) RSA Topology Manager implementation.
-    * [Discovery Configured](../../bundles/remote_services/discovery_configured) - A RSA Discovery implementation using static configuration (xml).
-    * [Discovery Etcd](../../bundles/remote_services/dicovery_etcd) - A RSA Discovery implementation using etcd.
-    * [Discovery SHM](../../bundles/remote_services/dicovery_shm) - A RSA Discovery implementation using shared memory.
-* [Shell](../../bundles/shell/shell) - A OSGi shell implementation.
-* [Shell TUI](../../bundles/shell/shell_tui) - A textual UI for the Celix Shell.
-* [Remote Shell](../../bundles/shell/remote_shell) - A remote (telnet) frontend for the Celix shell.
-* [Bonjour Shell](../../bundles/shell/shell_bonjour) - A remote (Bonjour / mDNS) frontend for the Celix shell.
-* [Deployment Admin](../../bundles/deployment_admin) - A deployment admin implementation.
+* [Framework](../libs/framework) - The Apache Celix framework, an implementation of OSGi adapted to C.
+* [C Dependency Manager](../libs/dependency_manager) - A C component/dependency model for use through an API provided as library.
+* [C++ Dependency Manager](../libs/dependency_manager_cxx) - A C++ component/dependency model for use through an API provided as library.
+* [Device Access](../bundles/device_access) - An implementation of the OSGi Device Access specification adapted to C.
+* [Etcd library](../libs/etcdlib) - A C library that interfaces with ETCD.
+* [Examples](../examples) - A Selection of examples showing how the framework can be used.
+* [Log Service](../bundles/log_service) - An implementation of the OSGi Log Service adapated to C.
+* [Log Writer](../bundles/log_writer) - A simple log writer for use in combination with the Log Service.
+* [Remote Service Admin](../bundles/remote_services) - An implementation of the OSGi Remote Service Admin Service - for several protocols - adapted to C.
+* [Shell](../bundles/shell/shell) - A OSGi shell implementation.
+* [Shell TUI](../bundles/shell/shell_tui) - A textual UI for the Celix Shell.
+* [Remote Shell](../bundles/shell/remote_shell) - A remote (telnet) frontend for the Celix shell.
+* [Bonjour Shell](../bundles/shell/shell_bonjour) - A remote (Bonjour / mDNS) frontend for the Celix shell.
+* [Deployment Admin](../bundles/deployment_admin) - A deployment admin implementation.
 

http://git-wip-us.apache.org/repos/asf/celix/blob/3f24edf0/misc/roadmap/improvement_ideas.md
----------------------------------------------------------------------
diff --git a/misc/roadmap/improvement_ideas.md b/misc/roadmap/improvement_ideas.md
new file mode 100644
index 0000000..32db322
--- /dev/null
+++ b/misc/roadmap/improvement_ideas.md
@@ -0,0 +1,54 @@
+<!--
+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.
+-->
+
+# Improvement Ideas
+ 
+# Introduce dlmopen for library imports.
+Currently library are loaded LOCAL for bundles. This works alright, but makes it hard to add a concept 
+of exporting and importing libraries. 
+
+The trick is that the NEEDED header in the importing libraries 
+should match the target exported library SONAME header and no other exported libraries SONAME headers. 
+One solution to make this work is to alter the NEEDED & SONAME runtime. 
+ 
+For glibc there is now an other alternative, namely using dlmopen. dlmopen makes it possible to load 
+libraries in a given namespace. For bundle this can be used to create a library namespace per bundle 
+and load exported libraries int importing bundle namespace. A clean solution, but this currently 
+only works for glibc (linux).
+
+
+# Fix the performance use case and add C++ support
+There was a locking example which also functioned as a performance test to measure the impact of
+using services instead of direct function calls. 
+During the removal of APR this example stopped working. Add it back, fix it and add a C++ use case
+as example.
+See [locking example tree](https://github.com/apache/celix/tree/216032cae956379d4a740f37ae5caee7e957bd98/examples/locking)
+
+# Cleanup Celix project structure
+Celix is growing and getting more sub project, this is fine but maybe the structure needs a cleanup to 
+create a more clear root directory structure. 
+
+# Extend the test environment
+
+# Improve documentation
+
+# Create one or more "real life" applications based on Celix to show the potential of Celix
+
+# Add pub sub admins. 
+The current implementation uses JSON over multicast UDP or over ZMQ.  
+One or more could be added. i.e. serialization based on Apache-Avro, communication over TCP / Kafka / Shared Memory  
+Add interfaces for other languages (Python / Rust / Go / ...)  

http://git-wip-us.apache.org/repos/asf/celix/blob/3f24edf0/misc/roadmap/roadmap.md
----------------------------------------------------------------------
diff --git a/misc/roadmap/roadmap.md b/misc/roadmap/roadmap.md
new file mode 100644
index 0000000..a3100be
--- /dev/null
+++ b/misc/roadmap/roadmap.md
@@ -0,0 +1,123 @@
+<!--
+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.
+-->
+
+# Roadmap
+
+Note this roadmap is still a draft.
+
+# Apache Celix 2.0.1 
+
+Date: TBD (juli/aug 2017?)
+
+## Improve PubSub (CELIX-407)
+
+1. Finalize introduction serializer services  
+1. Ensure code coverage of ~ 70% 
+
+## Finalize Runtime Creation (CELIX-408)
+
+1. Ensure that the runtime command are used for testing some distributed test (e.g. pubsub)
+
+## Add Support for running Celix as a single executable (TODO issue)
+For different reasons it could be interesting to support running bundles from a single executable.
+Primarily security, but also startup performance.
+
+To start this can be achieved by creating static version of the celix provided bundles. These static 
+bundles should have unique symbols, e.g  shell_bundleActivator_create instead of a 
+"normal" bundleActivator_create. The normal  activator functions should then 
+only be used (using a define or separated source file) when building a shared library bundle.
+A additional property (e.g. "cosgi.auto.static.start=shell, shell_tui") can be used to specify which 
+symbol prefixes to use.
+
+Note that if this is implemented it would also be a good moment to add a compile option / launcher option
+to disable dynamic loading of libraries. This way shared library based bundles can be used during 
+development, but for production a static executable with no capability to add bundles runtime 
+could be used if preferable. 
+
+# Apache Celix 2.1.0
+
+Date: TBD (Jan 2018)
+
+Note a short comming is that there is still no good support for export and import libraries between
+bundles. For Linux dlmopen is a solution, but for a more broader UNIX support a more "creative" 
+solution is needed (e.g. Just in time replacing the SONAME and NEEDED values in the respective shared libraries)
+
+## Extend Dependency Manager C/C++ (CELIX-409)
+
+The dependency manager offers declarative API for working with services and is arguable more easier 
+to use than the official OSGi Api. Extend the DM so that in can be used for virtually any bundle 
+without directly using the bundle context, bundle, module, service ref, service registration, etc API.
+This provided a much smaller API providing almost the same functionality.
+
+This means:
+1. Add support for service factory 
+1. Add support for providing listener hooks. Note that this is already supported by registering 
+   a `listener_hook_service` service, but maybe a more abstracted way.
+1. Add support looking up and opening resources in the bundle.
+1. Replace add,remove, etc callbacks which uses the service reference, with callbacks using properties
+1. Test if the dm correctly works when adding / removing provided services and service dependencies after a component is started.
+1. Getting framework properties (e.g. bundleContext_getProperty)
+1. Support for getting basic info from bundle (version, symbolic name, manifest)
+
+## Add framework services (TODO issue)
+Apache Celix is a framework for service oriented programming, this should also include for interacting with the 
+framework itself. Create framework services for:
+
+1. bundle management: installing, Starting, Stopping, deinstalling, listing, etc bundles.
+1. service registry info: nr of service registered, nr of service listeners, etc.
+1. framework listenerL start, stop, error events (whiteboard)
+1. bundle listener: installed, start, stop, deinstalled events (whiteboard)
+
+## Support dependency manager from framework (TODO issue)
+Because the dependency manager is actual the preferred way to write bundles, this should be support
+like "normal" activators" directly from the framework without using a static library.
+
+## Refactor Celix provided bundles to use dependency manager and framework services (TODO issue)
+Refactor Celix bundles (shell, shell_tuu, RSA, etc) to use the dependency manager instead of a "vanilla" 
+bundle activator. The dependency manager should be the preferred way to handle services. 
+Also instead of directly using the API from bundle_context, bundle, module, etc the framework services
+should be used.
+
+## Create dfi descriptor generator (TODO issue)
+Create a descriptor generator which can parse type and service headers. 
+This can be relatively easy  achieved by (e.g.) using the libclang library. 
+Also extend the CMake add_bundle command and create a CMake bundle_add_descriptors command to be able
+to add the descriptors to the bundle
+
+## Use dfi descriptor in service registrations/references (TODO issue)
+When available dfi descriptors can be used in Celix to validate if service are compatible and
+in case of the provided service having more functions than the consumer needs, create a (cast to) 
+a compatible consumer version.
+
+# Apache Celix 3.0.0
+
+Date: TBD (aug 2018)
+
+## Remove support for "vanilla" bundle activators (TODO issue)
+When all Celix provided bundles are using the dependency manager and framework services support for
+the "vanilla"  bundle activator can be dropped. Also a lot internals can be refactored because the public
+API should have shrunk quite a bit; This should lead to smaller code base -> less complex, easier to maintain
+and a smaller footprint.
+
+  
+## Refactor service registry to a single threaded design (TODO issue)
+Celix currently has some nested lock. It would be preferable to remove these, but this is difficult 
+because they are used to sync events which react on registering/unregistering services. Specially when 
+a unregister/register event leads to other services being registered/unregisterd. One way to deal with 
+this sync problem is to remove it by adding a single thread which handle al interaction between bundles 
+and the service registry.
+


[3/4] celix git commit: CELIX-449: Restructure of some parts of the documentation to make it easier to integrate with the celix-site.

Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/3f24edf0/documents/getting_started/services_with_cxx/readme.md
----------------------------------------------------------------------
diff --git a/documents/getting_started/services_with_cxx/readme.md b/documents/getting_started/services_with_cxx/readme.md
new file mode 100644
index 0000000..b8f359e
--- /dev/null
+++ b/documents/getting_started/services_with_cxx/readme.md
@@ -0,0 +1,571 @@
+<!--
+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.
+-->
+
+# Apache Celix - Using Services with C++
+
+## Intro 
+
+This example gives an overview for providing and using C and C++ services with Apache Celix with C++.
+
+## Services
+
+### C++ Services
+To start of, C++ service in Celix are just (abstract) classes. 
+
+In the following example there also a projected default constructor and destructor to ensure no instantiation / deletion of the service is possible:
+```C++
+#ifndef IANOTHER_EXAMPLE_H
+#define IANOTHER_EXAMPLE_H
+
+#define IANOTHER_EXAMPLE_VERSION "1.0.0"
+#define IANOTHER_EXAMPLE_CONSUMER_RANGE "[1.0.0,2.0.0)"
+
+class IAnotherExample {
+protected:
+    IAnotherExample() = default;
+    virtual ~IAnotherExample() = default;
+public:
+    virtual double method(int arg1, double arg2) = 0;
+};
+
+#endif //IANOTHER_EXAMPLE_H
+```
+
+For a Celix service a service name, service provider version and service consumer range should be declared.
+This is explicitly done with macros to prevent symbols so to that no linking dependencies are introduced. 
+For C++ the service name can be inferred. 
+
+### C Services
+C services in Celix are just a pointer to a memory location registered in the service registry using a name and an optional set of key/value pairs.
+
+By convention use the following service layout:
+```C
+//example.h
+#ifndef EXAMPLE_H_
+#define EXAMPLE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define EXAMPLE_NAME 			"org.example"
+#define EXAMPLE_VERSION 		"1.0.0"
+#define EXAMPLE_CONSUMER_RANGE   "[1.0.0,2.0.0)"
+
+
+struct example_struct {
+	void *handle;
+	int (*method)(void *handle, int arg1, double arg2, double *result);
+} ;
+
+typedef struct example_struct example_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* EXAMPLE_H_ */
+```
+
+For C service a struct containing the function pointers needs to be declared.
+The first element of the service struct should be a handle which can be used to store the service context, as convention we keep this pointer a void pointer to explicitly make it opaque.
+Note that also an opaque struct could be used (e.g a declared but not defined struct), but this can become problematic concerning components registering multiple services. 
+In that case explicit cast are needed to prevent warning and this can be confusing for the To prevent that issues void pointers are preferred.
+
+The rest of the element should be function pointers, which by convention should return an celix_status_t or int (which is technically the same). 
+The return value is used as a way of handling errors and is also needed to be able to make remote services (e.g. to be able to handle remote exceptions).
+
+The first argument of a service function should be the service handle and if there is a result the last argument should be a output parameter (either pre allocated (e.g. double *) or not (e.g. double **)).
+If the caller is not the owner of the output argument, a const pointer should be used (e.g. const char**). 
+It is also possible to create typedef of the pointer to the service struct (e.g. typedef struct example_struct example_t), but this is not needed. 
+
+In the Celix code base there are still service which uses a typedef with a pointer (e.g. typedef struct example_struct* example_struct_pt). This should be avoided, 
+because it is not possible to create the const pointer of those typedefs and it is not possible to include those typedef inside a existing struct without the needed for an additional malloc.
+
+
+
+### Semantic Versioning
+For versioning, semantic versioning should be used.
+
+A backward incompatible change should lead to a major version increase (e.g. 1.0.0 -> 2.0.0).
+
+### Versioning C++ Services
+For C++ Services versioning is used ot express binary compatibility changes that are incompatible are:
+
+- Everything. Seriously, binary compatibility in C++ is difficult and should be avoided. 
+
+Note that is is possible to use versioning for source compatibility and setup the build environment accordingly, but this is not part of this guide.
+
+### Versioning C Services
+For C Services versioning is used to express binary compatibility (for the same platform / compiler), change that are incompatible are:
+
+- Removing a function
+- Adding a function to before any other function
+- Moving a function to an other location in the service struct
+- Changing the signature of a function
+- Changing the semantics of a argument (e.g. changing range input from "range in kilometer" to "range in meters")
+
+A backwards binary compatible change which extend the functionality should lead to a minor version increase (e.g. 1.0.0 -> 1.1.0).
+Changes considered backwards compatible which extend the functionality are:
+
+- Adding a function to the back of the service struct
+
+A backwards binary compatible change which does not extend the functionality should lead to a micro version increase (e.g. 1.0.0 -> 1.0.1).
+Changes considered backwards binary compatible which does not extend the functionality are:
+
+- Changes in the documentation
+- Renaming of arguments
+
+For C services generally platform specific calling convention are used therefore binary compatibility between service provider and consumers from different compilers is possible (e.g. gcc and clang), 
+ but not advisable
+
+ 
+## Components
+
+Component are concrete classes in C++. This do not have to implement specific interface, expect the C++ service interfaces they provide.
+
+## Code Examples
+
+The next code blocks contains some code examples of components to indicate how to handle service dependencies, how to specify providing services and how to cope with locking/synchronizing.
+The complete example can be found [here](../../examples/celix-examples/services_example_cxx).
+
+### Bar Example
+
+The Bar example is a simple component providing the C `example` service and C++ `IAnotherExample` service.
+ 
+Note that the `Bar` component is just a plain old C++ object and does need to implement any specific Celix interfaces. 
+
+The `BarActivator` is the entry point for a C++ bundle. It must implement the `DmActivator::create` method so that C++ Dependency manager can create a instance `DmActivator` without needing to known the subclass. 
+It should also override the `DmActivator::init` to be able to declaratively program components and their provided service and service dependencies.
+
+The C++ Dependency Manager can use C++ member function pointers to control the component lifecycle (`init`, `start`, `stop` and `deinit`)  
+
+```C++
+//Bar.h
+#ifndef BAR_H
+#define BAR_H
+
+#include "IAnotherExample.h"
+
+class Bar : public IAnotherExample {
+    const double seed = 42;
+public:
+    Bar() = default;
+    virtual ~Bar() = default;
+
+    void init();
+    void start();
+    void stop();
+    void deinit();
+
+    virtual double method(int arg1, double arg2) override; //implementation of IAnotherExample::method
+    int cMethod(int arg1, double arg2, double *out); //implementation of example_t->method;
+};
+
+#endif //BAR_H
+```
+
+```C++
+//BarActivator.h
+#ifndef BAR_ACTIVATOR_H
+#define BAR_ACTIVATOR_H
+
+#include "celix/dm/DmActivator.h"
+#include "example.h"
+
+using namespace celix::dm;
+
+class BarActivator : public DmActivator {
+private:
+    example_t cExample {nullptr, nullptr};
+public:
+    BarActivator(DependencyManager& mng) : DmActivator(mng) {}
+    virtual void init() override;
+};
+
+#endif //BAR_ACTIVATOR_H
+```
+
+```C++
+//Bar.cc
+#include "Bar.h"
+#include <iostream>
+
+void Bar::init() {
+    std::cout << "init Bar\n";
+}
+
+void Bar::start() {
+    std::cout << "start Bar\n";
+}
+
+void Bar::stop() {
+    std::cout << "stop Bar\n";
+}
+
+void Bar::deinit() {
+    std::cout << "deinit Bar\n";
+}
+
+double Bar::method(int arg1, double arg2) {
+    double update = (this->seed + arg1) * arg2;
+    return update;
+}
+
+int Bar::cMethod(int arg1, double arg2, double *out) {
+    double r = this->method(arg1, arg2);
+    *out = r;
+    return 0;
+}
+```
+
+```C++
+//BarActivator.cc
+#include "Bar.h"
+#include "BarActivator.h"
+
+using namespace celix::dm;
+
+DmActivator* DmActivator::create(DependencyManager& mng) {
+    return new BarActivator(mng);
+}
+
+void BarActivator::init() {
+    std::shared_ptr<Bar> bar = std::shared_ptr<Bar>{new Bar{}};
+
+    Properties props;
+    props["meta.info.key"] = "meta.info.value";
+
+    Properties cProps;
+    cProps["also.meta.info.key"] = "also.meta.info.value";
+
+    this->cExample.handle = bar.get();
+    this->cExample.method = [](void *handle, int arg1, double arg2, double *out) {
+        Bar* bar = static_cast<Bar*>(handle);
+        return bar->cMethod(arg1, arg2, out);
+    };
+
+    mng.createComponent(bar)  //using a pointer a instance. Also supported is lazy initialization (default constructor needed) or a rvalue reference (move)
+        .addInterface<IAnotherExample>(IANOTHER_EXAMPLE_VERSION, props)
+        .addCInterface(&this->cExample, EXAMPLE_NAME, EXAMPLE_VERSION, cProps)
+        .setCallbacks(&Bar::init, &Bar::start, &Bar::stop, &Bar::deinit);
+}
+```
+
+### Foo Example
+
+The `Foo` example has a dependency to the C++ and C services provider by the `Bar` component. Note that it depends on the services and not directly on the Bar component.
+
+```C++
+//Foo.h
+#ifndef FOO_H
+#define FOO_H
+
+#include "example.h"
+#include "IAnotherExample.h"
+#include <thread>
+
+class Foo  {
+    IAnotherExample* example {nullptr};
+    const example_t* cExample {nullptr};
+    std::thread pollThread {};
+    bool running = false;
+public:
+    Foo() = default;
+    virtual ~Foo() = default;
+
+    void start();
+    void stop();
+
+    void setAnotherExample(IAnotherExample* e);
+    void setExample(const example_t* e);
+
+    void poll();
+};
+
+#endif //FOO_H
+```
+
+```C++
+//FooActivator.h
+#ifndef FOO_ACTIVATOR_H
+#define FOO_ACTIVATOR_H
+
+#include "celix/dm/DmActivator.h"
+
+using namespace celix::dm;
+
+class FooActivator : public DmActivator {
+private:
+public:
+    FooActivator(DependencyManager& mng) : DmActivator(mng) {}
+    virtual void init() override;
+};
+
+#endif //FOO_ACTIVATOR_H
+```
+
+```C++
+//Foo.cc
+#include "Foo.h"
+#include <iostream>
+
+void Foo::start() {
+    std::cout << "start Foo\n";
+    this->running = true;
+    pollThread = std::thread {&Foo::poll, this};
+}
+
+void Foo::stop() {
+    std::cout << "stop Foo\n";
+    this->running = false;
+    this->pollThread.join();
+}
+
+void Foo::setAnotherExample(IAnotherExample *e) {
+    this->example = e;
+}
+
+void Foo::setExample(const example_t *e) {
+    this->cExample = e;
+}
+
+void Foo::poll() {
+    double r1 = 1.0;
+    double r2 = 1.0;
+    while (this->running) {
+        //c++ service required -> if component started always available
+        r1 = this->example->method(3, r1);
+        std::cout << "Result IAnotherExample is " << r1 << "\n";
+
+        //c service is optional, can be nullptr
+        if (this->cExample != nullptr) {
+            double out;
+            this->cExample->method(this->cExample->handle, 4, r2, &out);
+            r2 = out;
+            std::cout << "Result example_t is " << r2 << "\n";
+        }
+        std::this_thread::sleep_for(std::chrono::milliseconds(5000));
+    }
+}
+```
+
+```C++
+//FooActivator.cc
+#include "Foo.h"
+#include "FooActivator.h"
+
+using namespace celix::dm;
+
+DmActivator* DmActivator::create(DependencyManager& mng) {
+    return new FooActivator(mng);
+}
+
+void FooActivator::init() {
+
+    Component<Foo>& cmp = mng.createComponent<Foo>()
+        .setCallbacks(nullptr, &Foo::start, &Foo::stop, nullptr);
+
+    cmp.createServiceDependency<IAnotherExample>()
+            .setRequired(true)
+            .setVersionRange(IANOTHER_EXAMPLE_CONSUMER_RANGE)
+            .setCallbacks(&Foo::setAnotherExample);
+
+    cmp.createCServiceDependency<example_t>(EXAMPLE_NAME)
+            .setRequired(false)
+            .setVersionRange(EXAMPLE_CONSUMER_RANGE)
+            .setCallbacks(&Foo::setExample);
+}
+```
+
+### Baz Example
+
+The `Baz` example has a dependency to the C++ and C services provider by the `Bar` component, 
+but uses the add / remove callbacks instead of set and as result is able to depend on multiple instance of a declared service dependencies.
+
+
+```C++
+//Baz.h
+#ifndef BAZ_H
+#define BAZ_H
+
+#include "example.h"
+#include "IAnotherExample.h"
+#include <thread>
+#include <list>
+#include <mutex>
+
+class Baz  {
+    std::list<IAnotherExample*> examples {};
+    std::mutex lock_for_examples {};
+
+    std::list<const example_t*> cExamples {};
+    std::mutex lock_for_cExamples {};
+
+    std::thread pollThread {};
+    bool running = false;
+public:
+    Baz() = default;
+    virtual ~Baz() = default;
+
+    void start();
+    void stop();
+
+    void addAnotherExample(IAnotherExample* e);
+    void removeAnotherExample(IAnotherExample* e);
+
+    void addExample(const example_t* e);
+    void removeExample(const example_t* e);
+
+    void poll();
+};
+
+#endif //BAZ_H
+```
+
+```C++
+//BazActivator.h
+#ifndef BAZ_ACTIVATOR_H
+#define BAZ_ACTIVATOR_H
+
+#include "celix/dm/DmActivator.h"
+
+using namespace celix::dm;
+
+class BazActivator : public DmActivator {
+private:
+public:
+    BazActivator(DependencyManager& mng) : DmActivator(mng) {}
+    virtual void init() override;
+};
+
+#endif //BAZ_ACTIVATOR_H
+```
+
+```C++
+//Baz.cc
+#include "Baz.h"
+#include <iostream>
+
+void Baz::start() {
+    std::cout << "start Baz\n";
+    this->running = true;
+    pollThread = std::thread {&Baz::poll, this};
+}
+
+void Baz::stop() {
+    std::cout << "stop Baz\n";
+    this->running = false;
+    this->pollThread.join();
+}
+
+void Baz::addAnotherExample(IAnotherExample *e) {
+    std::lock_guard<std::mutex> lock(this->lock_for_examples);
+    this->examples.push_back(e);
+}
+
+void Baz::removeAnotherExample(IAnotherExample *e) {
+    std::lock_guard<std::mutex> lock(this->lock_for_examples);
+    this->examples.remove(e);
+}
+
+void Baz::addExample(const example_t *e) {
+    std::lock_guard<std::mutex> lock(this->lock_for_cExamples);
+    this->cExamples.push_back(e);
+}
+
+void Baz::removeExample(const example_t *e) {
+    std::lock_guard<std::mutex> lock(this->lock_for_cExamples);
+    this->cExamples.remove(e);
+}
+
+void Baz::poll() {
+    double r1 = 1.0;
+    double r2 = 1.0;
+    while (this->running) {
+        //c++ service required -> if component started always available
+
+        {
+            std::lock_guard<std::mutex> lock(this->lock_for_examples);
+            int index = 0;
+            for (IAnotherExample *e : this->examples) {
+                r1 = e->method(3, r1);
+                std::cout << "Result IAnotherExample " << index++ << " is " << r1 << "\n";
+            }
+        }
+
+
+        {
+            std::lock_guard<std::mutex> lock(this->lock_for_cExamples);
+            int index = 0;
+            for (const example_t *e : this->cExamples) {
+                double out;
+                e->method(e->handle, 4, r2, &out);
+                r2 = out;
+                std::cout << "Result example_t " << index++ << " is " << r2 << "\n";
+            }
+        }
+
+        std::this_thread::sleep_for(std::chrono::milliseconds(4000));
+    }
+}
+```
+
+```C++
+//BazActivator.cc
+#include "Baz.h"
+#include "BazActivator.h"
+
+using namespace celix::dm;
+
+DmActivator* DmActivator::create(DependencyManager& mng) {
+    return new BazActivator(mng);
+}
+
+void BazActivator::init() {
+
+    Component<Baz>& cmp = mng.createComponent<Baz>()
+        .setCallbacks(nullptr, &Baz::start, &Baz::stop, nullptr);
+
+    cmp.createServiceDependency<IAnotherExample>()
+            .setRequired(true)
+            .setStrategy(DependencyUpdateStrategy::locking)
+            .setVersionRange(IANOTHER_EXAMPLE_CONSUMER_RANGE)
+            .setCallbacks(&Baz::addAnotherExample, &Baz::removeAnotherExample);
+
+    cmp.createCServiceDependency<example_t>(EXAMPLE_NAME)
+            .setRequired(false)
+            .setStrategy(DependencyUpdateStrategy::locking)
+            .setVersionRange(EXAMPLE_CONSUMER_RANGE)
+            .setCallbacks(&Baz::addExample, &Baz::removeExample);
+}
+```
+
+## Locking and Suspending
+ 
+As you may notice, the Baz example uses locks.
+In principle, locking is necessary in order to ensure coherence in case service dependencies are removed/added/changed; on the other hands, locking increases latency and, when misused, can lead to poor performance. 
+For this reason, the serviceDependency interface gives the possibility to choose between a locking and suspend (a non-locking) strategy through the serviceDependency_setStrategy function, as is used in the Foo2 example.
+
+The locking strategy `DependencyUpdateStrategy::locking` notifies the component in case the dependencies' set changes (e.g. a dependency is added/removed): the component is responsible for protecting via locks the dependencies' list and check (always under lock) if the service he's depending on is still available.
+The suspend or non-locking strategy `DependencyUpdateStrategy::suspend` (default when no strategy is explicitly set) reliefs the programmer from dealing with service dependencies' consistency issues: in case this strategy is adopted, the component is stopped and restarted (i.e. temporarily suspended) upon service dependencies' changes.
+
+The suspend strategy has the advantage of reducing locks' usage: of course, suspending the component has its own overhead (e.g. stopping and restarting threads), but this overhead is "paid" only in case of changes in service dependencies, while the locking overhead is always paid.
+
+## See also
+
+See the [C++ Dependeny Manager](../../libs/dependency_manager_cxx/readme.md) and [C++ Dependency Manager example](../../examples/celix-examples/dm_example_cxx) for more information and a more complex working example.

http://git-wip-us.apache.org/repos/asf/celix/blob/3f24edf0/documents/getting_started/simple_bundle/readme.md
----------------------------------------------------------------------
diff --git a/documents/getting_started/simple_bundle/readme.md b/documents/getting_started/simple_bundle/readme.md
new file mode 100644
index 0000000..8f10869
--- /dev/null
+++ b/documents/getting_started/simple_bundle/readme.md
@@ -0,0 +1,333 @@
+<!--
+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.
+-->
+
+# Apache Celix - Getting Started Guide: Creating a Simple Bundle
+
+## Intro
+This page is intended for first time users of Apache Celix. It should guide you through building & installing Apache Celix, setting up a new project, creating your first bundle, setting up the project for use with Eclipse project and finally running and debugging your bundle directly from eclipse workspace. 
+
+If there are any uncertainties or question, don't hesitate to ask your questions in the [Apache Celix mailing](https://celix.apache.org/support/mailinglist.html).
+
+## Prerequisite
+Some experience with a command line interface (xterm) is expected to be able to follow this guide. 
+
+## Building and Installing
+For Apache Celix see [Building And Installing](../building/readme.md)
+
+## Installing Eclipse CDT
+Download the latest eclipse CDT at [http://www.eclipse.org](http://www.eclipse.org) and install it on your system. For more information on how the install eclipse on your system consult the eclipse documentation. For this getting started guide the luna version of eclipse was used ([linux](http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/luna/R/eclipse-cpp-luna-R-linux-gtk-x86_64.tar.gz) [mac](http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/luna/R/eclipse-cpp-luna-R-macosx-cocoa-x86_64.tar.gz)).
+
+## Apache Celix Bundle project
+Now that Apache Celix and Eclipse is installed, we are ready to create a new Apache Celix Bundle project.
+CMake is used as build tool for Apache Celix projects.
+
+To setup of the project, first create a new project dir to work in:
+
+```bash
+#Create a new workspace to work in, e.g:
+mkdir ${HOME}/workspace
+export WS=${HOME}/workspace
+
+mkdir ${WS}/myproject
+cd ${WS}/myproject
+```
+
+Then create a CMakeLists.txt file - the makefile variant of CMake -in project root directory:
+
+```cmake	
+#${WS}/myproject/CMakeLists.txt
+	
+#Part 1. setup project
+cmake_minimum_required(VERSION 3.4)
+project(myproject C CXX)
+
+#Part 2. setup compilers
+SET(CMAKE_C_FLAGS "-D_GNU_SOURCE -std=gnu99 -Wall -Werror -fPIC ${CMAKE_C_FLAGS}")
+SET(CMAKE_C_FLAGS_DEBUG "-g -DDEBUG")
+SET(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
+SET(CMAKE_CXX_FLAGS_DEBUG "-g -DDEBUG")
+
+#Part 3. Setup Celix cmake files, include paths, libraries and library paths
+#Note. If celix is not installed in /usr/local dir, change the location accordingly.
+set(CMAKE_MODULE_PATH  ${CMAKE_MODULE_PATH} "/usr/local/share/celix/cmake/modules")
+find_package(CELIX REQUIRED)
+include_directories(${CELIX_INCLUDE_DIRS})
+
+#Part 4. Choose C, C++ or both
+add_subdirectory(bundles/HelloWorld_c) #C
+add_subdirectory(bundles/HelloWorld_cxx) #C++
+```
+		
+This CMakeLists.txt file, sets up the following:
+
+* Part 1 
+	* The minimum cmake version required. 
+	* The project name
+	* The type of source files to expect, in this case C and C++.
+* Part 2
+    * Setup the compilers. c99 for C and C++11 for C++
+* Part 3
+	* The Celix package should be searched, configured and that the Celix package is required. 
+	* For all build targets in this CMakeLists.txt file or any sub directory CMakeLists.txt files the Apache Celix headers directory should be included.
+* Part 4
+	* The CMakelists.txt file in the subdirectory bundles/hello_world and/or bundles/HelloWorld should also be processed.
+	
+
+It is a good practice to create a separate CMakeLists.txt file for every bundle you want to build. For the hello_world bundle a CMakeLists.txt file should be created in the bundles/hello_world sub directory.
+
+Create the sub directory:
+
+```CMake
+#Create directory structure for the hello_world bundles
+cd ${WS}/myproject
+mkdir -p bundles/HelloWorld_c/src
+mkdir -p bundles/HelloWorld_cxx/src
+mkdir -p bundles/HelloWorld_cxx/include
+```
+
+
+And add the following CMakeLists.txt file for the C Bundle:
+
+```CMake	
+#${WS}/myproject/bundles/HelloWorld_c/CMakeLists.txt
+
+add_celix_bundle(HelloWorld_c
+    VERSION 1.0.0
+	SOURCES
+        src/HelloWorld_activator.c
+)	
+
+if(APPLE)
+    target_link_libraries(HelloWorld_c ${CELIX_LIBRARIES} -Wl,-all_load ${CELIX_DM_STATIC_LIB})
+else()  
+    target_link_libraries(HelloWorld_c -Wl,--no-undefined -Wl,--whole-archive ${CELIX_DM_STATIC_LIB} -Wl,--no-whole-archive ${CELIX_LIBRARIES})
+endif()
+```
+
+And/or the following CMakeLists.txt for the C++ bundle:
+
+```CMake
+#${WS}/myproject/bundles/HelloWorld_cxx/CMakeLists.txt
+
+add_celix_bundle(HelloWorld_cxx
+    VERSION 1.0.0
+	SOURCES
+        src/HelloWorldActivator.cc
+)
+target_include_directories(HelloWorld_cxx PRIVATE include)
+
+IF(APPLE)
+    target_link_libraries(HelloWorld_cxx ${CELIX_LIBRARIES} -Wl,-all_load ${CELIX_DM_STATIC_CXX_LIB})
+else()
+    target_link_libraries(HelloWorld_cxx -Wl,--no-undefined -Wl,--whole-archive ${CELIX_DM_STATIC_CXX_LIB} -Wl,--no-whole-archive ${CELIX_LIBRARIES})
+endif()
+```
+	
+These CMakeLists.txt files declare that the bundles should be build based on the build result (shared library) of the declared sources (in this case the `private/src/hello_world_activator.c` or `private/src/HelloWorldActivator.cc` source). 
+The `add_celix_bundle` CMake function is an Apache Celix specific CMake extension. 
+The library used for the bundle will also be linked against the dependency manager static library. 
+
+
+The Celix framework will install the bundle, load the bundle shared library and call the bundle activator entry symbols. These entries need to be programmed by the user. 
+Note that in these examples we use the dependency manager libraries (C and C++ version) instead of developing a "vanilla" bundle activator; 
+The dependency manager uses a higher abstraction and is more simple to understand and maintain, but not part of the OSGi standard.
+
+The C Bundle Activator:
+```C
+//${WS}/myproject/bundles/hello_world/src/HelloWorld_activator.c
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "dm_activator.h"
+
+
+struct userData {
+	    char * word;
+};
+
+celix_status_t dm_create(bundle_context_pt context, void **out) {
+	celix_status_t status = CELIX_SUCCESS;
+    struct userData* result = calloc(1, sizeof(*result));
+	if (result != NULL) {
+            result->word = "C World";
+            *out = result;
+    } else {
+            status = CELIX_START_ERROR;
+    }
+    return status;
+}
+
+celix_status_t dm_init(void* userData, bundle_context_pt context, dm_dependency_manager_pt manager) {
+    struct userData* data = (struct userData *) userData;
+    printf("Hello %s\n", data->word);
+    return CELIX_SUCCESS;
+}
+
+celix_status_t dm_destroy(void* userData, bundle_context_pt context, dm_dependency_manager_pt manager) {
+    free(userData);
+    return CELIX_SUCCESS;
+}
+```
+	
+The C++ Bundle Activator (header + source):
+```C++
+//${WS}/myproject/bundles/HelloWorld/include/HelloWorldActivator.h
+#ifndef HELLOWORLDACTIVATOR_H_
+#define HELLOWORLDACTIVATOR_H_
+
+#include "celix/dm/DmActivator.h"
+
+class HelloWorldActivator : public celix::dm::DmActivator {
+private:
+    const std::string word {"C++ World"};
+public:
+    HelloWorldActivator(celix::dm::DependencyManager& mng) : DmActivator {mng} {}
+    virtual void init();
+    virtual void deinit();
+};
+
+#endif //HELLOWORLDACTIVATOR_H_
+```
+
+```C++
+//${WS}/myproject/bundles/HelloWorld/private/src/HelloWorldActivator.cc
+#include "HelloWorldActivator.h"
+#include <iostream>
+
+DmActivator* DmActivator::create(celix::dm::DependencyManager& mng) {
+    return new HelloWorldActivator(mng);
+}
+
+void HelloWorldActivator::init() {
+    std::cout << "Hello " << this->word << "\n";
+}
+
+void HelloWorldActivator::deinit() {
+    //nothing to do
+}
+```
+	
+### Building
+One of the highly recommended features of CMake is the ability to do out of source builds, the benefit is that all of the build results will go in a separate directory without cluttering the (source) project.
+CMake also needs to able to find the cmake files Celix provides. This can be achieved by providing a CMAKE_MODULE_PATH variable (or setting the CMAKE_MODULE_PATH in the top level CMakeLists.txt). 
+For this example it is assumed that Celix in installed in `/usr/local`.
+To create the build directory and build the project execute the following commands:
+
+
+```bash
+cd ${WS}
+mkdir myproject-build
+cd myproject-build
+cmake ../myproject
+make all  
+```	
+
+Hopefully you will some some build results scrolling over the screen and actual build results in the build directory.
+There should be a HelloWorld_c.zip in the bundles/HelloWorld_c directory and a HelloWorld_cxx.zip in the bundles/HelloWorld_cxx directory,
+these are the actual bundles.
+A bundle on its own has no real value, so lets setup a Celix container and run Celix with these bundles.
+
+### Running
+
+To create a deployment for the hello world bundles two things are needed: 
+	
+1. Add a `add_celix_container` statement in the (top level) `CMakeLists.txt` file declaring what to deploy and under which name.
+
+```CMake
+#${WS}/myproject/CMakeLists.txt
+add_celix_container(myproject
+    CXX 
+    BUNDLES 
+	    ${CELIX_BUNDLES_DIR}/shell.zip 
+	    ${CELIX_BUNDLES_DIR}/shell_tui.zip
+	    ${CELIX_BUNDLES_DIR}/dm_shell.zip 
+	    HelloWorld_c #C bundle
+	    HelloWorld_cxx #C++ bundle
+)		
+```
+
+With the `add_celix_container` CMake function a Celix container will be configured, which bundles to use can be specified with absolute paths to
+bundle files (e.g. the shell.zip bundle) or Celix bundle CMake target (e.g. the HelloWorld_c bundle).
+
+Rerun make again form the build project. the make files generated by CMake will ensure cmake is run it again to update the actual make files.
+
+```bash 		
+cd ${WS}/myproject-build
+make -j
+```	
+
+Now a deploy directory myproject should be available in the deploy directory. This directory contains - among other files - a release.sh script. This can be used to setup the required environment variables (like LD_LIBRARY_PATH).
+
+```bash
+cd ${WS}/myproject-build/deploy/myproject
+./myproject
+```
+
+The HelloWorld_c and HelloWorld_cxx bundles should be started with their own famous "Hello World" text variant printed. One for the C and one for the C++ bundle.
+The shell and shell_tui bundle are also deployed and these can be used to query and control the running framework. Below some commands are shown for querying the installed bundles, listing all known shell command, showing the help of a specific command and stopping a specific bundle (note that bundle 0 is the framework "bundle"):
+
+```
+lb 
+help
+stop 0
+```
+	
+## Apache Celix Projects in Eclipse
+
+A nice feature of CMake is the ability to generate Eclipse project files, with this feature bundles can also be developed with use of Eclipse. This should help speed up the development process. 
+To get started change directory to the build directory and generate a eclipse project file.
+
+	cd ${WS}/myproject-build 
+	cmake -G "Eclipse CDT4 - Unix Makefiles" .
+	
+Startup the Eclipse EDI and a chose the `${WS}`
+
+![select workspace](getting_started_img1.png)
+
+Import the project with existing project. 
+
+![import project](getting_started_img2.png)
+
+To build the project, use Project->Build All.
+To run or debug from Eclipse navigate to the myproject deploy directory and right click on
+the 'myproject' executable and as "Local C/C++ Application"
+
+
+## Apache Celix Projects in CLion
+
+Using Apache Celix projects in CLion quite easy.
+Just use `File -> Open ...` and select a Apache Celix project.
+Because CLion is a IDE for CMake projects and Apache Celix projects are CMake projects this works out of the box.
+
+To run a Celix container just select the target from CLion and press Run.
+
+ 
+## Next
+
+The get a complete overview of the available Celix CMake commands see:
+ - [Apache Celix - Celix CMake Commands](../cmake_commands/readme.md)
+
+The idea behind service oriented programming is that functionality is provided and used by abstract service, which hide implementation details.
+For a guide how to provide and use services see
+
+- [Apache Celix - Getting Started Guide: Using Services with C](using_services_with_c.md)
+- [Apache Celix - Getting Started Guide: Using Services with C++](using_services_with_cxx.md)
+ 
+
+
+	
+	

http://git-wip-us.apache.org/repos/asf/celix/blob/3f24edf0/documents/getting_started/using_services_with_c.md
----------------------------------------------------------------------
diff --git a/documents/getting_started/using_services_with_c.md b/documents/getting_started/using_services_with_c.md
deleted file mode 100644
index 75692f9..0000000
--- a/documents/getting_started/using_services_with_c.md
+++ /dev/null
@@ -1,610 +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.
--->
-
-# Apache Celix - Using Services with C
-
-## Intro 
-
-This example gives an overview for providing and using services with Apache Celix with C.
-
-## Services
-
-To start of, C services in Celix are just a pointer to a memory location registered in the service registry using a name and an optional set of key/value pairs. 
-
-By convention use the following service layout:
-
-```C
-//example.h
-#ifndef EXAMPLE_H_
-#define EXAMPLE_H_
-
-#define EXAMPLE_NAME            "org.example"
-#define EXAMPLE_VERSION         "1.0.0"
-#define EXAMPLE_CONSUMER_RANGE  "[1.0.0,2.0.0)"
-
-
-struct example_struct {
-	void *handle;
-	int (*method)(void *handle, int arg1, double arg2, double *result);
-} ;
-
-typedef struct example_struct example_t;
-
-#endif /* EXAMPLE_H_ */
-
-```
-
-
-For a Celix service a service name, service provider version and service consumer range should be declared.
-This is explicitly done with macros to prevent symbols so to that no linking dependencies are introduced.
-
-Then the actual struct for the service needs to be declared.
-The first element of the service struct should be a handle which can be used to store the service context, as convention we keep this pointer a void pointer to explicitly make it opaque.
-Note that also an opaque struct could be used (e.g a declared but not defined struct), but this can become problematic concerning components registering multiple services. 
-In that case explicit cast are needed to prevent warning and this can be confusing for the To prevent that issues void pointers are preferred.
-
-The rest of the element should be function pointers, which by convention should return an celix_status_t or int (which is technically the same). 
-The return value is used as a way of handling errors and is also needed to be able to make remote services (e.g. to be able to handle remote exceptions).
-
-The first argument of a service function should be the service handle and if there is a result the last argument should be a output parameter (either pre allocated (e.g. double *) or not (e.g. double **)).
-If the caller is not the owner of the output argument, a const pointer should be used (e.g. const char**). 
-It is also possible to create typedef of the pointer to the service struct (e.g. typedef struct example_struct example_t), but this is not needed. 
-
-In the Celix code base there are still service which uses a typedef with a pointer (e.g. typedef struct example_struct* example_struct_pt). This should be avoided, 
-because it is not possible to create the const pointer of those typedefs and it is not possible to include those typedef inside a existing struct without the needed for an additional malloc.
-
-### Semantic Versioning
-
-For versioning, semantic versioning should be used.
-
-A backward incompatible change should lead to a major version increase (e.g. 1.0.0 -> 2.0.0).
-For a C Service versioning is used to express binary compatibility (for the same platform / compiler), change that are incompatible are:
-
-- Removing a function
-- Adding a function to before any other function
-- Moving a function to an other location in the service struct
-- Changing the signature of a function
-- Changing the semantics of a argument (e.g. changing range input from "range in kilometer" to "range in meters")
-
-A backwards binary compatible change which extend the functionality should lead to a minor version increase (e.g. 1.0.0 -> 1.1.0).
-Changes considered backwards compatible which extend the functionality are:
-
-- Adding a function to the back of the service struct
-
-A backwards binary compatible change which does not extend the functionality should lead to a micro version increase (e.g. 1.0.0 -> 1.0.1).
-Changes considered backwards binary compatible which does not extend the functionality are:
-
-- Changes in the documentation
-- Renaming of arguments
-
-For C services generally platform specific calling convention are used therefore binary compatibility between service provider and consumers from different compilers is possible (e.g. gcc and clang), 
- but not advisable
-
- 
-## Components
-
-Component should use the ADT principle (see [ADT in C](http://inst.eecs.berkeley.edu/~selfpace/studyguide/9C.sg/Output/ADTs.in.C.html)).
-Note that is a convention.
-
-Components should have a `<cmpName>_create` and `<cmpName>_destroy` function.
-Components can have a `<cmpName>_start` and `<cmpName>_stop` function to start/stop threads or invoke functionality needed a fully created component. 
-The start function will only be called if all required service are available and the stop function will be called when some required are going or if the component needs to be stopped.
-
-Components can also have a `<cmpName>_init` and `<cmpName>_deinit` function which will be called before and after respectively the start and stop function. 
-The init/deinit function can be used to include (de)initialization which is not needed/wanted every time when service dependencies are being removed/added. 
-
-## Code Examples
-
-The next code blocks contains some code examples of components to indicate how to handle service dependencies, how to specify providing services and how to cope with locking/synchronizing.
-The complete example can be found [here](../../examples/services_example_c).
-
-The error checking is very minimal in these example to keep the focus on how to interact with services and how to deal with errors in C / Celix.
-
-
-### Bar example
-
-The bar example is a simple component providing the `example` service. 
- 
-```C
-//bar.h
-#ifndef BAR_H_
-#define BAR_H_
-
-#include "example.h"
-
-typedef struct bar_struct bar_t;
-
-bar_t* bar_create(void);
-void bar_destroy(bar_t *self);
-
-int bar_method(bar_t *self, int arg1, double arg2, double *out);
-
-#endif //BAR_H_
-```
-
-```C
-//bar.c
-#define OK 0
-#define ERROR 1
-
-struct bar_struct {
-    double prefValue;
-};
-
-bar_t* bar_create(void) {
-    bar_t *self = calloc(1, sizeof(*self));
-    if (self != NULL) {
-        self->prefValue = 42;
-    } else {
-        //log error
-    }
-    return self;
-};
-
-void bar_destroy(bar_t *self) {
-    free(self);
-}
-
-int bar_method(bar_t *self, int arg1, double arg2, double *out) {
-    double update = (self->prefValue + arg1) * arg2;
-    self->prefValue = update;
-    *out = update;
-    return OK;
-}
-```
-
-```C
-//bar_activator.c
-#include "dm_activator.h"
-#include "bar.h"
-
-#include <stdlib.h>
-
-struct activator {
-	bar_t *bar;
-	example_t exampleService;
-};
-
-celix_status_t dm_create(bundle_context_pt context, void **userData) {
-    celix_status_t status = CELIX_SUCCESS;
-    struct activator *act = calloc(1, sizeof(*act));
-    if (act != NULL) {
-
-        act->bar = bar_create();
-        act->exampleService.handle = act->bar;
-        act->exampleService.method = (void*) bar_method;
-
-        if (act->bar != NULL) {
-            *userData = act;
-        } else {
-            free(act);
-        }
-    } else {
-        status = CELIX_ENOMEM;
-	}
-	return status;
-}
-
-celix_status_t dm_init(void *userData, bundle_context_pt context, dm_dependency_manager_pt manager) {
-    celix_status_t status = CELIX_SUCCESS;
-    struct activator *activator = userData;
-
-    dm_component_pt cmp = NULL;
-    component_create(context, "BAR", &cmp);
-    component_setImplementation(cmp, activator->bar);
-    component_addInterface(cmp, EXAMPLE_NAME, EXAMPLE_VERSION, &activator->exampleService, NULL);
-
-    dependencyManager_add(manager, cmp);
-    return status;
-}
-
-celix_status_t dm_destroy(void *userData, bundle_context_pt context, dm_dependency_manager_pt manager) {
-    celix_status_t status = CELIX_SUCCESS;
-    struct activator *activator = userData;
-    bar_destroy(activator->bar);
-    free(activator);
-    return status;
-};
-```
-
-### Foo1 example
-
-The Foo1 example shows how add a service dependency, implement the callback, invoke a service and how to protect the usage of service with use of a mutex.
-
-```C
-//foo1.h
-#ifndef FOO1_H_
-#define FOO1_H_
-
-#include "example.h"
-
-typedef struct foo1_struct foo1_t;
-
-foo1_t* foo1_create(void);
-void foo1_destroy(foo1_t *self);
-
-int foo1_start(foo1_t *self);
-int foo1_stop(foo1_t *self);
-
-int foo1_setExample(foo1_t *self, const example_t *example);
-
-
-#endif //FOO1_H_
-```
-
-```C
-//foo1.c
-#include "foo1.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <signal.h>
-#include <stdbool.h>
-#include <pthread.h>
-#include <assert.h>
-
-
-#define OK 0
-#define ERROR 1
-
-static void* foo1_thread(void*);
-
-struct foo1_struct {
-    const example_t *example;
-    pthread_mutex_t mutex; //protecting example
-    pthread_t thread;
-    bool running;
-};
-
-foo1_t* foo1_create(void) {
-    foo1_t *self = calloc(1, sizeof(*self));
-    if (self != NULL) {
-        pthread_mutex_init(&self->mutex, NULL);
-        self->running = false;
-    } else {
-        //log error
-    }
-    return self;
-};
-
-void foo1_destroy(foo1_t *self) {
-    assert(!self->running);
-    pthread_mutex_destroy(&self->mutex);
-    free(self);
-}
-
-int foo1_start(foo1_t *self) {
-    self->running = true;
-    pthread_create(&self->thread, NULL, foo1_thread, self);
-    return OK;
-}
-
-int foo1_stop(foo1_t *self) {
-    self->running = false;
-    pthread_kill(self->thread, SIGUSR1);
-    pthread_join(self->thread, NULL);
-    return OK;
-}
-
-int foo1_setExample(foo1_t *self, const example_t *example) {
-    pthread_mutex_lock(&self->mutex);
-    self->example = example; //NOTE could be NULL if req is not mandatory
-    pthread_mutex_unlock(&self->mutex);
-    return OK;
-}
-
-static void* foo1_thread(void *userdata) {
-    foo1_t *self = userdata;
-    double result;
-    int rc;
-    while (self->running) {
-        pthread_mutex_lock(&self->mutex);
-        if (self->example != NULL) {
-            rc = self->example->method(self->example->handle, 1, 2.0, &result);
-            if (rc == 0) {
-                printf("Result is %f\n", result);
-            } else {
-                printf("Error invoking method for example\n");
-            }
-        }
-        pthread_mutex_unlock(&self->mutex);
-        usleep(10000000);
-    }
-    return NULL;
-}
-```
-
-```C
-//foo1_activator.c
-#include "dm_activator.h"
-#include "foo1.h"
-
-#include <stdlib.h>
-
-struct activator {
-	foo1_t *foo;
-};
-
-celix_status_t dm_create(bundle_context_pt context, void **userData) {
-    celix_status_t status = CELIX_SUCCESS;
-    struct activator *act = calloc(1, sizeof(*act));
-    if (act != NULL) {
-        act->foo = foo1_create();
-        if (act->foo != NULL) {
-            *userData = act;
-        } else {
-            free(act);
-        }
-    } else {
-        status = CELIX_ENOMEM;
-    }
-    return status;
-}
-
-celix_status_t dm_init(void *userData, bundle_context_pt context, dm_dependency_manager_pt manager) {
-    celix_status_t status = CELIX_SUCCESS;
-    struct activator *activator = userData;
-
-    dm_component_pt cmp = NULL;
-    component_create(context, "FOO1", &cmp);
-    component_setImplementation(cmp, activator->foo);
-
-    /*
-    With the component_setCallbacksSafe we register callbacks when a component is started / stopped using a component
-     with type foo1_t*
-    */
-    component_setCallbacksSafe(cmp, foo1_t*, NULL, foo1_start, foo1_stop, NULL);
-
-    dm_service_dependency_pt dep = NULL;
-    serviceDependency_create(&dep);
-    serviceDependency_setRequired(dep, true);
-    serviceDependency_setService(dep, EXAMPLE_NAME, EXAMPLE_CONSUMER_RANGE, NULL);
-    serviceDependency_setStrategy(dep, DM_SERVICE_DEPENDENCY_STRATEGY_LOCKING);
-
-    /*
-    With the serviceDependency_setCallbacksSafe we register callbacks when a service
-    is added and about to be removed for the component type foo1_t* and service type example_t*.
-
-    We should protect the usage of the
-    service because after removal of the service the memory location of that service
-    could be freed
-    */
-    serviceDependency_setCallbacksSafe(dep, foo1_t*, const example_t*, foo1_setExample, NULL, NULL, NULL, NULL);
-    component_addServiceDependency(cmp, dep);
-
-    dependencyManager_add(manager, cmp);
-
-    return status;
-}
-
-celix_status_t dm_destroy(void *userData, bundle_context_pt context, dm_dependency_manager_pt manager) {
-	celix_status_t status = CELIX_SUCCESS;
-	struct activator *activator = userData;
-	foo1_destroy(activator->foo);
-	free(activator);
-	return status;
-};
-
-```
-
-### Foo2 example
-
-The Foo2 example shows how to cope with multiple services and how to remove the need for locking by ensuring only access to the services and the services container by a single thread.
-
-```C
-//foo2.h
-#ifndef FOO2_H_
-#define FOO2_H_
-
-#include "example.h"
-
-typedef struct foo2_struct foo2_t;
-
-foo2_t* foo2_create(void);
-void foo2_destroy(foo2_t *self);
-
-int foo2_start(foo2_t *self);
-int foo2_stop(foo2_t *self);
-
-int foo2_addExample(foo2_t *self, const example_t *example);
-int foo2_removeExample(foo2_t *self, const example_t *example);
-
-#endif //FOO2_H_
-```
-
-```C
-//foo2.c
-#include "foo2.h"
-
-#include "array_list.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <signal.h>
-#include <stdbool.h>
-#include <pthread.h>
-#include <assert.h>
-
-
-#define OK 0
-#define ERROR 1
-
-static void* foo2_thread(void*);
-
-struct foo2_struct {
-    array_list_pt examples;
-    pthread_t thread;
-    bool running;
-};
-
-foo2_t* foo2_create(void) {
-    foo2_t *self = calloc(1, sizeof(*self));
-    if (self != NULL) {
-        self->examples = NULL;
-        arrayList_create(&self->examples);
-        self->running = false;
-    } else {
-        //log error
-    }
-    return self;
-};
-
-void foo2_destroy(foo2_t *self) {
-    assert(!self->running);
-    arrayList_destroy(self->examples);
-    free(self);
-}
-
-int foo2_start(foo2_t *self) {
-    self->running = true;
-    pthread_create(&self->thread, NULL, foo2_thread, self);
-    return OK;
-}
-
-int foo2_stop(foo2_t *self) {
-    self->running = false;
-    pthread_kill(self->thread, SIGUSR1);
-    pthread_join(self->thread, NULL);
-    return OK;
-}
-
-int foo2_addExample(foo2_t *self, const example_t *example) {
-    //NOTE foo2 is suspended -> thread is not running  -> safe to update
-    int status = OK;
-    status = arrayList_add(self->examples, (void *)example);
-    return status;
-}
-
-int foo2_removeExample(foo2_t *self, const example_t *example) {
-    //NOTE foo2 is suspended -> thread is not running  -> safe to update
-    int status = OK;
-    status = arrayList_removeElement(self->examples, (void*)example);
-    return status;
-}
-
-static void* foo2_thread(void *userdata) {
-    foo2_t *self = userdata;
-    double result;
-    int rc;
-    while (self->running) {
-        unsigned int size = arrayList_size(self->examples);
-        int i;
-        for (i = 0; i < size; i += 1) {
-            const example_t* example = arrayList_get(self->examples, i);
-            rc = example->method(example->handle, 1, 2.0, &result);
-            if (rc == 0) {
-                printf("Result is %f\n", result);
-            } else {
-                printf("Error invoking method for example\n");
-            }
-        }
-        usleep(10000000);
-    }
-    return NULL;
-
-```
-
-```C
-//foo2_activator.c
-#include "dm_activator.h"
-#include "foo2.h"
-
-#include <stdlib.h>
-
-struct activator {
-	foo2_t *foo;
-};
-
-celix_status_t dm_create(bundle_context_pt context, void **userData) {
-	celix_status_t status = CELIX_SUCCESS;
-	struct activator *act = calloc(1, sizeof(*act));
-	if (act != NULL) {
-		act->foo = foo2_create();
-        if (act->foo != NULL) {
-            *userData = act;
-        } else {
-            free(act);
-        }
-	} else {
-		status = CELIX_ENOMEM;
-	}
-	return status;
-}
-
-celix_status_t dm_init(void *userData, bundle_context_pt context, dm_dependency_manager_pt manager) {
-    celix_status_t status = CELIX_SUCCESS;
-	struct activator *activator = userData;
-
-	dm_component_pt cmp = NULL;
-	component_create(context, "FOO2", &cmp);
-	component_setImplementation(cmp, activator->foo);
-
-	/*
-	With the component_setCallbacksSafe we register callbacks when a component is started / stopped using a component
-	 with type foo1_t*
-	*/
-    component_setCallbacksSafe(cmp, foo2_t*, NULL, foo2_start, foo2_stop, NULL);
-
-	dm_service_dependency_pt dep = NULL;
-	serviceDependency_create(&dep);
-	serviceDependency_setRequired(dep, false);
-	serviceDependency_setService(dep, EXAMPLE_NAME, EXAMPLE_CONSUMER_RANGE, NULL);
-	serviceDependency_setStrategy(dep, DM_SERVICE_DEPENDENCY_STRATEGY_SUSPEND);
-
-	/*
-	With the serviceDependency_setCallbacksSafe we register callbacks when a service
-	is added and about to be removed for the component type foo1_t* and service type example_t*.
-
-	We should protect the usage of the
- 	service because after removal of the service the memory location of that service
-	could be freed
-	*/
-    serviceDependency_setCallbacksSafe(dep, foo2_t*, const example_t*, NULL, foo2_addExample, NULL, foo2_removeExample, NULL);
-	component_addServiceDependency(cmp, dep);
-
-	dependencyManager_add(manager, cmp);
-
-    return status;
-}
-
-celix_status_t dm_destroy(void *userData, bundle_context_pt context, dm_dependency_manager_pt manager) {
-	celix_status_t status = CELIX_SUCCESS;
-	struct activator *activator = userData;
-	foo2_destroy(activator->foo);
-	free(activator);
-	return status;
-};
-```
-
-## Locking and Suspending
- 
-As you may notice, the Foo1 example uses locks. 
-In principle, locking is necessary in order to ensure coherence in case service dependencies are removed/added/changed; on the other hands, locking increases latency and, when misused, can lead to poor performance. 
-For this reason, the serviceDependency interface gives the possibility to choose between a locking and suspend (a non-locking) strategy through the serviceDependency_setStrategy function, as is used in the Foo2 example.
-
-The locking strategy `DM_SERVICE_DEPENDENCY_STRATEGY_LOCKING` notifies the component in case the dependencies' set changes (e.g. a dependency is added/removed): the component is responsible for protecting via locks the dependencies' list and check (always under lock) if the service he's depending on is still available.
-The suspend or non-locking strategy `DM_SERVICE_DEPENDENCY_STRATEGY_SUSPEND` (default when no strategy is explicitly set) reliefs the programmer from dealing with service dependencies' consistency issues: in case this strategy is adopted, the component is stopped and restarted (i.e. temporarily suspended) upon service dependencies' changes.
-
-The suspend strategy has the advantage of reducing locks' usage: of course, suspending the component has its own overhead (e.g. stopping and restarting threads), but this overhead is "paid" only in case of changes in service dependencies, while the locking overhead is always paid.
-
-## See also
-
-See the [C Dependeny Manager](../../libs/dependency_manager/readme.md) and [C Dependency Manager example](../../examples/celix-examples/dm_example) for more information and a more complex working example.

http://git-wip-us.apache.org/repos/asf/celix/blob/3f24edf0/documents/getting_started/using_services_with_cxx.md
----------------------------------------------------------------------
diff --git a/documents/getting_started/using_services_with_cxx.md b/documents/getting_started/using_services_with_cxx.md
deleted file mode 100644
index b8f359e..0000000
--- a/documents/getting_started/using_services_with_cxx.md
+++ /dev/null
@@ -1,571 +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.
--->
-
-# Apache Celix - Using Services with C++
-
-## Intro 
-
-This example gives an overview for providing and using C and C++ services with Apache Celix with C++.
-
-## Services
-
-### C++ Services
-To start of, C++ service in Celix are just (abstract) classes. 
-
-In the following example there also a projected default constructor and destructor to ensure no instantiation / deletion of the service is possible:
-```C++
-#ifndef IANOTHER_EXAMPLE_H
-#define IANOTHER_EXAMPLE_H
-
-#define IANOTHER_EXAMPLE_VERSION "1.0.0"
-#define IANOTHER_EXAMPLE_CONSUMER_RANGE "[1.0.0,2.0.0)"
-
-class IAnotherExample {
-protected:
-    IAnotherExample() = default;
-    virtual ~IAnotherExample() = default;
-public:
-    virtual double method(int arg1, double arg2) = 0;
-};
-
-#endif //IANOTHER_EXAMPLE_H
-```
-
-For a Celix service a service name, service provider version and service consumer range should be declared.
-This is explicitly done with macros to prevent symbols so to that no linking dependencies are introduced. 
-For C++ the service name can be inferred. 
-
-### C Services
-C services in Celix are just a pointer to a memory location registered in the service registry using a name and an optional set of key/value pairs.
-
-By convention use the following service layout:
-```C
-//example.h
-#ifndef EXAMPLE_H_
-#define EXAMPLE_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define EXAMPLE_NAME 			"org.example"
-#define EXAMPLE_VERSION 		"1.0.0"
-#define EXAMPLE_CONSUMER_RANGE   "[1.0.0,2.0.0)"
-
-
-struct example_struct {
-	void *handle;
-	int (*method)(void *handle, int arg1, double arg2, double *result);
-} ;
-
-typedef struct example_struct example_t;
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* EXAMPLE_H_ */
-```
-
-For C service a struct containing the function pointers needs to be declared.
-The first element of the service struct should be a handle which can be used to store the service context, as convention we keep this pointer a void pointer to explicitly make it opaque.
-Note that also an opaque struct could be used (e.g a declared but not defined struct), but this can become problematic concerning components registering multiple services. 
-In that case explicit cast are needed to prevent warning and this can be confusing for the To prevent that issues void pointers are preferred.
-
-The rest of the element should be function pointers, which by convention should return an celix_status_t or int (which is technically the same). 
-The return value is used as a way of handling errors and is also needed to be able to make remote services (e.g. to be able to handle remote exceptions).
-
-The first argument of a service function should be the service handle and if there is a result the last argument should be a output parameter (either pre allocated (e.g. double *) or not (e.g. double **)).
-If the caller is not the owner of the output argument, a const pointer should be used (e.g. const char**). 
-It is also possible to create typedef of the pointer to the service struct (e.g. typedef struct example_struct example_t), but this is not needed. 
-
-In the Celix code base there are still service which uses a typedef with a pointer (e.g. typedef struct example_struct* example_struct_pt). This should be avoided, 
-because it is not possible to create the const pointer of those typedefs and it is not possible to include those typedef inside a existing struct without the needed for an additional malloc.
-
-
-
-### Semantic Versioning
-For versioning, semantic versioning should be used.
-
-A backward incompatible change should lead to a major version increase (e.g. 1.0.0 -> 2.0.0).
-
-### Versioning C++ Services
-For C++ Services versioning is used ot express binary compatibility changes that are incompatible are:
-
-- Everything. Seriously, binary compatibility in C++ is difficult and should be avoided. 
-
-Note that is is possible to use versioning for source compatibility and setup the build environment accordingly, but this is not part of this guide.
-
-### Versioning C Services
-For C Services versioning is used to express binary compatibility (for the same platform / compiler), change that are incompatible are:
-
-- Removing a function
-- Adding a function to before any other function
-- Moving a function to an other location in the service struct
-- Changing the signature of a function
-- Changing the semantics of a argument (e.g. changing range input from "range in kilometer" to "range in meters")
-
-A backwards binary compatible change which extend the functionality should lead to a minor version increase (e.g. 1.0.0 -> 1.1.0).
-Changes considered backwards compatible which extend the functionality are:
-
-- Adding a function to the back of the service struct
-
-A backwards binary compatible change which does not extend the functionality should lead to a micro version increase (e.g. 1.0.0 -> 1.0.1).
-Changes considered backwards binary compatible which does not extend the functionality are:
-
-- Changes in the documentation
-- Renaming of arguments
-
-For C services generally platform specific calling convention are used therefore binary compatibility between service provider and consumers from different compilers is possible (e.g. gcc and clang), 
- but not advisable
-
- 
-## Components
-
-Component are concrete classes in C++. This do not have to implement specific interface, expect the C++ service interfaces they provide.
-
-## Code Examples
-
-The next code blocks contains some code examples of components to indicate how to handle service dependencies, how to specify providing services and how to cope with locking/synchronizing.
-The complete example can be found [here](../../examples/celix-examples/services_example_cxx).
-
-### Bar Example
-
-The Bar example is a simple component providing the C `example` service and C++ `IAnotherExample` service.
- 
-Note that the `Bar` component is just a plain old C++ object and does need to implement any specific Celix interfaces. 
-
-The `BarActivator` is the entry point for a C++ bundle. It must implement the `DmActivator::create` method so that C++ Dependency manager can create a instance `DmActivator` without needing to known the subclass. 
-It should also override the `DmActivator::init` to be able to declaratively program components and their provided service and service dependencies.
-
-The C++ Dependency Manager can use C++ member function pointers to control the component lifecycle (`init`, `start`, `stop` and `deinit`)  
-
-```C++
-//Bar.h
-#ifndef BAR_H
-#define BAR_H
-
-#include "IAnotherExample.h"
-
-class Bar : public IAnotherExample {
-    const double seed = 42;
-public:
-    Bar() = default;
-    virtual ~Bar() = default;
-
-    void init();
-    void start();
-    void stop();
-    void deinit();
-
-    virtual double method(int arg1, double arg2) override; //implementation of IAnotherExample::method
-    int cMethod(int arg1, double arg2, double *out); //implementation of example_t->method;
-};
-
-#endif //BAR_H
-```
-
-```C++
-//BarActivator.h
-#ifndef BAR_ACTIVATOR_H
-#define BAR_ACTIVATOR_H
-
-#include "celix/dm/DmActivator.h"
-#include "example.h"
-
-using namespace celix::dm;
-
-class BarActivator : public DmActivator {
-private:
-    example_t cExample {nullptr, nullptr};
-public:
-    BarActivator(DependencyManager& mng) : DmActivator(mng) {}
-    virtual void init() override;
-};
-
-#endif //BAR_ACTIVATOR_H
-```
-
-```C++
-//Bar.cc
-#include "Bar.h"
-#include <iostream>
-
-void Bar::init() {
-    std::cout << "init Bar\n";
-}
-
-void Bar::start() {
-    std::cout << "start Bar\n";
-}
-
-void Bar::stop() {
-    std::cout << "stop Bar\n";
-}
-
-void Bar::deinit() {
-    std::cout << "deinit Bar\n";
-}
-
-double Bar::method(int arg1, double arg2) {
-    double update = (this->seed + arg1) * arg2;
-    return update;
-}
-
-int Bar::cMethod(int arg1, double arg2, double *out) {
-    double r = this->method(arg1, arg2);
-    *out = r;
-    return 0;
-}
-```
-
-```C++
-//BarActivator.cc
-#include "Bar.h"
-#include "BarActivator.h"
-
-using namespace celix::dm;
-
-DmActivator* DmActivator::create(DependencyManager& mng) {
-    return new BarActivator(mng);
-}
-
-void BarActivator::init() {
-    std::shared_ptr<Bar> bar = std::shared_ptr<Bar>{new Bar{}};
-
-    Properties props;
-    props["meta.info.key"] = "meta.info.value";
-
-    Properties cProps;
-    cProps["also.meta.info.key"] = "also.meta.info.value";
-
-    this->cExample.handle = bar.get();
-    this->cExample.method = [](void *handle, int arg1, double arg2, double *out) {
-        Bar* bar = static_cast<Bar*>(handle);
-        return bar->cMethod(arg1, arg2, out);
-    };
-
-    mng.createComponent(bar)  //using a pointer a instance. Also supported is lazy initialization (default constructor needed) or a rvalue reference (move)
-        .addInterface<IAnotherExample>(IANOTHER_EXAMPLE_VERSION, props)
-        .addCInterface(&this->cExample, EXAMPLE_NAME, EXAMPLE_VERSION, cProps)
-        .setCallbacks(&Bar::init, &Bar::start, &Bar::stop, &Bar::deinit);
-}
-```
-
-### Foo Example
-
-The `Foo` example has a dependency to the C++ and C services provider by the `Bar` component. Note that it depends on the services and not directly on the Bar component.
-
-```C++
-//Foo.h
-#ifndef FOO_H
-#define FOO_H
-
-#include "example.h"
-#include "IAnotherExample.h"
-#include <thread>
-
-class Foo  {
-    IAnotherExample* example {nullptr};
-    const example_t* cExample {nullptr};
-    std::thread pollThread {};
-    bool running = false;
-public:
-    Foo() = default;
-    virtual ~Foo() = default;
-
-    void start();
-    void stop();
-
-    void setAnotherExample(IAnotherExample* e);
-    void setExample(const example_t* e);
-
-    void poll();
-};
-
-#endif //FOO_H
-```
-
-```C++
-//FooActivator.h
-#ifndef FOO_ACTIVATOR_H
-#define FOO_ACTIVATOR_H
-
-#include "celix/dm/DmActivator.h"
-
-using namespace celix::dm;
-
-class FooActivator : public DmActivator {
-private:
-public:
-    FooActivator(DependencyManager& mng) : DmActivator(mng) {}
-    virtual void init() override;
-};
-
-#endif //FOO_ACTIVATOR_H
-```
-
-```C++
-//Foo.cc
-#include "Foo.h"
-#include <iostream>
-
-void Foo::start() {
-    std::cout << "start Foo\n";
-    this->running = true;
-    pollThread = std::thread {&Foo::poll, this};
-}
-
-void Foo::stop() {
-    std::cout << "stop Foo\n";
-    this->running = false;
-    this->pollThread.join();
-}
-
-void Foo::setAnotherExample(IAnotherExample *e) {
-    this->example = e;
-}
-
-void Foo::setExample(const example_t *e) {
-    this->cExample = e;
-}
-
-void Foo::poll() {
-    double r1 = 1.0;
-    double r2 = 1.0;
-    while (this->running) {
-        //c++ service required -> if component started always available
-        r1 = this->example->method(3, r1);
-        std::cout << "Result IAnotherExample is " << r1 << "\n";
-
-        //c service is optional, can be nullptr
-        if (this->cExample != nullptr) {
-            double out;
-            this->cExample->method(this->cExample->handle, 4, r2, &out);
-            r2 = out;
-            std::cout << "Result example_t is " << r2 << "\n";
-        }
-        std::this_thread::sleep_for(std::chrono::milliseconds(5000));
-    }
-}
-```
-
-```C++
-//FooActivator.cc
-#include "Foo.h"
-#include "FooActivator.h"
-
-using namespace celix::dm;
-
-DmActivator* DmActivator::create(DependencyManager& mng) {
-    return new FooActivator(mng);
-}
-
-void FooActivator::init() {
-
-    Component<Foo>& cmp = mng.createComponent<Foo>()
-        .setCallbacks(nullptr, &Foo::start, &Foo::stop, nullptr);
-
-    cmp.createServiceDependency<IAnotherExample>()
-            .setRequired(true)
-            .setVersionRange(IANOTHER_EXAMPLE_CONSUMER_RANGE)
-            .setCallbacks(&Foo::setAnotherExample);
-
-    cmp.createCServiceDependency<example_t>(EXAMPLE_NAME)
-            .setRequired(false)
-            .setVersionRange(EXAMPLE_CONSUMER_RANGE)
-            .setCallbacks(&Foo::setExample);
-}
-```
-
-### Baz Example
-
-The `Baz` example has a dependency to the C++ and C services provider by the `Bar` component, 
-but uses the add / remove callbacks instead of set and as result is able to depend on multiple instance of a declared service dependencies.
-
-
-```C++
-//Baz.h
-#ifndef BAZ_H
-#define BAZ_H
-
-#include "example.h"
-#include "IAnotherExample.h"
-#include <thread>
-#include <list>
-#include <mutex>
-
-class Baz  {
-    std::list<IAnotherExample*> examples {};
-    std::mutex lock_for_examples {};
-
-    std::list<const example_t*> cExamples {};
-    std::mutex lock_for_cExamples {};
-
-    std::thread pollThread {};
-    bool running = false;
-public:
-    Baz() = default;
-    virtual ~Baz() = default;
-
-    void start();
-    void stop();
-
-    void addAnotherExample(IAnotherExample* e);
-    void removeAnotherExample(IAnotherExample* e);
-
-    void addExample(const example_t* e);
-    void removeExample(const example_t* e);
-
-    void poll();
-};
-
-#endif //BAZ_H
-```
-
-```C++
-//BazActivator.h
-#ifndef BAZ_ACTIVATOR_H
-#define BAZ_ACTIVATOR_H
-
-#include "celix/dm/DmActivator.h"
-
-using namespace celix::dm;
-
-class BazActivator : public DmActivator {
-private:
-public:
-    BazActivator(DependencyManager& mng) : DmActivator(mng) {}
-    virtual void init() override;
-};
-
-#endif //BAZ_ACTIVATOR_H
-```
-
-```C++
-//Baz.cc
-#include "Baz.h"
-#include <iostream>
-
-void Baz::start() {
-    std::cout << "start Baz\n";
-    this->running = true;
-    pollThread = std::thread {&Baz::poll, this};
-}
-
-void Baz::stop() {
-    std::cout << "stop Baz\n";
-    this->running = false;
-    this->pollThread.join();
-}
-
-void Baz::addAnotherExample(IAnotherExample *e) {
-    std::lock_guard<std::mutex> lock(this->lock_for_examples);
-    this->examples.push_back(e);
-}
-
-void Baz::removeAnotherExample(IAnotherExample *e) {
-    std::lock_guard<std::mutex> lock(this->lock_for_examples);
-    this->examples.remove(e);
-}
-
-void Baz::addExample(const example_t *e) {
-    std::lock_guard<std::mutex> lock(this->lock_for_cExamples);
-    this->cExamples.push_back(e);
-}
-
-void Baz::removeExample(const example_t *e) {
-    std::lock_guard<std::mutex> lock(this->lock_for_cExamples);
-    this->cExamples.remove(e);
-}
-
-void Baz::poll() {
-    double r1 = 1.0;
-    double r2 = 1.0;
-    while (this->running) {
-        //c++ service required -> if component started always available
-
-        {
-            std::lock_guard<std::mutex> lock(this->lock_for_examples);
-            int index = 0;
-            for (IAnotherExample *e : this->examples) {
-                r1 = e->method(3, r1);
-                std::cout << "Result IAnotherExample " << index++ << " is " << r1 << "\n";
-            }
-        }
-
-
-        {
-            std::lock_guard<std::mutex> lock(this->lock_for_cExamples);
-            int index = 0;
-            for (const example_t *e : this->cExamples) {
-                double out;
-                e->method(e->handle, 4, r2, &out);
-                r2 = out;
-                std::cout << "Result example_t " << index++ << " is " << r2 << "\n";
-            }
-        }
-
-        std::this_thread::sleep_for(std::chrono::milliseconds(4000));
-    }
-}
-```
-
-```C++
-//BazActivator.cc
-#include "Baz.h"
-#include "BazActivator.h"
-
-using namespace celix::dm;
-
-DmActivator* DmActivator::create(DependencyManager& mng) {
-    return new BazActivator(mng);
-}
-
-void BazActivator::init() {
-
-    Component<Baz>& cmp = mng.createComponent<Baz>()
-        .setCallbacks(nullptr, &Baz::start, &Baz::stop, nullptr);
-
-    cmp.createServiceDependency<IAnotherExample>()
-            .setRequired(true)
-            .setStrategy(DependencyUpdateStrategy::locking)
-            .setVersionRange(IANOTHER_EXAMPLE_CONSUMER_RANGE)
-            .setCallbacks(&Baz::addAnotherExample, &Baz::removeAnotherExample);
-
-    cmp.createCServiceDependency<example_t>(EXAMPLE_NAME)
-            .setRequired(false)
-            .setStrategy(DependencyUpdateStrategy::locking)
-            .setVersionRange(EXAMPLE_CONSUMER_RANGE)
-            .setCallbacks(&Baz::addExample, &Baz::removeExample);
-}
-```
-
-## Locking and Suspending
- 
-As you may notice, the Baz example uses locks.
-In principle, locking is necessary in order to ensure coherence in case service dependencies are removed/added/changed; on the other hands, locking increases latency and, when misused, can lead to poor performance. 
-For this reason, the serviceDependency interface gives the possibility to choose between a locking and suspend (a non-locking) strategy through the serviceDependency_setStrategy function, as is used in the Foo2 example.
-
-The locking strategy `DependencyUpdateStrategy::locking` notifies the component in case the dependencies' set changes (e.g. a dependency is added/removed): the component is responsible for protecting via locks the dependencies' list and check (always under lock) if the service he's depending on is still available.
-The suspend or non-locking strategy `DependencyUpdateStrategy::suspend` (default when no strategy is explicitly set) reliefs the programmer from dealing with service dependencies' consistency issues: in case this strategy is adopted, the component is stopped and restarted (i.e. temporarily suspended) upon service dependencies' changes.
-
-The suspend strategy has the advantage of reducing locks' usage: of course, suspending the component has its own overhead (e.g. stopping and restarting threads), but this overhead is "paid" only in case of changes in service dependencies, while the locking overhead is always paid.
-
-## See also
-
-See the [C++ Dependeny Manager](../../libs/dependency_manager_cxx/readme.md) and [C++ Dependency Manager example](../../examples/celix-examples/dm_example_cxx) for more information and a more complex working example.


[2/4] celix git commit: CELIX-449: Restructure of some parts of the documentation to make it easier to integrate with the celix-site.

Posted by pn...@apache.org.
http://git-wip-us.apache.org/repos/asf/celix/blob/3f24edf0/documents/roadmap/api_v3/celix/celix.h
----------------------------------------------------------------------
diff --git a/documents/roadmap/api_v3/celix/celix.h b/documents/roadmap/api_v3/celix/celix.h
deleted file mode 100644
index 583262e..0000000
--- a/documents/roadmap/api_v3/celix/celix.h
+++ /dev/null
@@ -1,1896 +0,0 @@
-/**
- *Licensed to the Apache Software Foundation (ASF) under one
- *or more contributor license agreements.  See the NOTICE file
- *distributed with this work for additional information
- *regarding copyright ownership.  The ASF licenses this file
- *to you under the Apache License, Version 2.0 (the
- *"License"); you may not use this file except in compliance
- *with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- *Unless required by applicable law or agreed to in writing,
- *software distributed under the License is distributed on an
- *"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- *specific language governing permissions and limitations
- *under the License.
- */
-#ifndef CELIX_H_
-#define CELIX_H_
-
-/** General remarks
- *
- * - Id instead of pointers
- * In many cases a object id as uint64_t is used instead of pointer. This to prevent storing pointers to shared
- * resources with a volatile lifecycle (i.e. almost everything in a dynamic module/service framework)
- *
- * - Resilient API
- * All celix functions should silently allow to be called by NULL arguments and invalid ids.
- * For example the celix_bundle_name(NULL) call will silently return NULL.
- *
- * - Naming
- * The API mostly moved away from the typical Java getter / setter approach: Nouns are used
- * for retrieving values which does not have a side effect (also the first argument is a const).
- * THe exception for this are function which can be used as questions in logical operation, these are prefix
- * with a is or has (e.g. hasKey / isValid). Verbs are used for functions with side effects.
- * For callbacks which act on a certain event a on prefix is used (e.g. onAddingService).
- *
- * - Multi language support
- * The aim is to add support for multiple language with the C being the common denominator, foreseen languages:
- * C, C++, Rust, Swift & Python.
- * The API is prepared for multi language support.
- */
-
-//TODO log marcros (FW, MODULE & BUNDLE)
-
-#include <stddef.h> //NULL
-#include <stdint.h> //uint64_t
-#include <stdio.h> //FILE
-#include <pthread.h> //pthread_mutex_t
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-//celix.h
-#include "celix/types.h"
-#include "celix/utils/properies.h"
-#include "celix/utils/map.h"
-#include "celix/framework.h"
-#include "celix/bundle.h"
-#include "celix/module.h"
-#include "celix/framework_services.h"
-
-#define CELIX_API_VERSION 3
-
-#define CELIX_LANG_C "C"
-#define CELIX_LANG_CXX "C++"
-#define CELIX_LANG_SWIFT "Swift"
-#define CELIX_LANG_PYTHON "Python"
-
-
-
-
-//celix/utils/map.h
-
-/**
- * The celix map can store values under a string keys.
- * The values can have different types.
- *
- * The map API is not thread safe.
- */
-
-#include <stdbool.h> //bool
-
-typedef struct celix_map celix_map;
-
-typedef enum celix_map_value_type {
-    CELIX_MAP_TYPE_UNKNOWN      = 0,
-    CELIX_MAP_TYPE_STRING       = 1,
-    CELIX_MAP_TYPE_PTR          = 2,
-    CELIX_MAP_TYPE_CONST_PTR    = 3,
-    CELIX_MAP_TYPE_INT8         = 4,
-    CELIX_MAP_TYPE_UINT8        = 5,
-    CELIX_MAP_TYPE_INT16        = 6,
-    CELIX_MAP_TYPE_UINT16       = 7,
-    CELIX_MAP_TYPE_INT32        = 8,
-    CELIX_MAP_TYPE_UINT32       = 9,
-    CELIX_MAP_TYPE_INT64        = 10,
-    CELIX_MAP_TYPE_UINT64       = 11,
-    CELIX_MAP_TYPE_FLOAT        = 12,
-    CELIX_MAP_TYPE_DOUBLE       = 13,
-} celix_map_value_type;
-
-typedef struct celix_map_entry {
-    const char* key;
-    celix_map_entry_type type;
-    union {
-        const char* strVal;
-        void* ptrVal;
-        void* constPtrVal;
-        int8_t int8Val;
-        int16_t int16Val;
-        int32_t int32Val;
-        int64_t int64Val;
-        uint8_t uint8Val;
-        uint16_t uint8Val;
-        uint32_t uint8Val;
-        uint64_t uint8Val;
-        float floatVal;
-        double doubleVal;
-    } value;
-} celix_map_entry;
-
-/**
- * Creates a new map (hashmap or maybe BST (sys/tree.h)?)
- */
-celix_map* celix_map_create(void);
-
-/**
- * Copies (deep copy) a map
- */
-celix_map* celix_map_copy(const celix_map* map);
-
-/**
- * Destroys the map and release the memory.
- * Specifically this means that the map entries and keys are freed.
- */
-void celix_map_destroy(celix_map* map);
-
-/**
- * Returns an array of keys. The map is still owner of this array.
- * @param map The celix map
- * @param len If not NULL will be set to the size of the map.
- * @return If len is NULL this returns NULL, else a array of the keys.
- */
-const char* celix_map_keys(const celix_map* map, size_t* len);
-
-/**
- * Returns an array of entries. The map is still owner of this array.
- * @param map The celix map
- * @param len If not NULL will be set to the size of the map.
- * @return If len is NULL this returns NULL, else a array of the entries.
- */
-const celix_map_entry* celix_map_entries(const celix_map* map, size_t* len);
-
-/**
- * Returns the nr of entries of the map
- */
-size_t celix_map_size(const celix_map* map);
-
-/**
- * Returns whether the map has an entry with the provided key
- */
-bool celix_map_hasKey(const celix_map* map, const char* key);
-
-/**
- * Returns the value type of the entry for the provided key
- * or CELIX_MAP_VALUE_TYPE_UNKNOWN if the is no entry for the
- * provided key.
- */
-celix_map_value_type celix_map_valueType(const celix_map* map, const char* key);
-
-/**
- * Returns the string value for the provided key.
- * If there is no entry for the provided key or if the entry is not a string
- * type the provided defaultValue will be returned.
- */
-const char* celix_map_stringValue(const celix_map* map, const char* key, const char* defaultValue);
-
-/**
- * Adds or replaces an entry fot he provided key. The entry will be of a ptr type.
- * The key and value string will be copied into the entry if its a new entry.
- * If this replaces an entry, only the value will copied to the entry and previous
- * value will be freed.
- */
-void celix_map_putString(celix_map* map, const char* key, const char* value);
-
-/**
- * Returns the ptr value for the provided key.
- * If there is no entry for the provided key or if the entry is not a ptr
- * type the provided defaultValue will be returned.
- */
-void* celix_map_ptrValue(const celix_map* map, const char* key, const void* defaultValue);
-
-/**
- * Adds or replaces an entry fot he provided key. The entry will be of a ptr type.
- * The key string will be copied into the entry if its a new entry.
- * If this replaces an entry, only the value will be changed.
- */
-void celix_map_putPtr(celix_map* map, const char* key, void* value);
-
-/**
- * Returns the const ptr value for the provided key.
- * If there is no entry for the provided key or if the entry is not a ptr
- * type the provided defaultValue will be returned.
- */
-const void* celix_map_constPtrValue(const celix_map* map, const char* key, const void* defaultValue);
-
-/**
- * Adds or replaces an entry fot he provided key. The entry will be of a const ptr type.
- * The key string will be copied into the entry if its a new entry.
- * If this replaces an entry, only the value will be changed.
- */
-void celix_map_putConstPtr(celix_map* map, const char* key, const void* value);
-
-
-int8_t celix_map_int8Value(const celix_map* map, const char* key, int8_t defaultValue);
-void celix_map_putInt8(celix_map* map, const char* key, int8_t value);
-
-uint8_t celix_map_uint8Value(const celix_map* map, const char* key, uin8_t defaultValue);
-void celix_map_putUint8(celix_map* map, const char* key, uint8_t value);
-
-int16_t celix_map_int16Value(const celix_map* map, const char* key, int16_t defaultValue);
-void celix_map_putInt16(celix_map* map, const char* key, int16_t value);
-
-uint16_t celix_map_uint16Value(const celix_map* map, const char* key, uin16_t defaultValue);
-void celix_map_putUint16(celix_map* map, const char* key, uint16_t value);
-
-int32_t celix_map_int32Value(const celix_map* map, const char* key, int32_t defaultValue);
-void celix_map_putInt32(celix_map* map, const char* key, int32_t value);
-
-uint32_t celix_map_uint32Value(const celix_map* map, const char* key, uin32_t defaultValue);
-void celix_map_putUint32(celix_map* map, const char* key, uint32_t value);
-
-int64_t celix_map_int64Value(const celix_map* map, const char* key, int64_t defaultValue);
-void celix_map_putInt64(celix_map* map, const char* key, int64_t value);
-
-uint64_t celix_map_uint64Value(const celix_map* map, const char* key, uin64_t defaultValue);
-void celix_map_putUint64(celix_map* map, const char* key, uint64_t value);
-
-float celix_map_floatValue(const celix_map* map, const char* key, float defaultValue);
-void celix_map_putFloat(celix_map* map, const char* key, float value);
-
-double celix_map_doubleValue(const celix_map* map, const char* key, double defaultValue);
-void celix_map_putDouble(celix_map* map, const char* key, double value);
-
-//celix/utils/properties.h
-
-/**
- * The celix properties can store string values under a string keys.
- * Properties can be created from properties files (see https://en.wikipedia.org/wiki/.properties)
- *
- * The properties API is not thread safe.
- */
-
-#include <stdbool.h> //bool
-#include <stdio.h> //FILE
-
-typedef struct celix_properties celix_properties;
-
-typedef struct celix_properties_entry {
-    const char* key;
-    const char* value;
-} celix_properties_entry;
-
-/**
- * Creates a properties object
- */
-celix_properties* celix_properties_create(void);
-
-/**
- * Creates a properties object from the provided properties file.
- * Returns NULL if the properties file is invalid.
- */
-celix_properties* celix_properties_createFromFile(FILE* file);
-
-/**
- * Creates a properties object from the provided properties formatted string
- * Returns NULL if the content is invalid.
- */
-celix_properties* celix_properties_createFromContent(const char* content);
-
-/**
- * Copies (deep copy) a properties object
- */
-celix_properties* celix_properties_copy(const celix_properties* properties);
-
-/**
- * Destroy a properties object. Also frees the keys and values
- */
-void celix_properties_destroy(celix_properties* props);
-
-/**
- * Returns an array of keys. The properties is still owner of this array.
- * @param map The celix properties
- * @param len If not NULL will be set to the size of the map.
- * @return If len is NULL this returns NULL, else a array of the keys.
- */
-const char* celix_properties_keys(const celix_properties* props, size_t* len);
-
-/**
- * Returns an array of entries. The properties is still owner of this array.
- * @param map The celix properties
- * @param len If not NULL will be set to the size of the map.
- * @return If len is NULL this returns NULL, else a array of the entries.
- */
-const celix_properties_entry* celix_properties_entries(const celix_properties* props, size_t* len);
-
-/**
- * Returns the nr of properties of the properties object.
- */
-size_t celix_properties_size(const celix_properties* props);
-
-/**
- * Returns whether the properties has an entry with the provided key
- */
-bool celix_properties_hasKey(const celix_properties* props, const char* key);
-
-/**
- * Returns the property value for the provided key.
- * Returns the defaultValue is there is no entry for the provided key.
- */
-const char* celix_properties_property(const celix_properties* props, const char* key, const char* defaultValue);
-
-/**
- * Set the property for the provided key/value. Creating a copy of the key and value.
- * If there was already a property with the same key, the previous value will be replaced and freed.
- */
-void celix_properties_setProperty(celix_properties* props, const char* key, const char* value);
-
-
-
-//celix/types.h
-
-//Opaque types. struct are defined in source files or non public header files
-typedef struct celix_framework celix_framework;
-typedef struct celix_bundle celix_bundle;
-typedef struct celix_module celix_module;
-typedef struct celix_dependency_manager celix_dependency_manager;
-typedef struct celix_component celix_component;
-typedef struct celix_service_dependency celix_service_dependency;
-
-//TODO, discuss create typedef per id type?
-//typedef uint64_t celix_framework_id;
-//typedef uint64_t celix_bundle_id;
-//typedef uint64_t celix_module_id;
-//typedef uint64_t celix_service_id;
-//typedef uint64_t celix_service_factor_id;
-//typedef uint64_t celix_service_tracker_id;
-//typedef uint64_t celix_service_tracker_listener_id;
-//typedef uint64_t celix_component_id;
-
-//service factory function pointers
-typedef struct celix_service_factory {
-    void* handle;
-    int (*getService)(void* handle, const celix_module* mod, void** svc /*out*/);
-    int (*ungetService)(void* handle, const celix_module* mod, void* svc);
-} celix_service_factory;
-
-//Opaque type which should be defined by users
-typedef struct celix_module_context celix_module_context;
-
-//celix/framework.h
-/**
- * The Framework API can be used to control the lifecycle the framework,
- * retrieve started frameworks.
- */
-
-
-/**
- * Creates a new Celix framework.
- * Note that this function will block if an framework is created, started, stopped or destroyed.
- *
- * The framework will take ownership of the provided properties.
- *
- * @param config The framework configuration. Will also be provided to the modules
- * @return a ptr to the new framework is successful or NULL.
- */
-celix_framework* celix_framework_create(celix_properties* config, celix_framwork_t** out);
-
-/**
- * Starts the provided Celix framework
- * Note that this function will block if an framework is created, started, stopped or destroyed.
- * @return 0 if successful
- */
-int celix_framework_start(celix_framework* fw);
-
-/**
- * Stops the provided Celix framework
- * Note that this function will block if an other framework is created, started, stopped or destroyed.
- * @return 0 if successful
- */
-int celix_framework_stop(celix_framework* fw);
-
-/**
- * Destroys the provided Celix framework
- * Note that this function will block if an other framework is created, started, stopped or destroyed.
- * @return 0 if successful
- */
-int celix_framework_destroy(celix_framework* fw);
-
-/**
- * Blocks until the provided framework is stopped.
- * @return 0 if successful, 1 if interrupted, < 0 if error
- */
-int celix_framework_waitForStop(celix_framework* fw);
-
-/**
- * Returns the id of the framework. This id is unique within a single process
- */
-uint64_t celix_framework_id(const celix_framework* fw);
-
-/**
- * Returns the uuid of the framework. This uuid is global unique.
- */
-const char* celix_framework_uuid(const celix_framework* fw);
-
-/**
- * Returns the framework modules for the provided framework (e.g. module 1, name framework)
- */
-celix_module* celix_framework_module(const framework* fw);
-
-/**
- * Returns the framework ids for this process.
- * @param arr The array to store the ids
- * @param arrSize The available size of the provided arr
- * @return the actual number ids added to the array
- */
-size_t celix_frameworkIds(void, uint64_t* arr, size_t arrSize);
-
-/**
- * Returns the framework for the provided id or NULL if the framework id is invalid.
- */
-celix_framework* celix_framework(uint64_t frameworkId);
-
-
-
-//celix/bundle.h
-
-/**
- * Returns the framework which owns the bundle
- */
-celix_framework* celix_bundle_framework(const celix_bundle* bundle);
-
-/**
- * Returns the id of te bundle
- */
-uint64_t celix_bundle_id(const celix_bundle* bundle);
-
-/**
- * Returns the module of the bundle.
- */
-celix_module* celix_bundle_module(const celix_bundle* bundle);
-
-
-
-//celix/module.h
-
-
-//NOTE dyn_intefaces renamed to dfi_interface and extended with dfi_interface_isCompatible(provider, consumer) function
-#include "dfi/interface.h"
-
-//NOTE dyn_message renamed to dfi_message and extended with dfi_message_isCompatible(provider, consumer) function
-#include "dfi/message.h"
-
-/**
- * The module can be used to register/unregister services, create service trackers,
- * add service tracker listeners, register/unregister service factories, get module resources,
- * store and get files from the module store  and retrieve the module's dependency manager.
- *
- * The module API is thread safe
- */
-
-typedef enum celix_module_state {
-    CELIX_MODULE_STATE_UNKNOWN      = 0,
-    CELIX_MODULE_STATE_INSTALLED    = 1,
-    CELIX_MODULE_STATE_RESOLVED     = 2,
-    CELIX_MODULE_STATE_STARTING     = 3,
-    CELIX_MODULE_STATE_ACTIVE       = 4,
-    CELIX_MODULE_STATE_STOPPING     = 5
-} celix_module_state;
-
-/**
- * Returns the module id
- */
-uint64_t celix_module_id(const celix_module* mod);
-
-/**
- * Returns the celix framwork which owns the module
- */
-celix_framework* celix_module_framework(const celix_module* mod);
-
-/**
- * Returns the state of the module.
- */
-celix_module_state celix_module_state(const celix_module* mod);
-
-
-/**
- * Returns the Manifest info in the form of properties (key,value)
- */
-const celix_properties* celix_module_manifest(const celix_module* mod);
-
-/**
- * Returns the bundle for this module.
- * @param mod The module
- * @return The bundle or NULL if the module has no bundle (i.e. a library module)
- */
-celix_bundle* celix_module_bundle(const celix_module* mod);
-
-/**
- * Set the module context. The module context is a user defined struct that can be used to store user specific data.
- * The module only stores the pointer. A module implementer is still responsible to free the module_context.
- *
- * @param mod The module
- * @param ctx The module context
- */
-void celix_module_setContext(celix_module* mod, celix_module_context* ctx);
-
-/**
- * Returns the module context or NULL if the module context is not set.
- */
-celix_module_context* celix_module_getContext(const celix_module* mod);
-
-/**
- * Returns the module name.
- */
-const char* celix_module_name(const celix_module* mod);
-
-/**
- * Returns the module version. in for format of
- * <major>.<minor>.<micro>-<qualifier>
- * @param mod The module
- * @param major If not NULL, will be set the the major version part.
- * @param minor If not NULL, will be set the the minor version part.
- * @param micro If not NULL, will be set the the micro version part.
- * @param qualifier If not NULL, will be set the the qualifier version part.
- * @return The complete version string
- */
-const char* celix_module_version(const celix_module* mod, const char** major /*out*/, const char** minor /*out*/, const char** micro /*out*/, const char** qualifier /*out*/);
-
-/**
- * Returns the property using the framework properties and env variables.
- *
- * If a property is present in the framework properties (config.properties) this will be returned,
- * else a the framework will try to lookup an environment variable for the provided key.
- * If there is no property nor environment variable for the provided key, the defaultValue will be returned.
- *
- * @param mod The module
- * @param name The property name
- * @param defaultValue The default value to use if the property is not set
- * @return The property value or the defaultValue if the property is not set.
- */
-const char* celix_module_property(const celix_module* mod, const char* name, const char* defaultValue); //get properties from config.properties and falling back to environment variables
-
-/**
- * Register service for the provide module for the C language.
- * If properties are provided the framework will take ownership.
- *
- * @param mod The module owning the service
- * @param serviceName The service name
- * @param svcVersion The service version. NULL will log a warning
- * @param svc The service
- * @param properties Optional properties containing the meta data of the service
- * @return 0 if unsuccessful else the service id
- */
-uint64_t celix_module_registerService(celix_module* mod, const char* serviceName, const char* svcVersion, void* svc, celix_properties* properties);
-
-/**
- * 'type safe' version of the celix_module_registerservice function.
- * Which takes as second argument the service type.
- */
-#define CELIX_MODULE_REGISTER_SERVICE(mod, svcType, svcVersion, svc, properties) \
-    do { \
-        (svcType) tmptype = (svc); \
-        const char* svcname = ##svcType; \
-        celix_module_registerService(mod, svcname, (svcVersion), (void*)tmptype, (properties)); \
-    } while(0)
-
-/**
- * Register service for the provide module for the provided language.
- * If properties are provided the framework will take ownership.
- *
- * @param mod The module owning the service
- * @param serviceName The service name
- * @param svcVersion The service version. NULL will log a warning
- * @param lang The service language. If NULL 'unspecified' will be used and warning will be logged
- * @param svc The service
- * @param properties Optional properties containing the meta data of the service
- * @return 0 if unsuccessful else the service id
- */
-uint64_t celix_module_registerServiceForLang(celix_module* mod, const char* serviceName, const char* svcVersion, const char* lang, void*svc, celix_properties* properties);
-
-/**
- * 'type safe' version of the celix_module_registerServiceForLang function.
- * Which takes as second argument the service type. The type is also used to infer the service name
- */
-#define CELIX_MODULE_REGISTER_SERVICE_FOR_LANG(mod, svcType, svcVersion, lang, svc, properties) \
-    do { \
-        svcType* tmptype = (svc); \
-        const char* tmpname = #svcType; \
-        celix_module_registerServiceForLang(mod, tmpname, (svcVersion), (lang), (void*)tmptype, (properties)); \
-    } while(0)
-
-/**
- * Unregister the service corresponding to the service id for the provided module.
- * Will log an error if the service id is not valid or not owned by the module
- *
- * @param mod The module
- * @param svcId The service id
- */
-void celix_module_unregisterService(celix_module* mod, uint64_t svcId);
-
-/**
- * Register service factory for the provide module for the C language.
- * If properties are provided the framework will take ownership.
- *
- * @param mod The module owning the service factory
- * @param serviceName The service name
- * @param serviceVersion The service version. NULL will log a warning
- * @param factory The service factory
- * @param properties Optional properties containing the meta data of the service
- * @return 0 if unsuccessful else the service factory id.
- */
-uint64_t celix_module_registerServiceFactory(
-        celix_module* mod,
-        const char* serviceName,
-        const char* serviceVersion,
-        celix_service_factory factory,
-        celix_properties* properties);
-
-/**
- * Register service factory for the provide module for the C language.
- * If properties are provided the framework will take ownership.
- *
- * @param mod The module owning the service factory
- * @param serviceName The service name
- * @param serviceVersion The service version. NULL will log a warning
- * @param lang The service language. If NULL 'unspecified' will be used and warning will be logged
- * @param factory The service factory
- * @param properties Optional properties containing the meta data of the service
- * @return 0 if unsuccessful else the service factory id.
- */
-uint64_t celix_module_registerServiceFactoryForLang(
-        celix_module* mod,
-        const char* serviceName,
-        const char* serviceVersion,
-        const char* lang,
-        celix_service_factory factory,
-        celix_properties* properties);
-
-/**
- * Unregister the service factory corresponding to the service factory id for the provided module.
- * Will log an error if the service factory id is not valid or not owned by the module
- *
- * @param mod The module
- * @param factoryId The service factory id
- */
-void celix_module_unregisterServiceFactory(celix_module* mod, uint64_t factoryId);
-
-//service tracker callback function types
-
-typedef int (*celix_serviceTracker_onSettingHighestRankingService_fp)(void* data, void* svc);
-typedef int (*celix_serviceTracker_onAddingService_fp)(void* data, void* svc);
-typedef int (*celix_serviceTracker_onRemovingService_fp)(void* data, void* svc);
-
-typedef int (*celix_serviceTracker_onSettingHighestRankingServiceWithProperties_fp)(void* data, void* svc, const celix_properties* properties);
-typedef int (*celix_serviceTracker_onAddingServiceWithProperties_fp)(void* data, void* svc, const elix_properties* properties);
-typedef int (*celix_serviceTracker_onRemovingServiceWithProperties_fp)(void* data, void* svc, const celix_properties* properties);
-
-/**
- * Callbacks wich also provides the owner module as argument. The module is guaranteed to exist during the callback,
- * but should not be stored for later use. The module can be used for extender pattern functionality.
- */
-typedef int (*celix_serviceTracker_onSettingHighestRankingServiceWithModule_fp)(void* data, void* svc, const celix_properties* properties, const celix_module* owner);
-typedef int (*celix_serviceTracker_onAddingServiceWithModule_fp)(void* data, void* svc, const celix_properties* properties, const celix_module* owner);
-typedef int (*celix_serviceTracker_onRemovingServiceWithModule_fp)(void* data, void* svc, const celix_properties* properties, const celix_module* owner);
-
-
-/**
- * track services for the provided serviceName and/or filter.
- *
- * @param mod The module which will be tracking for the services
- * @param serviceName Optional the service name to tracke
- * @param serviceVersionRange Optional the service version range to track
- * @param filter Optional the LDAP filter to use
- * @param data The data pointer, which will be used in the callbacks
- * @param onSettingFp The callback, which will be called when a new highest ranking service is set.
- * @return the tracker id or 0 if unsuccessful.
- */
-uint64_t celix_module_trackService(
-        celix_module* mod,
-        const char* serviceName,
-        const char* serviceVersionRange,
-        const char* filter,
-        void* data,
-        celix_serviceTracker_onSettingHighestRankingService_fp onSettingFp);
-
-/**
- * track services for the provided serviceName and/or filter.
- *
- * @param mod The module which will be tracking for the services
- * @param serviceName Optional the service name to tracke
- * @param serviceVersionRange Optional the service version range to track
- * @param filter Optional the LDAP filter to use
- * @param data The data pointer, which will be used in the callbacks
- * @param onAddingFp The callback, which will be called when service is added.
- * @param onRemovingFp The callback, which will be called when a service is removed
- * @return the tracker id or 0 if unsuccessful.
- */
-uint64_t celix_module_trackServices(
-        celix_module* mod,
-        const char* serviceName,
-        const char* serviceVersionRange,
-        const char* filter,
-        void* data,
-        celix_serviceTracker_onAddingService_fp onAddingFp,
-        celix_serviceTracker_onRemovingService_fp onRemovingFp);
-
-/**
- * The service tracker options.
- * This struct can be used to configure a more detailed service tracker.
- *
- * This includes service callbacks with properties/module arguments and settings pointers which will be used to
- * lock, set a service, set service properties and set the svcId.
- *
- * All field are optional, and any combination can be used.
- *
- */
-typedef struct celix_service_tracker_options {
-    //service filter options
-    const char* serviceName;
-    const char* serviceVersionRange;
-    const char* filter;
-    const char* lang; //NULL -> 'CELIX_LANG_C'
-
-    //callback options
-    void* data;
-
-    celix_serviceTracker_onSettingHighestRankingService_fp onSettingFp;
-    celix_serviceTracker_onAddingService_fp onAddingFp;
-    celix_serviceTracker_onRemovingService_fp onRemovingFp;
-
-    celix_serviceTracker_onSettingHighestRankingServiceWithProperties_fp onSettingWithProperties;
-    celix_serviceTracker_onAddingServiceWithProperties_fp onAddingWithProperties;
-    celix_serviceTracker_onRemovingServiceWithProperties_fp onRemovingWithProperties;
-
-    celix_serviceTracker_onSettingHighestRankingServiceWithModule_fp onSettingWithModule;
-    celix_serviceTracker_onAddingServiceWithModule_fp onAddingWithModule;
-    celix_serviceTracker_onRemovingServiceWithModule_fp onRemovingWithModule;
-
-    //field options
-    pthread_mutex_t* svcMutex;
-    void** svcField;
-    const properties** propertiesField;
-    uint64_t* svcIdField;
-} celix_service_tracker_options;
-
-//shortcut could be const celix_service_tracker_options opts = {0};
-const celix_service_tracker_options CELIX_DEFAULT_SERVICE_TRACKER_OPTIONS {
-        .serviceName = NULL,
-        .serviceVersionRange = NULL,
-        .filter = NULL,
-        .lang = NULL,
-
-        .data = NULL,
-
-        .onSettingFp = NULL,
-        .onAddingFp = NULL,
-        .onRemovingFp = NULL,
-
-        .onSettingWithProperties = NULL,
-        .onAddingWithProperties = NULL,
-        .onRemovingWithProperties = NULL,
-
-        .onSettingWithModule = NULL,
-        .onAddingWithModule = NULL,
-        .onRemovingWithModule = NULL,
-
-        .svcMutex = NULL,
-        .svcField = NULL,
-        .propertiesField = NULL,
-        .svcIdField = NULL
-};
-
-/**
- * Tracks services using the provided tracker options.
- * The tracker options are only using during this call.
- *
- * @param mod The module which will be tracking for the services.
- * @param opts The tracker options.
- * @return the tracker id or 0 if unsuccessful.
- */
-uint64_t celix_module_trackServicesWithOptions(celix_module* mod, const celix_service_tracker_options* opts);
-
-/**
- * Get and lock the current highest ranking service tracker by the provided tracker Id.
- * Note that this also locks the removal of the retrieved service. So if the returned svc
- * is not NULL this should be followed with a celix_module_trackerUngetAndUnlockService call.
- *
- * @param mod The module
- * @param trackerId the id of the tracker to use
- * @return the highest ranking service or NULL if no service is available.
- */
-void* celix_module_trackerGetAndLockService(celix_module* mod, uint64_t trackerId);
-
-/**
- * Ungets and unlock the retrieved service.
- * Logs an error if provided module, trackerId, svc or the combination is not valid.
- *
- * @param mod the module
- * @param trackerId the id of the tracker to use
- * @svc the service to unget and unlock
- */
-void celix_module_trackerUngetAndUnlockService(celix_module* mod, uint64_t trackerId, void* svc);
-
-/**
- * Get and lock all the currently tracked services.
- * Note that this also locks the removal of the retrieved services. So if the returned services
- * size is not 0, this should be followed with a celix_module_trackerUngetAndUnlockServices call.
- *
- * @param mod The module
- * @param trackerId the id of the tracker to use
- * @param services A array of service pointers to populate
- * @param servicesSize the size of the provided services array
- * @return Number of services added to the services array.
- */
-size_t celix_module_trackerGetAndLockServices(celix_module* mod, uint64_t trackerId, void** services, size_t servicesSize);
-
-/**
- * Ungets and unlock the retrieved service
- * Logs an error if provided module, trackerId, services or the combination is not valid.
- *
- * @param mod the module
- * @param trackerId the id of the tracker to use
- * @services the services to unget and unlock
- * @servicesSize the size of the services array
- */
-void celix_module_trackerUngetAndUnlockServices(celix_module* mod, uint64_t trackerId, void** services, size_t servicesSize);
-
-
-/**
- * Stops the tracker and free it's resources.
- * Logs an error in the module, trackerId or combination is not valid.
- *
- * @param mod The module owning the tracker
- * @param trackerId The tracker id
- */
-void celix_module_stopTracker(celix_module* mod, uint64_t trackerId);
-
-
-//service tracker listener callback struct / function types
-
-typedef struct celix_service_tracker_listener_tracker_info {
-    uint64_t trackerId;
-    const celix_module* owner;
-    const char* serviceName;
-    const char* filter;
-    const char* versionRange;
-    const char* lang;
-} celix_service_tracker_listener_tracker_info;
-
-/**
- * Callback for handling tracker adding event. The trackerInfo provided is guaranteed to exists and to be valid
- * during the execution of the callback. Note that the provided module pointer should not be stored outside the
- * callback.
- */
-typedef int (*celix_serviceTrackerListener_onTrackerAdding_fp)(void* data, const celix_service_tracker_listener_tracker_info* trackerInfo);
-
-/**
- * Callback for handling tracker removing event. The trackerInfo provided is guaranteed to exists and to be valid
- * during the execution of the callback. Note that the provided module pointer should not be stored outside the
- * callback.
- */
-typedef int (*celix_serviceTrackerListener_onTrackerRemoving_fp)(void* data, const celix_service_tracker_listener_tracker_info* trackerInfo);
-
-/**
- * Listen for service trackers for the C language.
- * @param mod The module owner of the tracker listener.
- * @param serviceName Optional, only listen to trackers for the specified service name.
- * @param data The data using the in the callbacks.
- * @param onAddingFp The onAdding callbacks.
- * @param onRemovingFp The onRemoving callbacks.
- * @return the service tracker listener id or 0 if unsuccessful.
- */
-uint64_t celix_module_listenForTrackers(
-        celix_module* mod,
-        const char* serviceName,
-        void* data,
-        celix_serviceTrackerListener_onTrackerAdding_fp onAddingFp,
-        celix_serviceTrackerListener_onTrackerRemoving_fp onRemovingFp);
-
-/**
- * Listen for service trackers for the specified language.
- * @param mod The module owner of the tracker listener.
- * @param serviceName Optional, only listen to trackers for the specified service name.
- * @param lang Optional, only listen to trackers for the specified language.
- * @param data The data using the in the callbacks.
- * @param onAddingFp The onAdding callbacks.
- * @param onRemovingFp The onRemoving callbacks.
- * @return the service tracker listener id or 0 if unsuccessful.
- */
-uint64_t celix_module_listenForTrackerForLang(
-        celix_module* mod,
-        const char* serviceName,
-        const char* lang,
-        void* data,
-        celix_serviceTrackerListener_onTrackerAdding_fp onAddingFp,
-        celix_serviceTrackerListener_onTrackerRemoving_fp onRemovingFp);
-
-/**
- * Stops the service tracker listener and free it's resources.
- * @param mod The module owning the service tracker listener
- * @param trackerListenerId The id
- */
-void celix_module_stopTrackerListener(celix_module* mod, uint64_t trackerListenerId);
-
-/**
- * Lookup and return a pointer to the requested symbol.
- * @param mod The module (library) to use for symbol lookup
- * @param symbol The symbol name
- * @return pointer to the symbol or NULL if unsuccessful.
- */
-void* celix_module_sym(celix_module* mod, const char* symbol);
-
-#ifndef CELIX_USE_DFI
-#define CELIX_USE_DFI 1
-#endif
-
-#if CELIX_USE_DFI == 1
-
-/**
- * Returns the dfi_interface for the provided interface name or
- * NULL if there is no dfi_interface for the provided service name
- * (i.e. no descriptor for the service name in the module resources).
- */
-const dfi_interface* celix_module_dfiInterface(const celix_module* mod, const char* serviceName);
-
-/**
- * Returns the dfi_message for the provided message type or
- * NULL if there is no dfi_message for the provided message type
- * (i.e. no descriptor for the message type in the module resources).
- */
-const dfi_message* celix_module_dfiInterface(const celix_module* mod, const char* messageType);
-
-#endif
-
-/**
- * Returns a resource entry or NULL if the resource entry cannot be found.
- *
- * Note that resource entries only present as long as the module is installed. So handling module resource
- * entries should only be done by the module self or in callbacks that guarantees that the module is valid during the
- * callback.
- */
-FILE* celix_module_resourceEntry(celix_module* mod, const char* path);
-
-/**
- * Store a file in the module store. These files are persistent and can be reused when the framework is restarted.
- * @param mod The module.
- * @param path Relative path to save the entry.
- * @param input The input file which will be copied to the store.
- * @return returns 0 if successful.
- */
-int celix_module_storePutFile(celix_module* mod, const char* path, FILE* input);
-
-/**
- * Store content as file in the module store.
- * These files are persistent and can be reused when the framework is restarted.
- * @param mod The module.
- * @param path Relative path to save the entry.
- * @param buf The content to store.
- * @param bufSize the size of the content.
- * @return returns 0 if successful.
- */
-int celix_module_storePutContent(celix_module* mod, const char* path, char* buf, size_t bufSize);
-
-/**
- * Returns an store entry as FILE or NULL if the entry cannot be found.
- * Caller should close the returned file.
- */
-FILE* celix_module_storeEntry(celix_module* mod, const char* path);
-
-/**
- * Returns the celix_dependency_manager.
- */
-celix_dependency_manager_t* celix_module_manager(const celix_module* mod);
-
-//celix/dependency_manager.h
-
-celix_component* celix_dependencyManager_addComponent(celix_dependency_manager* dm, const char* name);
-void celix_dependencyManager_removeComponent(celix_dependency_manager* man, celix_component* cmp);
-
-celix_module* celix_dependencyManager_module(const celix_dependency_manager* mng);
-
-//celix/component.h
-
-typedef enum celix_component_state {
-    CELIX_COMPONENT_STATE_UNKNOWN                           = 0,
-    CELIX_COMPONENT_STATE_INACTIVE                          = 1,
-    CELIX_COMPONENT_WAITING_FOR_REQUIRED                    = 2,
-    CELIX_COMPONENT_INSTANTIATED_AND_WAITING_FOR_REQUIRED   = 3,
-    CELIX_COMPONENT_TRACKING_OPTIONAL                       = 4,
-} celix_component_state;
-
-typedef int (*celix_component_lifecycleCallback_fp)(void *handle);
-
-/**
- * Returns the component id or 0 if the
- * provided cmp is invalid.
- */
-uint64_t celix_component_id(const celix_component* cmp);
-
-
-/**
- * Adds a C interface to provide as service if the component is active.
- *
- * @param cmp The component providing th service
- * @param the svc
- * @param serviceName the service name.
- * @param serviceVersion The version of the interface (e.g. "1.0.0"), Can be a NULL pointer.
- * @param properties To (meta) properties to provide with the service. Can be a NULL pointer.
- * @returns 0 if successful
- */
-int celix_component_addInterface(
-        celix_component* cmp,
-        void* svc,
-        const char* serviceName,
-        const char* serviceVersion,
-        void* service,
-        celix_properties* properties);
-
-/**
- * Adds a C interface to provide as service if the component is active.
- *
- * @param cmp The component providing the service
- * @param lang The language of the service (or C if NULL)
- * @param the svc
- * @param serviceName the service name.
- * @param serviceVersion The version of the interface (e.g. "1.0.0"), Can be a NULL pointer.
- * @param properties To (meta) properties to provide with the service. Can be a NULL pointer.
- * @returns 0 if successful
- */
-int celix_component_addInterfaceForLang(
-        celix_component* cmp,
-        const char* lang,
-        void* svc,
-        const char* serviceName,
-        const char* serviceVersion,
-        void* service,
-        celix_properties properties);
-
-/**
- * Adds a C service factory to provide as service if the component is active.
- *
- * @param cmp The component providing the service factory
- * @param the svc
- * @param serviceName the service name.
- * @param serviceVersion The version of the interface (e.g. "1.0.0"), Can be a NULL pointer.
- * @param factory The service factory
- * @param properties To (meta) properties to provide with the service. Can be a NULL pointer.
- * @returns 0 if successful
- */
-int celix_component_addFactory(
-        celix_component* cmp,
-        const char* serviceName,
-        const char* serviceVersion,
-        celix_service_factory factory,
-        celix_properties properties);
-
-/**
- * Adds a C service factory to provide as service if the component is active.
- *
- * @param cmp The component providing the service factory
- * @param lang The language of the service (or C if NULL)
- * @param the svc
- * @param serviceName the service name.
- * @param serviceVersion The version of the interface (e.g. "1.0.0"), Can be a NULL pointer.
- * @param factory The service factory
- * @param properties To (meta) properties to provide with the service. Can be a NULL pointer.
- * @returns 0 if successful
- */
-int celix_component_addFactoryForLang(
-        celix_component* cmp,
-        const char* lang,
-        const char* serviceName,
-        const char* serviceVersion,
-        celix_service_factory factory,
-        celix_properties properties);
-
-
-/**
- * Set the component context (e.g. user defined data)
- * @param cmp The component
- * @param ctx  The context
- * @return 0 if successful
- */
-int celix_component_setContext(celix_component* cmp, celix_component_context* ctx);
-
-/**
- * Returns the conponent context. Note that default this is NULL
- * @param cmp The component
- * @return component context or NULL if not successful
- */
-celix_component_context* celix_component_context(const celix_component* cmp);
-
-/**
- * creates and adds a service dependency for the provided component
- * @param component The component which should be the owner of the service dependency
- * @return The service dependency if sucessful else NULL
- */
-celix_service_dependency* celix_component_createServiceDependency(celix_component* cmp);
-
-/**
- * Removes and destroys the provided service dependency
- * @param component The owner of the service dependency
- * @return 0 if successful
- */
-int celix_component_destroyServiceDependency(celix_component* cmp, celix_service_dependency* dep);
-
-/**
- * Returns the current state of the component
- */
-celix_component_state celix_component_currentState(const celix_component* cmp);
-
-
-/**
- * Returns the DM component name.
- */
-const char * celix_component_name(const celix_component* cmp);
-
-/**
- * Returns the dependency manager (owner) of the component
- */
-celix_dependency_manager* component_manager(const celix_component* component);
-
-/**
- * Set the component init life cycle callbacks.
- * @param cmp The component which control the lifecycle
- * @param handle The handle used in the callback
- * @param init The callback
- * @return 0 if successful
- */
-int celix_component_setInitCallback(celix_component* cmp, void* handle,  celix_component_lifecycleCallback_fp init);
-
-/**
- * Set the component start life cycle callbacks.
- * @param cmp The component which control the lifecycle
- * @param handle The handle used in the callback
- * @param init The callback
- * @return 0 if successful
- */
-int celix_component_setStartCallback(celix_component* cmp, void* handle,  celix_component_lifecycleCallback_fp start);
-
-/**
- * Set the component stop life cycle callbacks.
- * @param cmp The component which control the lifecycle
- * @param handle The handle used in the callback
- * @param init The callback
- * @return 0 if successful
- */
-int celix_component_setStopCallback(celix_component* cmp, void* handle,  celix_component_lifecycleCallback_fp stop);
-
-/**
- * Set the component deinit life cycle callbacks.
- * @param cmp The component which control the lifecycle
- * @param handle The handle used in the callback
- * @param init The callback
- * @return 0 if successful
- */
-int celix_component_setDeinitCallback(celix_component* cmp, void* handle,  celix_component_lifecycleCallback_fp deinit);
-
-/**
- * Set the component init life cycle callbacks macro, sets the callback 'safely'
- */
-#define CELIX_COMPONENT_SET_INIT_CALLBACK(cmp, type, handle, fp) \
-    do { \
-        type* tmptype = (handle); \
-        int (*tmp_fp)(type*) = (tmpfp); \
-        celix_component_setInitCallback((cmp), (void*)tmptype, (celix_component_lifecycleCallback_fp)tmpfp); \
-    } while(0)
-
-
-/**
- * Set the component start life cycle callbacks macro, sets the callback 'safely'
- */
-#define CELIX_COMPONENT_SET_START_CALLBACK(cmp, type, handle, fp) \
-    do { \
-        type* tmptype = (handle); \
-        int (*tmp_fp)(type*) = (tmpfp); \
-        celix_component_setStartCallback((cmp), (void*)tmptype, (celix_component_lifecycleCallback_fp)tmpfp); \
-    } while(0)
-
-/**
- * Set the component stop life cycle callbacks macro, sets the callback 'safely'
- */
-#define CELIX_COMPONENT_SET_STOP_CALLBACK(cmp, type, handle, fp) \
-    do { \
-        type* tmptype = (handle); \
-        int (*tmp_fp)(type*) = (tmpfp); \
-        celix_component_setStopCallback((cmp), (void*)tmptype, (celix_component_lifecycleCallback_fp)tmpfp); \
-    } while(0)
-
-/**
- * Set the component deinit life cycle callbacks macro, sets the callback 'safely'
- */
-#define CELIX_COMPONENT_SET_DEINIT_CALLBACK(cmp, type, handle, fp) \
-    do { \
-        type* tmptype = (handle); \
-        int (*tmp_fp)(type*) = (tmpfp); \
-        celix_component_setDeinitCallback((cmp), (void*)tmptype, (celix_component_lifecycleCallback_fp)tmpfp); \
-    } while(0)
-
-
-
-
-
-
-//celix/service_dependency.h
-
-typedef enum celix_service_dependency_strategy {
-    celix_SERVICE_DEPENDENCY_STRATEGY_LOCKING,
-    celix_SERVICE_DEPENDENCY_STRATEGY_SUSPEND
-} celix_service_dependency_strategy;
-
-typedef int (*celix_service_dependency_callback_fp)(void *handle, void* service);
-typedef int (*celix_service_dependency_callbackWithProperties_fp)(void *handle, void* service, celix_properties* properties);
-
-/**
- * Specify if the service dependency is required. default is false
- * @returns 0 if successful
- */
-int celix_serviceDependency_setRequired(celix_service_dependency* dep, bool required);
-
-/**
- * Specify if the service dependency update strategy.
- *
- * The CELIX_SERVICE_DEPENDENCY_STRATEGY_LOCKING strategy notifies the component in case the dependencies set
- * changes (e.g. a dependency is added/removed): the component is responsible for protecting via locks
- * the dependencies list and check (always under lock) if the service he's depending on is still available.
- *
- * The CELIX_SERVICE_DEPENDENCY_STRATEGY_SUSPEND (default when no strategy is explicitly set) reliefs the programmer
- * from dealing with service dependencies' consistency issues: in case this strategy is adopted, the component
- * is stopped and restarted (i.e. temporarily suspended) upon service dependencies' changes.
- *
- * Default strategy is celix_SERVICE_DEPENDENCY_STRATEGY_SUSPEND
- * @returns 0 if successful
- */
-int serviceDependency_setStrategy(celix_service_dependency* dep ,celix_service_dependency_strategy strategy);
-
-
-/**
- * Set the service name, version range and filter.
- *
- * @param serviceName The service name. Must have a value.
- * @param serviceVersionRange The service version range, can be a NULL pointer.
- * @param filter The (additional) filter to use (e.g. "(location=front)"). Can be a NULL pointer.
- * @returns 0 if successful
- */
-int celix_serviceDependency_setService(celix_service_dependency* dep, const char* serviceName, const char* serviceVersionRange, const char* filter);
-
-/**
- * Sets the 'set' callbacks. This callback is called when a new service is set/removed.
- * If the service is removed the service argument is NULL.
- *
- * @param dep The service dependency which control the callbacks
- * @param handle The handle to provide for the use in the callbacks
- * @param set An optional set callback with only the service as argument
- * @param setWithProps An optional set callback with a service and properties as arguments.
- * @returns 0 if successful
- */
-int celix_serviceDependency_setSetCallback(
-        celix_service_dependency* dep,
-        void* handle,
-        celix_service_dependency_callback_fp onSetting,
-        celix_service_dependency_callbackWithProperties_fp onSettingWithProps);
-
-//TODO onAdding, onRemoving callbacks
-
-#define CELIX_SERVICE_DEPENDENCY_SET_SET_CALLBACK(dep, handleType, handle, svcType, fp, fpWithProps) \
-	do { \
-        (handleType)* tmptype = handle; \
-        int (*tmpFp)((handleType)*, (svcType)*) = fp; \
-        int (*tmpFpWithProps)((handleType)*, (svcType)*, celix_properties*) = fpWithProps; \
-		celix_serviceDependency_setSetCallbacks((dep), (void*)tmptype, (celix_service_dependency_callback_fp)fp, (celix_service_dependency_callbackWithProperties_fp)fpWithProps); \
-	} while(0)
-
-//TODO onAdding, onRemoving callback macros
-
-
-
-
-
-//celix/module_activator.h AND celix/module_registration.h
-
-/**
- * For module activation there are two options: the module activator or module registration. Both with their pro and cons.
- * For static module libraries on the the module registration is supported.
- *
- * Options:
- * 1) For the module registration the gcc (also clang supported) constructor (and optional destructor) attributes are
- *    used to call the moduleRegistration functions.
- *
- * 2) If a gcc constructor attribute is not supported for the platform, a set of module activator functions
- *    provided by the module_activator.h header can be implemented.
- *    Implementing this header will result in a set of symbols the framework can use to activate the module.
- *
- * 3) Use the celix_moduleRegistration_registerModule function to register modules programmatically.
- *    For example in a main function.
- */
-
-//celix/module_registration.h
-
-#include <stdbool.h>
-
-typedef int (*celix_module_registration_startModule_fp)(celix_module* mod);
-typedef int (*celix_module_registration_stopModule_fp)(celix_module* mod);
-
-typedef struct celix_module_registration_options {
-    /**
-     * If provided the module registration will take ownership
-     * of the properties, set the moduleName and moduleVersion
-     * and uses it a the module manifest
-     */
-    celix_properties* manifest;
-
-    /**
-     * If set to true the module will only be installed,
-     * not started automatically.
-     */
-    bool onlyInstall;
-} celix_module_registration_options;
-
-//shortcut could be celix_module_registration_options opts = {0};
-const celix_module_registration_options CELIX_DEFAULT_MODULE_REGISTRATION_OPTIONS {
-        .manifest = NULL,
-        .onlyInstall = false
-};
-
-/**
- * Registers the module for all current framework and future framework that are created.
- * If no name is provided, the module will not be registered and an error will be logged.
- *
- * When initializing the module, the framework will look for a <module_name>_resourceEntry and
- * <module_name>_resourceEntrySize symbol. If found, the content is assumed to be an embedded zip (or tar?) file.
- * the celix_modules_files CMake command will ensure that these symbols are created and linked to the module library.
- *
- * @param moduleName The name of the module.
- * @param moduleVersion Optional, the version of the module.
- * @startFp Optional the start function which will be called if the module is going to be added and ready to start.
- * @startFp Optional the stop function which will be called if the module going to be removed and ready to start.
- * @opts Optional the additional options. The options will only be used during the registerModule call.
- * @return 0 if successful
- */
-int celix_moduleRegistration_registerModule(
-        const char* moduleName,
-        const char* moduleVersion,
-        celix_module_registration_startModule_fp startFp,
-        celix_module_registration_stopModule_fp stopFp,
-        const celix_module_registration_options* opts);
-
-/* Start example for Option 1 =======================================================================================*/
-// my_module.c
-
-#include "celix/services.h" // celix_command_service
-#include <stdio.h> //fprintf
-
-struct celix_module_context {
-    //user specific
-    celix_command_service svc;
-    uint64_t svcId;
-    int defaultPort = 8080;
-};
-
-static int myModule_command(void *handle, char * commandLine, FILE *outStream, FILE *errorStream) {
-    fprintf(outStream, "Hello from MyModule\n");
-    return 0;
-}
-
-static int myModule_start(celix_module* mod) {
-    int status = 0;
-    celix_module_context* ctx = calloc(1, sizeof(*ctx));
-    if (ctx != NULL) {
-        celix_module_setContext(mod, ctx);
-        svc.handle = ctx; //Not used in this example
-        svc.executeCommand = myModule_command;
-        ctx->svcId = celix_module_registerService(mod, EXAMPLE_WEB_SERVICE_NAME, EXAMPLE_WEB_SERVICE_VERSION, &act->svc, NULL);
-    } else {
-        status = 1;
-    }
-    return status;
-}
-
-static int myModule_stop(celix_module* mod) {
-    int status = 0;
-    celix_module_context* ctx = celix_module_getContext(mod);
-    if (ctx != NULL) {
-        celix_module_unregisterService(mod, ctx->svcId);
-    }
-    return status;
-}
-
-/* NOTE: static function*/
-static void __attribute__((constructor)) myModule_ctor(void) {
-    celix_moduleRegistration_register(
-            "MyModule",
-            "1.0.0",
-            myModule_start,
-            myModule_stop,
-            NULL
-    );
-}
-/* End example for Option 1 =========================================================================================*/
-
-//celix/module_activator.h
-
-/**
- * When the Celix Framework loads modules as shared libraries or bundles, it will lookup the
- * celix_moduleActivator_start and celix_moduleActivator_stop symbols. If present these will be called
- * during starting and stopping the module.
- */
-
-/**
- * Will be called when a module is started.
- * @param mod The module
- * @return 0 if successful
- */
-int celix_moduleActivator_start(celix_module* mod);
-
-/**
- * Will be called when a module is stopped.
- * @param mod The module
- * @return 0 if successful
- */
-int celix_moduleActivator_stop(celix_module* mod);
-
-//celix/framework_services.h
-
-#include "celix/install_service.h"
-#include "celix/module_info_service.h"
-#include "celix/service_info_service.h"
-#include "celix/service_factory_info_service.h"
-#include "celix/service_tracker_info_service.h"
-#include "celix/service_tracker_listener_info_service.h"
-#include "celix/event_listener_service.h"
-
-/**
- * All framework provided services are using dynFunction_createClosure (ffi) to remove the need for a handle argument.
- */
-
-//celix/install_service.h
-
-typedef struct celix_install_service {
-    /**
-     * Install a module (shared lib) or bundle (zip)
-     * @param Path to a bundle file (ZIP) or shared library
-     * @return A module id or 0 if unsuccessful
-     */
-    uint64_t (*install)(const char* path);
-
-    /**
-     * Starts a module if not already started/starting
-     * @param moduleId The id of the module to start
-     * @return 0 if successful
-     */
-    int (*start)(uint64_t moduleId);
-
-    /**
-     * Stops a module if not already stopped/stopping
-     * @param moduleId The id of the module to stop
-     * @return 0 if successful
-     */
-    int (*stop)(uint64_t moduleId);
-
-    /**
-     * Uninstall a module and free it's resources
-     * @param moduleId The id of the module to uninstall
-     * @return 0 if successful
-     */
-    int (*uninstall)(uint64_t moduleId);
-
-    /**
-     * Returns the state of the module.
-     * If a module id is invalid CELIX_MODULE_STATE_UNKNOWN will be returned.
-     */
-    celix_module_state (*state)(uint64_t moduleId);
-} celix_install_service;
-
-
-
-
-//celix/module_info_service.h
-
-typedef struct celix_module_info_service {
-    /**
-     * Returns the installed module ids for the framework.
-     * @param arr The array to store the ids
-     * @param arrSize The available size of the provided arr
-     * @return the actual number ids added to the array
-     */
-    size_t (*listModuleIds)(uint64_t* arr, size_t arrSize);
-
-    /**
-     * Returns a copy of the module name.
-     * @param modId the module id
-     * @return A copy of the name or NULL if module id is invalid. The name should be released using free.
-     */
-    char* (*moduleName)(uint64_t modId);
-
-    /**
-     * Get the module name and stores it in the provided buffer.
-     * at most len characters will be written and a trailing 0 is ensured.
-     *
-     * @param modId The module id
-     * @param buf The string buffer
-     * @param len The length of the provider buffer
-     * @return number of characters written or 0 if unsuccessful
-     */
-    int (*getModuleName)(uint64_t modId, char* buf, size_t len);
-
-    /**
-     * Returns a copy of the module version.
-     * @param modId the module id
-     * @return A copy of the version or NULL if module id is invalid. The version should be released using free.
-     */
-    char* (*moduleVersion)(uint64_t modId);
-
-    /**
-     * Get the module version and stores it in the provided buffer.
-     * at most len characters will be written and a trailing 0 is ensured.
-     *
-     * @param modId The module id
-     * @param buf The string buffer
-     * @param len The length of the provider buffer
-     * @return number of characters written or 0 if unsuccessful
-     */
-    int (*getModuleVersion)(uint64_t modId, char* buf, size_t len);
-
-    /**
-     * Returns a copy of the manifest properties for the provided module id.
-     * @param modId The module id
-     * @return A copy of the manifest properties or NULL if the module id is invalid.
-     */
-    celix_properties* (*moduleManifest)(uint64_t modId);
-
-    size_t (*listServices)(uint64_t modId, uint64_t* arr, size_t arrSize);
-    size_t (*listServiceFactories)(uint64_t modId, uint64_t* arr, size_t arrSize);
-    size_t (*listTrackers)(uint64_t modId, uint64_t* arr, size_t arrSize);
-    size_t (*listTrackerListeners)(uint64_t modId, uint64_t* arr, size_t arrSize);
-    size_t (*listComponents)(uint64_t modId, uint64_t* arr, size_t arrSize);
-} celix_module_info_service;
-
-
-
-//celix/service_info_service.h
-
-typedef struct celix_service_info {
-    uint64_t serviceId;
-    uint64_t moduleOwner;
-    char* serviceName;
-    char lang[16];
-    uintt64_t rank;
-    celix_properties* properties;
-    size_t usageCount;
-    uint64_t factoryId;
-    struct timeval registrationTime;
-
-    struct {
-        uint64_t usingModule;
-        struct timeval trackTime;
-    }* usages;
-    size_t usagesSize;
-} celix_service_info;
-
-typedef struct celix_service_info_service {
-    /**
-     * Returns the all provided service ids for the framework.
-     * @param arr The array to store the ids
-     * @param arrSize The available size of the provided arr
-     * @return the actual number ids added to the array
-     */
-    size_t (*listServices)(uint64_t* arr, size_t arrSize);
-
-    /**
-     * Populates the service info for the provided service id.
-     * Caller needs to release the serviceName,
-     * properties and usages.
-     * Or call releaseInfo.
-     *
-     * If the service is the result of a service factory the
-     * factoryId will be set (not 0).
-     *
-     * If the service id is invalid, all fields will be 0.
-     *
-     * @param serviceId The service id
-     * @param info The service info struct to fill
-     */
-    void (*getInfo)(uint64_t* serviceId, celix_service_info* info);
-
-    /**
-    * Convenience function to release (free) the content in the info struct
-    */
-    void (*releaseInfo)(celix_service_info* info);
-} celix_service_info_service;
-
-
-
-//celix/service_factory_info_service.h
-
-typedef struct celix_service_factory_info {
-    uint64_t factoryId;
-    uint64_t moduleOwner;
-    char* serviceName;
-    char lang[16];
-    celix_properties* properties;
-    size_t usageCount;
-    struct timeval registrationTime;
-
-    struct {
-        uint64_t serviceId;
-        uint64_t boundedToModule;
-        struct timeval creationTime;
-    }* boundedServices;
-    size_t boundedServicesSize;
-} celix_service_factory_info;
-
-typedef struct celix_service_factory_info_service {
-    /**
-     * Returns the all provided factory ids for the framework.
-     * @param arr The array to store the ids
-     * @param arrSize The available size of the provided arr
-     * @return the actual number ids added to the array
-     */
-    size_t (*listFactories)(uint64_t* arr, size_t arrSize);
-
-    /**
-     * Populates the service factory info for the provided factory id.
-     * Caller needs to release the serviceName, properties and
-     * boundedServices.
-     * Or call releaseInfo.
-     *
-     * If the factory id is invalid, all fields will be 0.
-     *
-     * @param factoryId The factory id
-     * @param info The service factory info struct to fill
-     */
-    void (*getInfo)(uint64_t* factoryId, celix_service_factory_info* info);
-
-    /**
-     * Convenience function to release (free) the content in the info struct
-     */
-    void (*releaseInfo)(celix_service_factory_info* info);
-} celix_service_factory_info_service;
-
-
-
-//celix/service_tracker_info_service.h
-
-typedef struct celix_service_tracker_info {
-    uint64_t trackerId;
-    uint64_t moduleOwner;
-    char* serviceName;
-    char* filter;
-    char lang[16];
-
-    struct {
-        uint64_t serviceId;
-        uintt64_t rank;
-        struct timeval trackedTime;
-    }* trackedServices; /*ranked*/
-    size_t trackedServicesSize;
-} celix_service_tracker_info;
-
-typedef struct celix_tracker_info_service {
-    /**
-     * Returns the all provided service tracker ids for the framework.
-     * @param arr The array to store the ids
-     * @param arrSize The available size of the provided arr
-     * @return the actual number ids added to the array
-     */
-    size_t (*listServiceTrackers)(uint64_t* arr, size_t arrSize);
-
-    /**
-     * Populates the service tracker info for the provided service tracker id.
-     * Caller needs to release the serviceName, filter and
-     * trackedServices.
-     * Or call releaseInfo.
-     *
-     * If the service tracker id is invalid, all fields will be 0.
-     *
-     * @param trackerId The service tracker id
-     * @param info The service tracker info struct to fill
-     */
-    void (*getInfo)(uint64_t* trackerId, celix_service_tracker_info* info);
-
-    /**
-     * Convenience function to release (free) the content in the info struct
-     */
-    void (*releaseInfo)(celix_service_tracker_info* info);
-} celix_tracker_info_service;
-
-
-//celix/service_tracker_listener_info_service.h
-
-typedef struct celix_tracker_listener_info_service {
-    //TODO
-} celix_tracker_listener_info_service;
-
-
-
-//celix/component_info_service.h
-
-typedef struct celix_component_info {
-    char* componentName;
-    uint64_t ownerModuleId;
-    celix_component_state state;
-
-    //service dependencies
-    struct {
-        uint64_t trackerId;
-        bool required;
-        size_t availableCount;
-        char* filter;
-    }* dependencies;
-    size_t dependenciesSize;
-
-    //provided service
-    struct {
-        uint64_t serviceId;
-        celix_properties* properties;
-    }* providedServices;
-    size_t providedServicesSize;
-
-    //provided factories
-    struct {
-        uint64_t factoryId;
-        celix_properties* properties;
-    }* providedFactories;
-    size_t providedFactoriesSize;
-
-} celix_component_info;
-
-typedef struct celix_component_info_service {
-    /**
-     * Returns the all provided components ids for the framework.
-     * @param arr The array to store the ids
-     * @param arrSize The available size of the provided arr
-     * @return the actual number ids added to the array
-     */
-    size_t (*listFactories)(uint64_t* arr, size_t arrSize);
-
-    /**
-     * Populates the component info for the provided factory id.
-     * Caller needs to release the componentName, dependencies filter,
-     * dependencies, providedServices properties,  providedServices,
-     * providedFactories properties, providedFactories.
-     * Or call releaseInfo.
-     *
-     * If the component id is invalid, all fields will be 0.
-     *
-     * @param componentId The component id
-     * @param info The component info struct to fill
-     */
-    void (*getInfo)(uint64_t* factoryId, celix_component_info* info);
-
-    /**
-     * Convenience function to release (free) the content in the info struct
-     */
-    void (*releaseInfo)(celix_component_info* info);
-} celix_component_info_service;
-
-
-
-//celix/event_service.h
-
-#include "celix/events.h"
-
-/**
- * A Celix Event. Events always have a topic and
- * optional can have multiple key/value entries.
- *
- * For the event entries, the key is always a string and
- * the value pointer to something.
- *
- * Important to note is that events (and their entries) are only quaranteed to exists
- * during the handle of the event callback. As result event and their entries should not
- * be stored for later use.
- * The values of pointer to primitive types can of course be copied (e.g. a module id).
- */
-typedef struct celix_event {
-    const char* eventTopic;
-    const celix_map* entries;
-};
-
-#define CELIX_EVENT_TOPICS      "event.topics"
-#define CELIX_EVENT_FILTER      "event.filter"
-
-/**
- * The celix_event_listener is a generic whiteboard service which can be registered
- * to handle events for specific topics.
- *
- * If this service is registered with the event.topics property, only those topics (comma seperated) will trigger the
- * onEvent callback.
- * If this service is registered with the event.filter propertie, only event which match the filter, using the
- * string entries of celix_event.entries as filter target, will trigger the onEvent callback.
- *
- */
-typedef struct celix_event_listener {
-    void* handle;
-
-    /**
-     * Will be called when a matching event is triggered.
-     *
-     * @param handle the service handle
-     * @param event The event, which will quaranteed to exists during the execution of the onEvent callbacks
-     */
-    void (*onEvent)(void* handle, const celix_event* event);
-} celix_event_listener;
-
-
-typedef void (*freeEvent_fp)(celix_event* event);
-
-typedef struct celix_event_admin {
-    void* handle;
-
-    /**
-     * Posts an event. The event will be send and freed async.
-     */
-    void (*postEvent)(void* handle, const char* topic, celix_event* event, freeEvent_fp freeEvent);
-
-    /**
-     * Send an event. This call will block til the event propagated through all registered event listener.
-     * The event can be freed after the sendEvent function returns.
-     */
-    void (*sendEvent)(void* handle, const char* topic, const celix_event* event);
-} celix_event_admin;
-
-
-
-//celix/events.h
-
-
-/**
- * A Module INSTALL, START, STOP or UNINSTALL Event will be created by the framework
- * - if a event admin service is available - when installing, starting, stopping and uninstalling a module.
- *
- * The event map has two entries:
- *   - A module id uint64 entry, containing the moduleId
- *   - A module const ptr entry, containing a celix_module*
- *
- *   The module entry can be used to for extender pattern functionality and dynamic lookup functionality
- *   (e.g. like gogo commands). The module entry can only be used in during a handleEvent callback,
- *   after the callback module entry can be invalid.
- */
-
-#define CELIX_EVENT_MODULE_TOPIC_ALL        "celix/event/module/*"
-#define CELIX_EVENT_MODULE_TOPIC_INSTALL    "celix/event/module/INSTALL"
-#define CELIX_EVENT_MODULE_TOPIC_START      "celix/event/module/START"
-#define CELIX_EVENT_MODULE_TOPIC_STOP       "celix/event/module/STOP"
-#define CELIX_EVENT_MODULE_TOPIC_UNINSTALL  "celix/event/module/UNINSTALL"
-
-#define CELIX_EVENT_MODULE_KEY_MODULE "module"
-#define CELIX_EVENT_MODULE_KEY_MODULE_ID "moduleId"
-
-
-/**
- * A Service REGISTER/UNREGISTER Event will be created by the framework - if a event admin service is available -
- * when registering, unregistering a service
- *
- * The event map has the following entries
- *   - A serviceId uint64 entry, containing the service id
- *   - A serviceName string entry, containing the service name
- *   - A moduleOwnerId uint64 entry, containing the module owner id
- *   - A owner const ptr entry containing a celix_module*
- *   - A properties const ptr entry containing a celix_properties* entry.
- *
- *   The owner entry can be used to for extender pattern functionality and dynamic lookup functionality
- *   (e.g. like gogo commands). The module entry can only be used in during a handleEvent callback,
- *   after the callback module entry can be invalid.
- */
-
-#define CELIX_EVENT_SERVICE_TOPIC_ALL           "celix/event/service/*"
-#define CELIX_EVENT_SERVICE_TOPIC_REGISTER      "celix/event/service/REGISTER"
-#define CELIX_EVENT_SERVICE_TOPIC_UNREGISTER    "celix/event/service/UNREGISTER"
-
-#define CELIX_EVENT_SERVICE_KEY_SERVICE_ID      "serviceId"
-#define CELIX_EVENT_SERVICE_KEY_SERVICE_NAME    "serviceName"
-#define CELIX_EVENT_SERVICE_KEY_MODULE_OWNER_ID "moduleOwnerId"
-#define CELIX_EVENT_SERVICE_KEY_OWNER           "owner"
-#define CELIX_EVENT_SERVICE_KEY_PROPERTIES      "properties"
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif //CELIX_H_

http://git-wip-us.apache.org/repos/asf/celix/blob/3f24edf0/documents/roadmap/api_v3/readme.md
----------------------------------------------------------------------
diff --git a/documents/roadmap/api_v3/readme.md b/documents/roadmap/api_v3/readme.md
deleted file mode 100644
index f180aae..0000000
--- a/documents/roadmap/api_v3/readme.md
+++ /dev/null
@@ -1,283 +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.
--->
-
-# Celix Version 3 (Proposal)
-
-## Intro
-The [celix.h](celix/celix.h) header contains a proposed API for Apache Celix version 3.
-This API is not fixed, but work in progress and should be considered a starting point for discussion.
-
-There are a few reasons for a API change:
-
-### The current Apache Celix API is mapped from the OSGi API.
-The problem is that OSGi is designed for Java, a
-language where classes are present runtime, reflection can be used, resource are controlled through garbage collection
-and classes are kept available when still needed(garbage collector) even if a bundle is uninstalled.
-This resulted in an API which is very lenient in object sharing/ownership and no real focus on resource
-locking/protection. This simply does not map wel to a C language. For a dynamic service framework in C, the focus
-should be in minimizing object sharing and when needed only for a controlled, well defined and short period. When
-resource sharing is needed - i.e. services - projecting access to these resources should dictate the design of the
-API.
-In this proposed API, when possible, object sharing is done through sharing ids in the form of a primitive
-(value copied) types instead of pointers. These ids can be used to
-(safely) retrieve info form the object if still present, which should make it more safe to use and most importantly
-less complex for implementation (think threads & locks). Also most service or service related updates must be
-handled with callbacks, to ensure correct usage of locking can be applied more easily.
-
-### OSGi API leaks too much details.
-The OSGi API is more than 15 years old and has grown overtime, this shows.
-There are a lot of hoops to take to use a service in a correct way.
-The proposed Apache Celix API tries to minimize the needed objects, while still providing the same functionality.
-It was also designed for a more user friendly experience.
-
-### Smaller code base
-Because the OSGi leaks to much details, it is also difficult to implemented; specifically mapped one to one from Java.
-A redesign of the API could lead to a smaller code base.
-
-### Single framework event thread design.
-It would be beneficial to use single framework event thread,
-this would means that as a user it is ensured that all the callbacks are called from the same thread.
-Preventing issues that service can be added/removed simultaneously and the locking complexity which comes with that.
-With the current API this is more difficult (too many entries to shared resources).
-
-### Multiple languages
-One of the key values of Apache Celix should be to deliver a sophisticated develop / design environment for more
-complex - i.e. composed out of modules) application/systems. For example a applications with combines
-some well proven C modules/libraries, with modern C++ modules and a splash of development support
-with python modules.
-And although Apache Celix is not there yet, it is one of it's goals.
-The current API is not designed to support multiple languages and is difficult to port the different languages due to
-the "too much details" issue.
-
-### More focus on the primary ways to interact with a dynamic service framework.
-For Apache Celix developers a focus is how to: work with services (register, tracking & monitor service interest) and
-how to easily create components which provides and depends on services.
-The proposed API focus on these issues as built-in support. For OSGi some of these functions where added add a later
-stage and this shows.
-
-### Current api has a strong focus on error codes
-Java has exceptions, C has not. This has lead to an initial design that almost all function return a error code.
-While in principle completely correct, from a developer perspective it become cumbersome.
-Also taking in to perspective, than in many cases if an error is returned there no real way to handle this,
-the proposed API focus more on easy of use and lenient and silently accepting invalid input (i.e. NULL pointers
-or invalid ids).
-
-### Integral API
-Again because the OSGi API has grown overtime, the API seems to be dispersed and not one integral API.
-The proposed API tries to remedy that.
-
-### Runtime Type Introspection
-With OSGi for Java you have runtime type introspection (reflection) build-in the Java language, for C
-(and most other native languages) this is not the case. As effect is not possible to infer if services
-are compatible or to automagically make service remote / serialize types.
-The dynamic function interface library (dfi library) adds type introspection support, by using the extender pattern combined with so called type/interface descriptor files.
-Although not ideal, this can be used to runtime check service compatibility and automagically serialize types.
-If possible the dfi support will be optional and opt-out.
-
-### Eat your own dog food
-A bit strange, but as a service oriented framework the OSGi specification for the core framework specification does not provide framework services.
-The proposed API moves some of the API for detailed info to framework services.
-
-### Integrated event admin
-Services are great, but not everything fits perfectly solely with services. The event admin from the OSGi
-specification is a nice complement to the service oriented paradigm and as result event admin awareness is taken
-into account in the proposed API.
-
-### Missing prefix for symbols and headers
-The current usage of prefixes is not sufficient. For example the celix framework has te be included as
-"framework.h" and has no prefix. This is not wise for a language without namespaces. The proposed API
-prefixes everything with celix_ and all include paths start with celix/.
-TODO discuss if a more generic OSGi like prefix is desirable, e.g. nosgi_ and nosgi/
-
-### const correctness
-The proposed API add the use of const when applicable. The usage of const adds more semantics to the API and
-can prevent certain calls (e.g.in the callbacks) when they should not be used.
-
-### Support for a more static approach
-Although Apache Celix is a framework for dynamic services, this does not mean that every module should be runtime install/uninstall-able.
-Supporting static modules and modules as "plain old libraries" can make it easier to use and deploy application using Apache Celix.
-In this proposal, bundle are still present, but just a way to install modules. Support for installing modules using static
- and shared libraries is added.
-
-## Apache Celix V3 CMake Commands
-Apache Celix provides several CMake commands to be able to work with Apache Celix modules, bundles and deployments.
-
-### Generic Changes
-
-- symbolic_name is no longer needed nor expected. A module_name / bundle_name
-is enough and should be unique.
-- All command are prefixed with `celix_`.
-
-### Modules & Bundles
-
-Modules are self-contained, autonomous and bounded software parts which can be combined to provide a greater/broader functionality.
-
-Modules contain resources and required libraries (self-contained),
-use a activator to bootstrap itself (autonomous),
-can provide/require services to share/use functionality (bounded)
-and can import / export libraries so share types / routines (bounded)
-
-There are two types of modules
- - Library Modules
- - Bundled Modules (aka Bundles)
-
-Library modules are singular modules which do not import nor export libraries,
-cannot be bundled with additional required (private) libraries, and are build as shared or static libraries.
-Library modules can contain additional (embedded) resources.
-Static modules will only auto register on platforms where there is
-support for the  `__attribute__((ctor))` compiler attribute.
-
-Bundle modules are modules which can import and/or export other libraries and
-can embed additional required (private) libraries.
-Bundle modules will be build as bundle file (ZIP file).
-
-### Modules
-
-Modules can be build a "plain old libraries" using the CMake
-add_library command. Resources can be added using the
-celix_module_files command.
-
-To be able to find the module resources, the module name used in the
-celix_moduleRegister call should be the same as the module name used
-in the CMake commnands.
-If no module name is set using the celix_module_name CMake command,
-the module name is equal to the name target.
-
-```CMake
-
-celix_module_name(<module_target> <module_name>)
-
-celix_module_files(<bundle_or_module_target>
-    files... DESTINATION <dir>
-    [FILE_PERMISSIONS permissions...]
-    [DIRECTORY_PERMISSIONS permissions...]
-    [NO_SOURCE_PERMISSIONS] [USE_SOURCE_PERMISSIONS]
-    [FILES_MATCHING]
-    [[PATTERN <pattern> | REGEX <regex>]
-    [EXCLUDE] [PERMISSIONS permissions...]] [...])
-)
-```
-
-```C
-/**
- * Registers the module for all current framework and future framework that are created.
- * If no name is provided, the module will not be registered and an error will be logged.
- *
- * When initializing the module, the framework will look for a <module_name>_resourceEntry and
- * <module_name>_resourceEntrySize symbol. If found, the content is assumed to be an embedded zip (or tar?) file.
- * the celix_modules_files CMake command will ensure that these symbols are created and linked to the module library.
- *
- * @param moduleName The name of the module.
- * @param moduleVersion Optional, the version of the module.
- * @startFp Optional the start function which will be called if the module is going to be added and ready to start.
- * @startFp Optional the stop function which will be called if the module going to be removed and ready to start.
- * @opts Optional the additional options. The options will only be used during the registerModule call.
- * @return 0 if successful
- */
-int celix_moduleRegistration_registerModule(
-        const char* moduleName,
-        const char* moduleVersion,
-        celix_module_registration_startModule_fp startFp,
-        celix_module_registration_stopModule_fp stopFp,
-        const celix_module_registration_options* opts);
-```
-
-### Bundles
-Bundles are ZIP files which bundle one module.
-The CMake commands for add_bundle commands are not changed with exception of the
-added celix_ prefix. The other command are renamed to module and a celix_ is added
-(e.g bundle_name -> celix_module_name)
-
-```CMake
-celix_add_bundle(<bundle_target_name>
-    SOURCES source1 source2 ...
-    [NAME bundle_name]
-    [SYMBOLIC_NAME bundle_symbolic_name]
-    [DESCRIPTION bundle_description]
-    [VERSION bundle_version]
-    [PRIVATE_LIBRARIES private_lib1 private_lib2 ...]
-    [EXPORT_LIBRARIES export_lib1 export_lib2 ...]
-    [IMPORT_LIBRARIES import_lib1 import_lib2 ...]
-    [HEADERS "header1: header1_value" "header2: header2_value" ...]
-)
-
-celix_add_bundle(<bundle_target_name>
-    ACTIVATOR <activator_lib>
-    [NAME bundle_name]
-    [SYMBOLIC_NAME bundle_symbolic_name]
-    [DESCRIPTION bundle_description]
-    [VERSION bundle_version]
-    [PRIVATE_LIBRARIES private_lib1 private_lib2 ...]
-    [EXPORT_LIBRARIES export_lib1 export_lib2 ...]
-    [IMPORT_LIBRARIES import_lib1 import_lib2 ...]
-    [HEADERS "header1: header1_value" "header2: header2_value" ...]
-)
-
-celix_add_bundle(<bundle_target_name>
-    [NAME bundle_name]
-    [SYMBOLIC_NAME bundle_symbolic_name]
-    [DESCRIPTION bundle_description]
-    [VERSION bundle_version]
-    [PRIVATE_LIBRARIES private_lib1 private_lib2 ...]
-    [EXPORT_LIBRARIES export_lib1 export_lib2 ...]
-    [IMPORT_LIBRARIES import_lib1 import_lib2 ...]
-    [HEADERS "header1: header1_value" "header2: header2_value" ...]
-)
-
-```
-
-### Descriptors
-Descriptors are files which describe interfaces or messages which can be
-parsed by the dynamic function interface (dfi) library.
-The dfi library can be used for runtime 'type introspection'.
-The descriptor files are a bit cryptic for human eyes, but relatively easy to parse.
-
-With these descriptors the Celix framework can runtime compare if
-services and/or messages provider consumer combinations are compatible
-and make remote services / serialization of messages possible.
-
-The `celix_module_descriptor` CMake will register header files
-for descriptor generation and inclusion in the module/bundle
-resources (under META-INF/descriptors/interfaces and
-META-INF/descriptors/messages).
-
-The Celix project will have a `dfi-gen` target which will be used to
-generate the descriptors from the header files.
-
-```CMake
-
-celix_module_descriptor(<bundle_or_module_target>
-    header_file1 header_file2 ...
-)
-```
-
-### Deployment
-
-The `add_deploy` will be changed to `celix_add_deploy` and will accept
-library modules and bundle modules.
-
-```CMake
-celix_add_deploy(<deploy_target_name>
-    [COPY]
-    [GROUP group_name]
-    [NAME deploy_name]
-    [LAUNCHER launcher]
-    [DIR dir]
-    [MODULES <module_or_bundle1> <module_or_bundle2> ...]
-    [PROPERTIES "prop1=val1" "prop2=val2" ...]
-)
-```

http://git-wip-us.apache.org/repos/asf/celix/blob/3f24edf0/documents/roadmap/improvement_ideas.md
----------------------------------------------------------------------
diff --git a/documents/roadmap/improvement_ideas.md b/documents/roadmap/improvement_ideas.md
deleted file mode 100644
index 32db322..0000000
--- a/documents/roadmap/improvement_ideas.md
+++ /dev/null
@@ -1,54 +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.
--->
-
-# Improvement Ideas
- 
-# Introduce dlmopen for library imports.
-Currently library are loaded LOCAL for bundles. This works alright, but makes it hard to add a concept 
-of exporting and importing libraries. 
-
-The trick is that the NEEDED header in the importing libraries 
-should match the target exported library SONAME header and no other exported libraries SONAME headers. 
-One solution to make this work is to alter the NEEDED & SONAME runtime. 
- 
-For glibc there is now an other alternative, namely using dlmopen. dlmopen makes it possible to load 
-libraries in a given namespace. For bundle this can be used to create a library namespace per bundle 
-and load exported libraries int importing bundle namespace. A clean solution, but this currently 
-only works for glibc (linux).
-
-
-# Fix the performance use case and add C++ support
-There was a locking example which also functioned as a performance test to measure the impact of
-using services instead of direct function calls. 
-During the removal of APR this example stopped working. Add it back, fix it and add a C++ use case
-as example.
-See [locking example tree](https://github.com/apache/celix/tree/216032cae956379d4a740f37ae5caee7e957bd98/examples/locking)
-
-# Cleanup Celix project structure
-Celix is growing and getting more sub project, this is fine but maybe the structure needs a cleanup to 
-create a more clear root directory structure. 
-
-# Extend the test environment
-
-# Improve documentation
-
-# Create one or more "real life" applications based on Celix to show the potential of Celix
-
-# Add pub sub admins. 
-The current implementation uses JSON over multicast UDP or over ZMQ.  
-One or more could be added. i.e. serialization based on Apache-Avro, communication over TCP / Kafka / Shared Memory  
-Add interfaces for other languages (Python / Rust / Go / ...)  


[4/4] celix git commit: CELIX-449: Restructure of some parts of the documentation to make it easier to integrate with the celix-site.

Posted by pn...@apache.org.
CELIX-449: Restructure of some parts of the documentation to make it easier to integrate with the celix-site.


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

Branch: refs/heads/develop
Commit: 3f24edf0bc00b05d28acbbf924851050c23dbccf
Parents: 6779498
Author: Pepijn Noltes <pe...@gmail.com>
Authored: Mon Jul 2 20:33:28 2018 +0200
Committer: Pepijn Noltes <pe...@gmail.com>
Committed: Mon Jul 2 20:33:28 2018 +0200

----------------------------------------------------------------------
 bundles/log_service/README.md                   |   19 -
 bundles/log_writer/README.md                    |   13 -
 bundles/remote_services/README.md               |  166 --
 .../remote_services/discovery_etcd/README.md    |   29 -
 bundles/shell/remote_shell/README.md            |   27 -
 bundles/shell/shell/README.md                   |   51 -
 bundles/shell/shell_tui/README.md               |   34 -
 documents/bundles/log_service/README.md         |   19 +
 documents/bundles/log_writer/README.md          |   13 +
 documents/bundles/remote_services/README.md     |  176 ++
 .../remote_services/discovery_etcd/README.md    |   29 +
 documents/bundles/remote_shell/README.md        |   27 +
 documents/bundles/shell/README.md               |   51 +
 documents/bundles/shell_tui/README.md           |   34 +
 .../getting_started/creating_a_simple_bundle.md |  333 ---
 documents/getting_started/readme.md             |    6 +-
 .../getting_started/services_with_c/readme.md   |  610 ++++++
 .../getting_started/services_with_cxx/readme.md |  571 ++++++
 .../getting_started/simple_bundle/readme.md     |  333 +++
 .../getting_started/using_services_with_c.md    |  610 ------
 .../getting_started/using_services_with_cxx.md  |  571 ------
 documents/roadmap/api_v3/celix/celix.h          | 1896 ------------------
 documents/roadmap/api_v3/readme.md              |  283 ---
 documents/roadmap/improvement_ideas.md          |   54 -
 documents/roadmap/roadmap.md                    |  123 --
 documents/subprojects/readme.md                 |   35 +-
 misc/roadmap/improvement_ideas.md               |   54 +
 misc/roadmap/roadmap.md                         |  123 ++
 28 files changed, 2057 insertions(+), 4233 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/celix/blob/3f24edf0/bundles/log_service/README.md
----------------------------------------------------------------------
diff --git a/bundles/log_service/README.md b/bundles/log_service/README.md
deleted file mode 100644
index 53d2c3b..0000000
--- a/bundles/log_service/README.md
+++ /dev/null
@@ -1,19 +0,0 @@
-# Log Service
-
-The Celix Log Service realizes an adapted implementation of the OSGi Compendium Log Service. This is a very simple implementation which only stores the log in memory. It can be combined with one of the available Log Writers to forward the buffered entries to e.g. stdout or syslog.
-
-To ease the use of the Log Service, the [Log Helper](public/include/log_helper.h) can be used. It wraps and therefore simplifies the log service usage.
-
-## Properties
-    LOGHELPER_ENABLE_STDOUT_FALLBACK      If set to any value and in case no Log Service is found the logs
-                                          are still printed on stdout. 
-
-## CMake option
-    BUILD_LOG_SERVICE=ON
-
-## Using info
-
-If the Celix Log Service is installed, 'find_package(Celix)' will set:
- - The `Celix::log_service_api` interface (i.e. header only) library target
- - The `Celix::log_service` bundle target
- - The `Celix::log_helper` static library target

http://git-wip-us.apache.org/repos/asf/celix/blob/3f24edf0/bundles/log_writer/README.md
----------------------------------------------------------------------
diff --git a/bundles/log_writer/README.md b/bundles/log_writer/README.md
deleted file mode 100644
index e2d5b34..0000000
--- a/bundles/log_writer/README.md
+++ /dev/null
@@ -1,13 +0,0 @@
-# Log Writer
-
-The Celix Log Writers are components that read/listen to the Log Service and print the Log entries to the console or syslog, respectively.
-
-## CMake options
-    BUILD_LOG_WRITER=ON
-    BUILD_LOG_WRITER_SYSLOG=ON
-
-## Using info
-
-If the Celix Log Writers are installed `find_package(CELIX)` will set:
- - The `Celix::log_writer_stdout` bundle target
- - The `Celix::log_writer_syslog` bundle target

http://git-wip-us.apache.org/repos/asf/celix/blob/3f24edf0/bundles/remote_services/README.md
----------------------------------------------------------------------
diff --git a/bundles/remote_services/README.md b/bundles/remote_services/README.md
deleted file mode 100644
index 15365b2..0000000
--- a/bundles/remote_services/README.md
+++ /dev/null
@@ -1,166 +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.
--->
-
-Title: Apache Celix Remote Service Admin Service
-
-## Introduction
-
-The Remote Service Admin Service subproject contains an adapted implementation of the OSGi Enterprise Remote Service Admin Service Specification. The subproject consists of three parts, each described in more detail in the following sections.
-
-### Topology Manager
-
-The topology manager decides which services should be imported and exported according to a defined policy. Currently, only one policy is implemented in Celix, the *promiscuous* policy, which simply imports and exports all services.
-
-| **Bundle** | `topology_manager.zip` |
-|--|--|
-| **Configuration** | *None* |
-
-### Remote Service Admin
-
-The Remote Service Admin (RSA) provides the mechanisms to import and export services when instructed to do so by the Topology Manager. 
-
-#### Endpoints and proxies
-
-To delegate a *received* method call to the actual service implementation, the RSA uses an "endpoint" bundle, which has all the knowledge about the marshalling and unmarshalling of data for the service. This endpoint bundle is specific to the used RSA implementation, and as such cannot be reused between various RSA implementations.
-
-Invoking a *remote* method is done by using "proxy" bundles. Similar as to endpoints, proxy bundles encapsulate all knowledge to marshall and unmarshall data for a remote method call and as such can not be shared between RSA implementations.
-
-Both proxy and endpoint bundles are loaded on demand when a service is imported or exported by the RSA. As such, these bundles **must** not be added to the list of "auto started" bundles, but placed in a separate location. By default, `endpoints` is used as location for locating proxy and/or endpoint bundles.
-
-Note that since endpoints and proxies need to be created manually, one has full control about the handling of specifics of marshalling and unmarshalling data and dealing with exceptions. 
-
-#### HTTP/JSON
-
-Provides a RSA implementation that uses JSON to marshal requests and HTTP as transport mechanism for its remote method invocation. It is compatible with the *Remote Service Admin HTTP* implementation provided by [Amdatu Remote](https://amdatu.atlassian.net/wiki/display/AMDATUDEV/Amdatu+Remote).
-
-| **Bundle** | `remote_service_admin_http.zip` |
-|--|--|
-| **Configuration** | `RSA_PORT`: defines the port on which the HTTP server should listen for incoming requests. Defaults to port `8888`; |
-| | `ENDPOINTS`: defines the location in which service endpoints and/or proxies can be found. Defaults to `endpoints` in the current working directory |
-
-#### Shared memory (SHM)
-
-Provides a RSA implementation that uses shared memory for its remote method invocation. Note that this only works when all remote services are located on the same machine.
-
-| **Bundle** | `remote_service_admin_shm.zip` |
-|--|--|
-| **Configuration** | `ENDPOINTS`: defines the location in which service endpoints and/or proxies can be found. Defaults to `endpoints` in the current working directory |
-
-### Discovery
-
-Actively discovers the presence of remote exported services and provides information about local exported services, as given by the Topology Manager, to others.
-
-#### Shared memory (SHM) based discovery
-
-Provides service discovery for the RSA SHM implementation.
-
-| **Bundle** | `discovery_shm.zip` |
-|--|--|
-| **Configuration** | *None* |
-
-#### Configured discovery
-
-Provides a service discovery with preconfigured discovery endpoints, allowing a static mesh of nodes for remote service invocation to be created. The configured discovery bundle in Celix is compatible with the configured discovery implementation provided by [Amdatu Remote](https://amdatu.atlassian.net/wiki/display/AMDATUDEV/Amdatu+Remote).
-
-| **Bundle** | `discovery_configured.zip` |
-|--|--|
-| **Configuration** | `DISCOVERY_CFG_POLL_ENDPOINTS`: defines a comma-separated list of discovery endpoints that should be used to query for remote services. Defaults to `http://localhost:9999/org.apache.celix.discovery.configured`; |
-| | `DISCOVERY_CFG_POLL_INTERVAL`: defines the interval (in seconds) in which the discovery endpoints should be polled. Defaults to `10` seconds. |
-| | `DISCOVERY_CFG_SERVER_PORT`: defines the port on which the HTTP server should listen for incoming requests from other configured discovery endpoints. Defaults to port `9999`; |
-| | `DISCOVERY_CFG_SERVER_PATH`: defines the path on which the HTTP server should accept requests from other configured discovery endpoints. Defaults to `/org.apache.celix.discovery.configured`. |
-
-Note that for configured discovery, the "Endpoint Description Extender" XML format defined in the OSGi Remote Service Admin specification (section 122.8 of OSGi Enterprise 5.0.0) is used.
-
-See [etcd discovery](discovery_etcd/README.md)
-
-#### etcd discovery 
-
-| **Bundle** | `discovery_etcd.zip` |
-
-Provides a service discovery using etcd distributd key/value store. 
-
-See [etcd discovery](discovery_etcd/README.md)
-
-## Usage
-
-To develop for the Remote Service Admin implementation of Celix, one needs the following:
-
-1. A service **interface**, describes the actual service and methods[^1] that can be called. The service interface is needed at development time to allow a consistent definition;
-2. A service **implementation**, when exporting it as remote service. A service endpoint is needed to delegate remote requests to your service implementation;
-3. A service **endpoint**, which will be installed by Celix when exporting a local service. The endpoint is responsible for calling the actual Celix service. Endpoint bundles are not needed when *only* importing services in Celix;
-4. A service **proxy**, which will be installed by Celix when importing a remote service. The proxy is responsible for marshalling and unmarshalling method invocations. Proxy bundles are not needed when *only* exposing services from Celix;
-5. A service **client** or user, which invokes methods on the local or remote service. The client is oblivious to the fact whether the service is running locally or remote.
-
-The Celix source repository provides a simple calculator example that shows all of the described parts:
-
-1. [The calculator service interface](http://svn.apache.org/repos/asf/celix/trunk/remote_services/calculator_service/public/include/calculator_service.h), providing three methods: one for adding two numbers, one for subtracting two numbers, and lastly, a method that calculates the square root of a number;
-2. [A calculator service implementation](http://svn.apache.org/repos/asf/celix/trunk/remote_services/calculator_service/private/src/calculator_impl.c) that simply implements the three previously described functions. To mark this service as "remote service", you need to add the `service.exported.interfaces` service property to its service registration. This way, the RSA implementation can expose it as remote service to others;
-3. [A service endpoint](http://svn.apache.org/repos/asf/celix/trunk/remote_services/calculator_endpoint/private/src/calculator_endpoint_impl.c), which is called by the RSA implementation to delegate a method invocation to an actual method in the service implementation. The service endpoint should be registered as `remote_endpoint` service, along with the `remote.interface` service property denoting which service interface this endpoint is capable of handling;
-4. [A service proxy (factory)](http://svn.apache.org/repos/asf/celix/trunk/remote_services/calculator_proxy/private/src/calculator_proxy_impl.c), called by the service client when it wants to invoke a method on a remoted service. The service proxy should be registered as `remote_proxy_factory` service along with the `proxy.interface` service property denoting which service interface the service proxy is capable of handling;
-5. [A service client](http://svn.apache.org/repos/asf/celix/trunk/remote_services/calculator_shell/private/src/add_command.c), that exposes the three calculator methods to as Celix shell commands. The implementation simply retrieves the calculator service as it would do with any other Celix service.
-
-If you have access to the Celix source repository, you can run the calculator example using various discovery implementations by invoking the `deploy` target. You can find the example deployments in the `CELIX_BUILD/deploy` directory. For example, to run the calculator example using the configured discovery mechanism, you should open two terminals. In the first terminal, type:
-
-    remote-service-cfg$ export RSA_PORT=18888
-    remote-service-cfg$ sh run.sh
-    ...
-    RSA: Export services (org.apache.celix.calc.api.Calculator)
-    ...
-    -> _
-
-In the second terminal, type:
-
-    remote-service-cfg-client$ export RSA_PORT=28888
-    remote-service-cfg-client$ sh run.sh
-    ...
-    RSA: Import service org.apache.celix.calc.api.Calculator
-    ...
-    -> _
-
-Now, if all went well, the client (second terminal) has three new shell commands, `add`, `sub` and `sqrt`, which you can use to invoke the calculator service:
-
-    -> add 3 5
-    CALCULATOR_SHELL: Add: 3.000000 + 5.000000 = 8.000000
-    -> _
-
-On the server side (first terminal), you can follow each invocation as well:
-
-    CALCULATOR_ENDPOINT: Handle request "add(DD)D" with data "{"m": "add(DD)D", "a": [3.0, 5.0]}"
-    CALCULATOR: Add: 3.000000 + 5.000000 = 8.000000
-
-Note that the `RSA_PORT` property needs to be unique for at least the client in order to communicate correctly when running the examples on the same machine. 
-
-## Building
-
-To build the Remote Service Admin Service the CMake build option "`BUILD_REMOTE_SERVICE_ADMIN`" has to be enabled.
-
-## Dependencies
-
-The Remote Service Admin Service depends on the following subprojects:
-
-- Framework
-- Utils
-
-Also the following libraries are required for building and/or using the Remote Service Admin Service subproject:
-
-- Jansson (build and runtime)
-- cURL (build and runtime)
-
-
-## Notes
-
-[^1]: Although C does not use the term "method", we use this term to align with the terminology used in the RSA specification. 

http://git-wip-us.apache.org/repos/asf/celix/blob/3f24edf0/bundles/remote_services/discovery_etcd/README.md
----------------------------------------------------------------------
diff --git a/bundles/remote_services/discovery_etcd/README.md b/bundles/remote_services/discovery_etcd/README.md
deleted file mode 100644
index e560264..0000000
--- a/bundles/remote_services/discovery_etcd/README.md
+++ /dev/null
@@ -1,29 +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.
--->
-
-## Discovery ETCD
-
-The Celix Discovery ETCD bundles realizes OSGi services discovery based on [etcd](https://github.com/coreos/etcd).
-
-###### Properties
-    DISCOVERY_ETCD_ROOT_PATH             used path (default: discovery)
-    DEFAULT_ETCD_SERVER_IP               ip address of the etcd server (default: 127.0.0.1)
-    DEFAULT_ETCD_SERVER_PORT             port of the etcd server  (default: 2379)
-    DEFAULT_ETCD_TTL                     time-to-live for etcd entries in seconds (default: 30)
-
-###### CMake option
-    BUILD_RSA_DISCOVERY_ETCD=ON

http://git-wip-us.apache.org/repos/asf/celix/blob/3f24edf0/bundles/shell/remote_shell/README.md
----------------------------------------------------------------------
diff --git a/bundles/shell/remote_shell/README.md b/bundles/shell/remote_shell/README.md
deleted file mode 100644
index af28421..0000000
--- a/bundles/shell/remote_shell/README.md
+++ /dev/null
@@ -1,27 +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.
--->
-
-## Remote Shell
-
-The Celix Remote Shell implements a telnet interface for the Celix Shell.
-
-###### Properties
-    remote.shell.telnet.port              used port (default: 6666)
-    remote.shell.telnet.maxconn           amount of concurrent connections (default: 2)
-
-###### CMake option
-    BUILD_REMOTE_SHELL=ON

http://git-wip-us.apache.org/repos/asf/celix/blob/3f24edf0/bundles/shell/shell/README.md
----------------------------------------------------------------------
diff --git a/bundles/shell/shell/README.md b/bundles/shell/shell/README.md
deleted file mode 100644
index d9f38af..0000000
--- a/bundles/shell/shell/README.md
+++ /dev/null
@@ -1,51 +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.
--->
-
-# Shell
-
-The Celix Shell provides a service interface which can be used to interact with the Celix framework. Note that it does not offer a user interface. This modular approach enables having multiple frontends, e.g. textual or graphical.
-
-While the shell can be extended with additional commands by other bundles, it already offers some built in commands:
-
-    lb            list bundles
-    install       install additional bundle
-    uninstall     uninstall bundles
-    update        update bundles
-
-    start         start bundle
-    stop          stop bundle
-
-    help          displays available commands
-    inspect       inspect service and components
-
-    log           print log
-
-Further information about a command can be retrieved by using `help` combined with the command.
-
-## CMake options
-    BUILD_SHELL=ON
-
-## Shell Config Options
-
-- SHELL_USE_ANSI_COLORS - Whether shell command are allowed to use
-ANSI colors when printing info. default is true.
-
-## Using info
-
-If the Celix Shell is installed, 'find_package(Celix)' will set:
- - The `Celix::shell_api` interface (i.e. header only) library target
- - The `Celix::shell` bundle target

http://git-wip-us.apache.org/repos/asf/celix/blob/3f24edf0/bundles/shell/shell_tui/README.md
----------------------------------------------------------------------
diff --git a/bundles/shell/shell_tui/README.md b/bundles/shell/shell_tui/README.md
deleted file mode 100644
index 2b8984f..0000000
--- a/bundles/shell/shell_tui/README.md
+++ /dev/null
@@ -1,34 +0,0 @@
-<!--
-Licensed to the Apache Software Foundation (ASF) under one or more
-contributor license agreements.  See the NOTICE file distributed with
-this work for additional information regarding copyright ownership.
-The ASF licenses this file to You under the Apache License, Version 2.0
-(the "License"); you may not use this file except in compliance with
-the License.  You may obtain a copy of the License at
-   
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
--->
-
-# Shell TUI
-
-The Celix Shell TUI implements a textual user interface for the Celix Shell.
-
-## CMake option
-    BUILD_SHELL_TUI=ON
-
-## Config options
-
-- SHELL_USE_ANSI_CONTROL_SEQUENCES - Wether to use ANSI control
-sequences to support backspace, left, up, etc key commands in the
-shell tui. Default is true if a TERM environment is set else false.
-
-## Using info
-
-If the Celix Shell TUI is installed, 'find_package(Celix)' will set:
- - The `Celix::shell_tui` bundle target if the shell_tui is installed

http://git-wip-us.apache.org/repos/asf/celix/blob/3f24edf0/documents/bundles/log_service/README.md
----------------------------------------------------------------------
diff --git a/documents/bundles/log_service/README.md b/documents/bundles/log_service/README.md
new file mode 100644
index 0000000..53d2c3b
--- /dev/null
+++ b/documents/bundles/log_service/README.md
@@ -0,0 +1,19 @@
+# Log Service
+
+The Celix Log Service realizes an adapted implementation of the OSGi Compendium Log Service. This is a very simple implementation which only stores the log in memory. It can be combined with one of the available Log Writers to forward the buffered entries to e.g. stdout or syslog.
+
+To ease the use of the Log Service, the [Log Helper](public/include/log_helper.h) can be used. It wraps and therefore simplifies the log service usage.
+
+## Properties
+    LOGHELPER_ENABLE_STDOUT_FALLBACK      If set to any value and in case no Log Service is found the logs
+                                          are still printed on stdout. 
+
+## CMake option
+    BUILD_LOG_SERVICE=ON
+
+## Using info
+
+If the Celix Log Service is installed, 'find_package(Celix)' will set:
+ - The `Celix::log_service_api` interface (i.e. header only) library target
+ - The `Celix::log_service` bundle target
+ - The `Celix::log_helper` static library target

http://git-wip-us.apache.org/repos/asf/celix/blob/3f24edf0/documents/bundles/log_writer/README.md
----------------------------------------------------------------------
diff --git a/documents/bundles/log_writer/README.md b/documents/bundles/log_writer/README.md
new file mode 100644
index 0000000..e2d5b34
--- /dev/null
+++ b/documents/bundles/log_writer/README.md
@@ -0,0 +1,13 @@
+# Log Writer
+
+The Celix Log Writers are components that read/listen to the Log Service and print the Log entries to the console or syslog, respectively.
+
+## CMake options
+    BUILD_LOG_WRITER=ON
+    BUILD_LOG_WRITER_SYSLOG=ON
+
+## Using info
+
+If the Celix Log Writers are installed `find_package(CELIX)` will set:
+ - The `Celix::log_writer_stdout` bundle target
+ - The `Celix::log_writer_syslog` bundle target

http://git-wip-us.apache.org/repos/asf/celix/blob/3f24edf0/documents/bundles/remote_services/README.md
----------------------------------------------------------------------
diff --git a/documents/bundles/remote_services/README.md b/documents/bundles/remote_services/README.md
new file mode 100644
index 0000000..0e0215a
--- /dev/null
+++ b/documents/bundles/remote_services/README.md
@@ -0,0 +1,176 @@
+<!--
+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.
+-->
+
+Title: Apache Celix Remote Service Admin Service
+
+## Introduction
+
+The Remote Service Admin Service subproject contains an adapted implementation of the OSGi Enterprise Remote Service Admin Service Specification. The subproject consists of three parts, each described in more detail in the following sections.
+
+### Topology Manager
+
+The topology manager decides which services should be imported and exported according to a defined policy. Currently, only one policy is implemented in Celix, the *promiscuous* policy, which simply imports and exports all services.
+
+| **Bundle** | `topology_manager.zip` |
+|--|--|
+| **Configuration** | *None* |
+
+### Remote Service Admin
+
+The Remote Service Admin (RSA) provides the mechanisms to import and export services when instructed to do so by the Topology Manager. 
+
+#### Endpoints and proxies
+
+To delegate a *received* method call to the actual service implementation, the RSA uses an "endpoint" bundle, which has all the knowledge about the marshalling and unmarshalling of data for the service. This endpoint bundle is specific to the used RSA implementation, and as such cannot be reused between various RSA implementations.
+
+Invoking a *remote* method is done by using "proxy" bundles. Similar as to endpoints, proxy bundles encapsulate all knowledge to marshall and unmarshall data for a remote method call and as such can not be shared between RSA implementations.
+
+Both proxy and endpoint bundles are loaded on demand when a service is imported or exported by the RSA. As such, these bundles **must** not be added to the list of "auto started" bundles, but placed in a separate location. By default, `endpoints` is used as location for locating proxy and/or endpoint bundles.
+
+Note that since endpoints and proxies need to be created manually, one has full control about the handling of specifics of marshalling and unmarshalling data and dealing with exceptions. 
+
+#### HTTP/JSON
+
+Provides a RSA implementation that uses JSON to marshal requests and HTTP as transport mechanism for its remote method invocation. It is compatible with the *Remote Service Admin HTTP* implementation provided by [Amdatu Remote](https://amdatu.atlassian.net/wiki/display/AMDATUDEV/Amdatu+Remote).
+
+| **Bundle** | `remote_service_admin_http.zip` |
+|--|--|
+| **Configuration** | `RSA_PORT`: defines the port on which the HTTP server should listen for incoming requests. Defaults to port `8888`; |
+| | `ENDPOINTS`: defines the location in which service endpoints and/or proxies can be found. Defaults to `endpoints` in the current working directory |
+
+#### Shared memory (SHM)
+
+Provides a RSA implementation that uses shared memory for its remote method invocation. Note that this only works when all remote services are located on the same machine.
+
+| **Bundle** | `remote_service_admin_shm.zip` |
+|--|--|
+| **Configuration** | `ENDPOINTS`: defines the location in which service endpoints and/or proxies can be found. Defaults to `endpoints` in the current working directory |
+
+### Discovery
+
+Actively discovers the presence of remote exported services and provides information about local exported services, as given by the Topology Manager, to others.
+
+#### Shared memory (SHM) based discovery
+
+Provides service discovery for the RSA SHM implementation.
+
+| **Bundle** | `discovery_shm.zip` |
+|--|--|
+| **Configuration** | *None* |
+
+#### Configured discovery
+
+Provides a service discovery with preconfigured discovery endpoints, allowing a static mesh of nodes for remote service invocation to be created. The configured discovery bundle in Celix is compatible with the configured discovery implementation provided by [Amdatu Remote](https://amdatu.atlassian.net/wiki/display/AMDATUDEV/Amdatu+Remote).
+
+| **Bundle** | `discovery_configured.zip` |
+|--|--|
+| **Configuration** | `DISCOVERY_CFG_POLL_ENDPOINTS`: defines a comma-separated list of discovery endpoints that should be used to query for remote services. Defaults to `http://localhost:9999/org.apache.celix.discovery.configured`; |
+| | `DISCOVERY_CFG_POLL_INTERVAL`: defines the interval (in seconds) in which the discovery endpoints should be polled. Defaults to `10` seconds. |
+| | `DISCOVERY_CFG_SERVER_PORT`: defines the port on which the HTTP server should listen for incoming requests from other configured discovery endpoints. Defaults to port `9999`; |
+| | `DISCOVERY_CFG_SERVER_PATH`: defines the path on which the HTTP server should accept requests from other configured discovery endpoints. Defaults to `/org.apache.celix.discovery.configured`. |
+
+Note that for configured discovery, the "Endpoint Description Extender" XML format defined in the OSGi Remote Service Admin specification (section 122.8 of OSGi Enterprise 5.0.0) is used.
+
+See [etcd discovery](discovery_etcd/README.md)
+
+#### etcd discovery 
+
+| **Bundle** | `discovery_etcd.zip` |
+
+Provides a service discovery using etcd distributd key/value store. 
+
+See [etcd discovery](discovery_etcd/README.md)
+
+## Usage
+
+To develop for the Remote Service Admin implementation of Celix, one needs the following:
+
+1. A service **interface**, describes the actual service and methods[^1] that can be called. The service interface is needed at development time to allow a consistent definition;
+2. A service **implementation**, when exporting it as remote service. A service endpoint is needed to delegate remote requests to your service implementation;
+3. A service **endpoint**, which will be installed by Celix when exporting a local service. The endpoint is responsible for calling the actual Celix service. Endpoint bundles are not needed when *only* importing services in Celix;
+4. A service **proxy**, which will be installed by Celix when importing a remote service. The proxy is responsible for marshalling and unmarshalling method invocations. Proxy bundles are not needed when *only* exposing services from Celix;
+5. A service **client** or user, which invokes methods on the local or remote service. The client is oblivious to the fact whether the service is running locally or remote.
+
+The Celix source repository provides a simple calculator example that shows all of the described parts:
+
+1. [The calculator service interface](http://svn.apache.org/repos/asf/celix/trunk/remote_services/calculator_service/public/include/calculator_service.h), providing three methods: one for adding two numbers, one for subtracting two numbers, and lastly, a method that calculates the square root of a number;
+2. [A calculator service implementation](http://svn.apache.org/repos/asf/celix/trunk/remote_services/calculator_service/private/src/calculator_impl.c) that simply implements the three previously described functions. To mark this service as "remote service", you need to add the `service.exported.interfaces` service property to its service registration. This way, the RSA implementation can expose it as remote service to others;
+3. [A service endpoint](http://svn.apache.org/repos/asf/celix/trunk/remote_services/calculator_endpoint/private/src/calculator_endpoint_impl.c), which is called by the RSA implementation to delegate a method invocation to an actual method in the service implementation. The service endpoint should be registered as `remote_endpoint` service, along with the `remote.interface` service property denoting which service interface this endpoint is capable of handling;
+4. [A service proxy (factory)](http://svn.apache.org/repos/asf/celix/trunk/remote_services/calculator_proxy/private/src/calculator_proxy_impl.c), called by the service client when it wants to invoke a method on a remoted service. The service proxy should be registered as `remote_proxy_factory` service along with the `proxy.interface` service property denoting which service interface the service proxy is capable of handling;
+5. [A service client](http://svn.apache.org/repos/asf/celix/trunk/remote_services/calculator_shell/private/src/add_command.c), that exposes the three calculator methods to as Celix shell commands. The implementation simply retrieves the calculator service as it would do with any other Celix service.
+
+If you have access to the Celix source repository, you can run the calculator example using various discovery implementations by invoking the `deploy` target. You can find the example deployments in the `CELIX_BUILD/deploy` directory. For example, to run the calculator example using the configured discovery mechanism, you should open two terminals. In the first terminal, type:
+
+    remote-service-cfg$ export RSA_PORT=18888
+    remote-service-cfg$ sh run.sh
+    ...
+    RSA: Export services (org.apache.celix.calc.api.Calculator)
+    ...
+    -> _
+
+In the second terminal, type:
+
+    remote-service-cfg-client$ export RSA_PORT=28888
+    remote-service-cfg-client$ sh run.sh
+    ...
+    RSA: Import service org.apache.celix.calc.api.Calculator
+    ...
+    -> _
+
+Now, if all went well, the client (second terminal) has three new shell commands, `add`, `sub` and `sqrt`, which you can use to invoke the calculator service:
+
+    -> add 3 5
+    CALCULATOR_SHELL: Add: 3.000000 + 5.000000 = 8.000000
+    -> _
+
+On the server side (first terminal), you can follow each invocation as well:
+
+    CALCULATOR_ENDPOINT: Handle request "add(DD)D" with data "{"m": "add(DD)D", "a": [3.0, 5.0]}"
+    CALCULATOR: Add: 3.000000 + 5.000000 = 8.000000
+
+Note that the `RSA_PORT` property needs to be unique for at least the client in order to communicate correctly when running the examples on the same machine. 
+
+## Building
+
+To build the Remote Service Admin Service the CMake build option "`BUILD_REMOTE_SERVICE_ADMIN`" has to be enabled.
+
+## Dependencies
+
+The Remote Service Admin Service depends on the following subprojects:
+
+- Framework
+- Utils
+
+Also the following libraries are required for building and/or using the Remote Service Admin Service subproject:
+
+- Jansson (build and runtime)
+- cURL (build and runtime)
+
+## RSA Bundles
+
+* [Remote Service Admin HTTP](../bundles/remote_services/remote_service_admin_http) - A HTTP implementation of the RSA.
+* [Remote Service Admin DFI](../bundles/remote_services/remote_service_admin_dfi) - A Dynamic Function Interface (DFI) implementation of the RSA.
+* [Remote Service Admin SHM](../bundles/remote_services/remote_service_admin_shm) - A shared memory implementation of the RSA.
+* [Topology Manager](../bundles/remote_services/topology_manager) - A (scoped) RSA Topology Manager implementation.
+* [Discovery Configured](../bundles/remote_services/discovery_configured) - A RSA Discovery implementation using static configuration (xml).
+* [Discovery Etcd](../bundles/remote_services/dicovery_etcd) - A RSA Discovery implementation using etcd.
+* [Discovery SHM](../bundles/remote_services/dicovery_shm) - A RSA Discovery implementation using shared memory.
+
+
+## Notes
+
+[^1]: Although C does not use the term "method", we use this term to align with the terminology used in the RSA specification. 

http://git-wip-us.apache.org/repos/asf/celix/blob/3f24edf0/documents/bundles/remote_services/discovery_etcd/README.md
----------------------------------------------------------------------
diff --git a/documents/bundles/remote_services/discovery_etcd/README.md b/documents/bundles/remote_services/discovery_etcd/README.md
new file mode 100644
index 0000000..e560264
--- /dev/null
+++ b/documents/bundles/remote_services/discovery_etcd/README.md
@@ -0,0 +1,29 @@
+<!--
+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.
+-->
+
+## Discovery ETCD
+
+The Celix Discovery ETCD bundles realizes OSGi services discovery based on [etcd](https://github.com/coreos/etcd).
+
+###### Properties
+    DISCOVERY_ETCD_ROOT_PATH             used path (default: discovery)
+    DEFAULT_ETCD_SERVER_IP               ip address of the etcd server (default: 127.0.0.1)
+    DEFAULT_ETCD_SERVER_PORT             port of the etcd server  (default: 2379)
+    DEFAULT_ETCD_TTL                     time-to-live for etcd entries in seconds (default: 30)
+
+###### CMake option
+    BUILD_RSA_DISCOVERY_ETCD=ON

http://git-wip-us.apache.org/repos/asf/celix/blob/3f24edf0/documents/bundles/remote_shell/README.md
----------------------------------------------------------------------
diff --git a/documents/bundles/remote_shell/README.md b/documents/bundles/remote_shell/README.md
new file mode 100644
index 0000000..af28421
--- /dev/null
+++ b/documents/bundles/remote_shell/README.md
@@ -0,0 +1,27 @@
+<!--
+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.
+-->
+
+## Remote Shell
+
+The Celix Remote Shell implements a telnet interface for the Celix Shell.
+
+###### Properties
+    remote.shell.telnet.port              used port (default: 6666)
+    remote.shell.telnet.maxconn           amount of concurrent connections (default: 2)
+
+###### CMake option
+    BUILD_REMOTE_SHELL=ON

http://git-wip-us.apache.org/repos/asf/celix/blob/3f24edf0/documents/bundles/shell/README.md
----------------------------------------------------------------------
diff --git a/documents/bundles/shell/README.md b/documents/bundles/shell/README.md
new file mode 100644
index 0000000..d9f38af
--- /dev/null
+++ b/documents/bundles/shell/README.md
@@ -0,0 +1,51 @@
+<!--
+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.
+-->
+
+# Shell
+
+The Celix Shell provides a service interface which can be used to interact with the Celix framework. Note that it does not offer a user interface. This modular approach enables having multiple frontends, e.g. textual or graphical.
+
+While the shell can be extended with additional commands by other bundles, it already offers some built in commands:
+
+    lb            list bundles
+    install       install additional bundle
+    uninstall     uninstall bundles
+    update        update bundles
+
+    start         start bundle
+    stop          stop bundle
+
+    help          displays available commands
+    inspect       inspect service and components
+
+    log           print log
+
+Further information about a command can be retrieved by using `help` combined with the command.
+
+## CMake options
+    BUILD_SHELL=ON
+
+## Shell Config Options
+
+- SHELL_USE_ANSI_COLORS - Whether shell command are allowed to use
+ANSI colors when printing info. default is true.
+
+## Using info
+
+If the Celix Shell is installed, 'find_package(Celix)' will set:
+ - The `Celix::shell_api` interface (i.e. header only) library target
+ - The `Celix::shell` bundle target

http://git-wip-us.apache.org/repos/asf/celix/blob/3f24edf0/documents/bundles/shell_tui/README.md
----------------------------------------------------------------------
diff --git a/documents/bundles/shell_tui/README.md b/documents/bundles/shell_tui/README.md
new file mode 100644
index 0000000..2b8984f
--- /dev/null
+++ b/documents/bundles/shell_tui/README.md
@@ -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.
+-->
+
+# Shell TUI
+
+The Celix Shell TUI implements a textual user interface for the Celix Shell.
+
+## CMake option
+    BUILD_SHELL_TUI=ON
+
+## Config options
+
+- SHELL_USE_ANSI_CONTROL_SEQUENCES - Wether to use ANSI control
+sequences to support backspace, left, up, etc key commands in the
+shell tui. Default is true if a TERM environment is set else false.
+
+## Using info
+
+If the Celix Shell TUI is installed, 'find_package(Celix)' will set:
+ - The `Celix::shell_tui` bundle target if the shell_tui is installed

http://git-wip-us.apache.org/repos/asf/celix/blob/3f24edf0/documents/getting_started/creating_a_simple_bundle.md
----------------------------------------------------------------------
diff --git a/documents/getting_started/creating_a_simple_bundle.md b/documents/getting_started/creating_a_simple_bundle.md
deleted file mode 100644
index 8f10869..0000000
--- a/documents/getting_started/creating_a_simple_bundle.md
+++ /dev/null
@@ -1,333 +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.
--->
-
-# Apache Celix - Getting Started Guide: Creating a Simple Bundle
-
-## Intro
-This page is intended for first time users of Apache Celix. It should guide you through building & installing Apache Celix, setting up a new project, creating your first bundle, setting up the project for use with Eclipse project and finally running and debugging your bundle directly from eclipse workspace. 
-
-If there are any uncertainties or question, don't hesitate to ask your questions in the [Apache Celix mailing](https://celix.apache.org/support/mailinglist.html).
-
-## Prerequisite
-Some experience with a command line interface (xterm) is expected to be able to follow this guide. 
-
-## Building and Installing
-For Apache Celix see [Building And Installing](../building/readme.md)
-
-## Installing Eclipse CDT
-Download the latest eclipse CDT at [http://www.eclipse.org](http://www.eclipse.org) and install it on your system. For more information on how the install eclipse on your system consult the eclipse documentation. For this getting started guide the luna version of eclipse was used ([linux](http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/luna/R/eclipse-cpp-luna-R-linux-gtk-x86_64.tar.gz) [mac](http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/luna/R/eclipse-cpp-luna-R-macosx-cocoa-x86_64.tar.gz)).
-
-## Apache Celix Bundle project
-Now that Apache Celix and Eclipse is installed, we are ready to create a new Apache Celix Bundle project.
-CMake is used as build tool for Apache Celix projects.
-
-To setup of the project, first create a new project dir to work in:
-
-```bash
-#Create a new workspace to work in, e.g:
-mkdir ${HOME}/workspace
-export WS=${HOME}/workspace
-
-mkdir ${WS}/myproject
-cd ${WS}/myproject
-```
-
-Then create a CMakeLists.txt file - the makefile variant of CMake -in project root directory:
-
-```cmake	
-#${WS}/myproject/CMakeLists.txt
-	
-#Part 1. setup project
-cmake_minimum_required(VERSION 3.4)
-project(myproject C CXX)
-
-#Part 2. setup compilers
-SET(CMAKE_C_FLAGS "-D_GNU_SOURCE -std=gnu99 -Wall -Werror -fPIC ${CMAKE_C_FLAGS}")
-SET(CMAKE_C_FLAGS_DEBUG "-g -DDEBUG")
-SET(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
-SET(CMAKE_CXX_FLAGS_DEBUG "-g -DDEBUG")
-
-#Part 3. Setup Celix cmake files, include paths, libraries and library paths
-#Note. If celix is not installed in /usr/local dir, change the location accordingly.
-set(CMAKE_MODULE_PATH  ${CMAKE_MODULE_PATH} "/usr/local/share/celix/cmake/modules")
-find_package(CELIX REQUIRED)
-include_directories(${CELIX_INCLUDE_DIRS})
-
-#Part 4. Choose C, C++ or both
-add_subdirectory(bundles/HelloWorld_c) #C
-add_subdirectory(bundles/HelloWorld_cxx) #C++
-```
-		
-This CMakeLists.txt file, sets up the following:
-
-* Part 1 
-	* The minimum cmake version required. 
-	* The project name
-	* The type of source files to expect, in this case C and C++.
-* Part 2
-    * Setup the compilers. c99 for C and C++11 for C++
-* Part 3
-	* The Celix package should be searched, configured and that the Celix package is required. 
-	* For all build targets in this CMakeLists.txt file or any sub directory CMakeLists.txt files the Apache Celix headers directory should be included.
-* Part 4
-	* The CMakelists.txt file in the subdirectory bundles/hello_world and/or bundles/HelloWorld should also be processed.
-	
-
-It is a good practice to create a separate CMakeLists.txt file for every bundle you want to build. For the hello_world bundle a CMakeLists.txt file should be created in the bundles/hello_world sub directory.
-
-Create the sub directory:
-
-```CMake
-#Create directory structure for the hello_world bundles
-cd ${WS}/myproject
-mkdir -p bundles/HelloWorld_c/src
-mkdir -p bundles/HelloWorld_cxx/src
-mkdir -p bundles/HelloWorld_cxx/include
-```
-
-
-And add the following CMakeLists.txt file for the C Bundle:
-
-```CMake	
-#${WS}/myproject/bundles/HelloWorld_c/CMakeLists.txt
-
-add_celix_bundle(HelloWorld_c
-    VERSION 1.0.0
-	SOURCES
-        src/HelloWorld_activator.c
-)	
-
-if(APPLE)
-    target_link_libraries(HelloWorld_c ${CELIX_LIBRARIES} -Wl,-all_load ${CELIX_DM_STATIC_LIB})
-else()  
-    target_link_libraries(HelloWorld_c -Wl,--no-undefined -Wl,--whole-archive ${CELIX_DM_STATIC_LIB} -Wl,--no-whole-archive ${CELIX_LIBRARIES})
-endif()
-```
-
-And/or the following CMakeLists.txt for the C++ bundle:
-
-```CMake
-#${WS}/myproject/bundles/HelloWorld_cxx/CMakeLists.txt
-
-add_celix_bundle(HelloWorld_cxx
-    VERSION 1.0.0
-	SOURCES
-        src/HelloWorldActivator.cc
-)
-target_include_directories(HelloWorld_cxx PRIVATE include)
-
-IF(APPLE)
-    target_link_libraries(HelloWorld_cxx ${CELIX_LIBRARIES} -Wl,-all_load ${CELIX_DM_STATIC_CXX_LIB})
-else()
-    target_link_libraries(HelloWorld_cxx -Wl,--no-undefined -Wl,--whole-archive ${CELIX_DM_STATIC_CXX_LIB} -Wl,--no-whole-archive ${CELIX_LIBRARIES})
-endif()
-```
-	
-These CMakeLists.txt files declare that the bundles should be build based on the build result (shared library) of the declared sources (in this case the `private/src/hello_world_activator.c` or `private/src/HelloWorldActivator.cc` source). 
-The `add_celix_bundle` CMake function is an Apache Celix specific CMake extension. 
-The library used for the bundle will also be linked against the dependency manager static library. 
-
-
-The Celix framework will install the bundle, load the bundle shared library and call the bundle activator entry symbols. These entries need to be programmed by the user. 
-Note that in these examples we use the dependency manager libraries (C and C++ version) instead of developing a "vanilla" bundle activator; 
-The dependency manager uses a higher abstraction and is more simple to understand and maintain, but not part of the OSGi standard.
-
-The C Bundle Activator:
-```C
-//${WS}/myproject/bundles/hello_world/src/HelloWorld_activator.c
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "dm_activator.h"
-
-
-struct userData {
-	    char * word;
-};
-
-celix_status_t dm_create(bundle_context_pt context, void **out) {
-	celix_status_t status = CELIX_SUCCESS;
-    struct userData* result = calloc(1, sizeof(*result));
-	if (result != NULL) {
-            result->word = "C World";
-            *out = result;
-    } else {
-            status = CELIX_START_ERROR;
-    }
-    return status;
-}
-
-celix_status_t dm_init(void* userData, bundle_context_pt context, dm_dependency_manager_pt manager) {
-    struct userData* data = (struct userData *) userData;
-    printf("Hello %s\n", data->word);
-    return CELIX_SUCCESS;
-}
-
-celix_status_t dm_destroy(void* userData, bundle_context_pt context, dm_dependency_manager_pt manager) {
-    free(userData);
-    return CELIX_SUCCESS;
-}
-```
-	
-The C++ Bundle Activator (header + source):
-```C++
-//${WS}/myproject/bundles/HelloWorld/include/HelloWorldActivator.h
-#ifndef HELLOWORLDACTIVATOR_H_
-#define HELLOWORLDACTIVATOR_H_
-
-#include "celix/dm/DmActivator.h"
-
-class HelloWorldActivator : public celix::dm::DmActivator {
-private:
-    const std::string word {"C++ World"};
-public:
-    HelloWorldActivator(celix::dm::DependencyManager& mng) : DmActivator {mng} {}
-    virtual void init();
-    virtual void deinit();
-};
-
-#endif //HELLOWORLDACTIVATOR_H_
-```
-
-```C++
-//${WS}/myproject/bundles/HelloWorld/private/src/HelloWorldActivator.cc
-#include "HelloWorldActivator.h"
-#include <iostream>
-
-DmActivator* DmActivator::create(celix::dm::DependencyManager& mng) {
-    return new HelloWorldActivator(mng);
-}
-
-void HelloWorldActivator::init() {
-    std::cout << "Hello " << this->word << "\n";
-}
-
-void HelloWorldActivator::deinit() {
-    //nothing to do
-}
-```
-	
-### Building
-One of the highly recommended features of CMake is the ability to do out of source builds, the benefit is that all of the build results will go in a separate directory without cluttering the (source) project.
-CMake also needs to able to find the cmake files Celix provides. This can be achieved by providing a CMAKE_MODULE_PATH variable (or setting the CMAKE_MODULE_PATH in the top level CMakeLists.txt). 
-For this example it is assumed that Celix in installed in `/usr/local`.
-To create the build directory and build the project execute the following commands:
-
-
-```bash
-cd ${WS}
-mkdir myproject-build
-cd myproject-build
-cmake ../myproject
-make all  
-```	
-
-Hopefully you will some some build results scrolling over the screen and actual build results in the build directory.
-There should be a HelloWorld_c.zip in the bundles/HelloWorld_c directory and a HelloWorld_cxx.zip in the bundles/HelloWorld_cxx directory,
-these are the actual bundles.
-A bundle on its own has no real value, so lets setup a Celix container and run Celix with these bundles.
-
-### Running
-
-To create a deployment for the hello world bundles two things are needed: 
-	
-1. Add a `add_celix_container` statement in the (top level) `CMakeLists.txt` file declaring what to deploy and under which name.
-
-```CMake
-#${WS}/myproject/CMakeLists.txt
-add_celix_container(myproject
-    CXX 
-    BUNDLES 
-	    ${CELIX_BUNDLES_DIR}/shell.zip 
-	    ${CELIX_BUNDLES_DIR}/shell_tui.zip
-	    ${CELIX_BUNDLES_DIR}/dm_shell.zip 
-	    HelloWorld_c #C bundle
-	    HelloWorld_cxx #C++ bundle
-)		
-```
-
-With the `add_celix_container` CMake function a Celix container will be configured, which bundles to use can be specified with absolute paths to
-bundle files (e.g. the shell.zip bundle) or Celix bundle CMake target (e.g. the HelloWorld_c bundle).
-
-Rerun make again form the build project. the make files generated by CMake will ensure cmake is run it again to update the actual make files.
-
-```bash 		
-cd ${WS}/myproject-build
-make -j
-```	
-
-Now a deploy directory myproject should be available in the deploy directory. This directory contains - among other files - a release.sh script. This can be used to setup the required environment variables (like LD_LIBRARY_PATH).
-
-```bash
-cd ${WS}/myproject-build/deploy/myproject
-./myproject
-```
-
-The HelloWorld_c and HelloWorld_cxx bundles should be started with their own famous "Hello World" text variant printed. One for the C and one for the C++ bundle.
-The shell and shell_tui bundle are also deployed and these can be used to query and control the running framework. Below some commands are shown for querying the installed bundles, listing all known shell command, showing the help of a specific command and stopping a specific bundle (note that bundle 0 is the framework "bundle"):
-
-```
-lb 
-help
-stop 0
-```
-	
-## Apache Celix Projects in Eclipse
-
-A nice feature of CMake is the ability to generate Eclipse project files, with this feature bundles can also be developed with use of Eclipse. This should help speed up the development process. 
-To get started change directory to the build directory and generate a eclipse project file.
-
-	cd ${WS}/myproject-build 
-	cmake -G "Eclipse CDT4 - Unix Makefiles" .
-	
-Startup the Eclipse EDI and a chose the `${WS}`
-
-![select workspace](getting_started_img1.png)
-
-Import the project with existing project. 
-
-![import project](getting_started_img2.png)
-
-To build the project, use Project->Build All.
-To run or debug from Eclipse navigate to the myproject deploy directory and right click on
-the 'myproject' executable and as "Local C/C++ Application"
-
-
-## Apache Celix Projects in CLion
-
-Using Apache Celix projects in CLion quite easy.
-Just use `File -> Open ...` and select a Apache Celix project.
-Because CLion is a IDE for CMake projects and Apache Celix projects are CMake projects this works out of the box.
-
-To run a Celix container just select the target from CLion and press Run.
-
- 
-## Next
-
-The get a complete overview of the available Celix CMake commands see:
- - [Apache Celix - Celix CMake Commands](../cmake_commands/readme.md)
-
-The idea behind service oriented programming is that functionality is provided and used by abstract service, which hide implementation details.
-For a guide how to provide and use services see
-
-- [Apache Celix - Getting Started Guide: Using Services with C](using_services_with_c.md)
-- [Apache Celix - Getting Started Guide: Using Services with C++](using_services_with_cxx.md)
- 
-
-
-	
-	

http://git-wip-us.apache.org/repos/asf/celix/blob/3f24edf0/documents/getting_started/readme.md
----------------------------------------------------------------------
diff --git a/documents/getting_started/readme.md b/documents/getting_started/readme.md
index 9692bc0..3ca5406 100644
--- a/documents/getting_started/readme.md
+++ b/documents/getting_started/readme.md
@@ -18,9 +18,9 @@ limitations under the License.
 # Apache Celix - Getting Started Guide
 
 ## Guides
-There are several guide to help you get started. The first guide is [Getting Started: Creating a simple bundle](creating_a_simple_bundle.md) 
+There are several guide to help you get started. The first guide is [Getting Started: Creating a simple bundle](simple_bundle/) 
 and this should get you started for your first C and/or C++ bundle.
 
 After that you can extend the example by using services with the following guides:
- - [Getting Started: Using Services with C](using_services_with_c.md) 
- - [Getting Started: Using Services with C++](using_services_with_cxx.md). 
+ - [Getting Started: Using Services with C](services_with/) 
+ - [Getting Started: Using Services with C++](services_with/). 

http://git-wip-us.apache.org/repos/asf/celix/blob/3f24edf0/documents/getting_started/services_with_c/readme.md
----------------------------------------------------------------------
diff --git a/documents/getting_started/services_with_c/readme.md b/documents/getting_started/services_with_c/readme.md
new file mode 100644
index 0000000..75692f9
--- /dev/null
+++ b/documents/getting_started/services_with_c/readme.md
@@ -0,0 +1,610 @@
+<!--
+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.
+-->
+
+# Apache Celix - Using Services with C
+
+## Intro 
+
+This example gives an overview for providing and using services with Apache Celix with C.
+
+## Services
+
+To start of, C services in Celix are just a pointer to a memory location registered in the service registry using a name and an optional set of key/value pairs. 
+
+By convention use the following service layout:
+
+```C
+//example.h
+#ifndef EXAMPLE_H_
+#define EXAMPLE_H_
+
+#define EXAMPLE_NAME            "org.example"
+#define EXAMPLE_VERSION         "1.0.0"
+#define EXAMPLE_CONSUMER_RANGE  "[1.0.0,2.0.0)"
+
+
+struct example_struct {
+	void *handle;
+	int (*method)(void *handle, int arg1, double arg2, double *result);
+} ;
+
+typedef struct example_struct example_t;
+
+#endif /* EXAMPLE_H_ */
+
+```
+
+
+For a Celix service a service name, service provider version and service consumer range should be declared.
+This is explicitly done with macros to prevent symbols so to that no linking dependencies are introduced.
+
+Then the actual struct for the service needs to be declared.
+The first element of the service struct should be a handle which can be used to store the service context, as convention we keep this pointer a void pointer to explicitly make it opaque.
+Note that also an opaque struct could be used (e.g a declared but not defined struct), but this can become problematic concerning components registering multiple services. 
+In that case explicit cast are needed to prevent warning and this can be confusing for the To prevent that issues void pointers are preferred.
+
+The rest of the element should be function pointers, which by convention should return an celix_status_t or int (which is technically the same). 
+The return value is used as a way of handling errors and is also needed to be able to make remote services (e.g. to be able to handle remote exceptions).
+
+The first argument of a service function should be the service handle and if there is a result the last argument should be a output parameter (either pre allocated (e.g. double *) or not (e.g. double **)).
+If the caller is not the owner of the output argument, a const pointer should be used (e.g. const char**). 
+It is also possible to create typedef of the pointer to the service struct (e.g. typedef struct example_struct example_t), but this is not needed. 
+
+In the Celix code base there are still service which uses a typedef with a pointer (e.g. typedef struct example_struct* example_struct_pt). This should be avoided, 
+because it is not possible to create the const pointer of those typedefs and it is not possible to include those typedef inside a existing struct without the needed for an additional malloc.
+
+### Semantic Versioning
+
+For versioning, semantic versioning should be used.
+
+A backward incompatible change should lead to a major version increase (e.g. 1.0.0 -> 2.0.0).
+For a C Service versioning is used to express binary compatibility (for the same platform / compiler), change that are incompatible are:
+
+- Removing a function
+- Adding a function to before any other function
+- Moving a function to an other location in the service struct
+- Changing the signature of a function
+- Changing the semantics of a argument (e.g. changing range input from "range in kilometer" to "range in meters")
+
+A backwards binary compatible change which extend the functionality should lead to a minor version increase (e.g. 1.0.0 -> 1.1.0).
+Changes considered backwards compatible which extend the functionality are:
+
+- Adding a function to the back of the service struct
+
+A backwards binary compatible change which does not extend the functionality should lead to a micro version increase (e.g. 1.0.0 -> 1.0.1).
+Changes considered backwards binary compatible which does not extend the functionality are:
+
+- Changes in the documentation
+- Renaming of arguments
+
+For C services generally platform specific calling convention are used therefore binary compatibility between service provider and consumers from different compilers is possible (e.g. gcc and clang), 
+ but not advisable
+
+ 
+## Components
+
+Component should use the ADT principle (see [ADT in C](http://inst.eecs.berkeley.edu/~selfpace/studyguide/9C.sg/Output/ADTs.in.C.html)).
+Note that is a convention.
+
+Components should have a `<cmpName>_create` and `<cmpName>_destroy` function.
+Components can have a `<cmpName>_start` and `<cmpName>_stop` function to start/stop threads or invoke functionality needed a fully created component. 
+The start function will only be called if all required service are available and the stop function will be called when some required are going or if the component needs to be stopped.
+
+Components can also have a `<cmpName>_init` and `<cmpName>_deinit` function which will be called before and after respectively the start and stop function. 
+The init/deinit function can be used to include (de)initialization which is not needed/wanted every time when service dependencies are being removed/added. 
+
+## Code Examples
+
+The next code blocks contains some code examples of components to indicate how to handle service dependencies, how to specify providing services and how to cope with locking/synchronizing.
+The complete example can be found [here](../../examples/services_example_c).
+
+The error checking is very minimal in these example to keep the focus on how to interact with services and how to deal with errors in C / Celix.
+
+
+### Bar example
+
+The bar example is a simple component providing the `example` service. 
+ 
+```C
+//bar.h
+#ifndef BAR_H_
+#define BAR_H_
+
+#include "example.h"
+
+typedef struct bar_struct bar_t;
+
+bar_t* bar_create(void);
+void bar_destroy(bar_t *self);
+
+int bar_method(bar_t *self, int arg1, double arg2, double *out);
+
+#endif //BAR_H_
+```
+
+```C
+//bar.c
+#define OK 0
+#define ERROR 1
+
+struct bar_struct {
+    double prefValue;
+};
+
+bar_t* bar_create(void) {
+    bar_t *self = calloc(1, sizeof(*self));
+    if (self != NULL) {
+        self->prefValue = 42;
+    } else {
+        //log error
+    }
+    return self;
+};
+
+void bar_destroy(bar_t *self) {
+    free(self);
+}
+
+int bar_method(bar_t *self, int arg1, double arg2, double *out) {
+    double update = (self->prefValue + arg1) * arg2;
+    self->prefValue = update;
+    *out = update;
+    return OK;
+}
+```
+
+```C
+//bar_activator.c
+#include "dm_activator.h"
+#include "bar.h"
+
+#include <stdlib.h>
+
+struct activator {
+	bar_t *bar;
+	example_t exampleService;
+};
+
+celix_status_t dm_create(bundle_context_pt context, void **userData) {
+    celix_status_t status = CELIX_SUCCESS;
+    struct activator *act = calloc(1, sizeof(*act));
+    if (act != NULL) {
+
+        act->bar = bar_create();
+        act->exampleService.handle = act->bar;
+        act->exampleService.method = (void*) bar_method;
+
+        if (act->bar != NULL) {
+            *userData = act;
+        } else {
+            free(act);
+        }
+    } else {
+        status = CELIX_ENOMEM;
+	}
+	return status;
+}
+
+celix_status_t dm_init(void *userData, bundle_context_pt context, dm_dependency_manager_pt manager) {
+    celix_status_t status = CELIX_SUCCESS;
+    struct activator *activator = userData;
+
+    dm_component_pt cmp = NULL;
+    component_create(context, "BAR", &cmp);
+    component_setImplementation(cmp, activator->bar);
+    component_addInterface(cmp, EXAMPLE_NAME, EXAMPLE_VERSION, &activator->exampleService, NULL);
+
+    dependencyManager_add(manager, cmp);
+    return status;
+}
+
+celix_status_t dm_destroy(void *userData, bundle_context_pt context, dm_dependency_manager_pt manager) {
+    celix_status_t status = CELIX_SUCCESS;
+    struct activator *activator = userData;
+    bar_destroy(activator->bar);
+    free(activator);
+    return status;
+};
+```
+
+### Foo1 example
+
+The Foo1 example shows how add a service dependency, implement the callback, invoke a service and how to protect the usage of service with use of a mutex.
+
+```C
+//foo1.h
+#ifndef FOO1_H_
+#define FOO1_H_
+
+#include "example.h"
+
+typedef struct foo1_struct foo1_t;
+
+foo1_t* foo1_create(void);
+void foo1_destroy(foo1_t *self);
+
+int foo1_start(foo1_t *self);
+int foo1_stop(foo1_t *self);
+
+int foo1_setExample(foo1_t *self, const example_t *example);
+
+
+#endif //FOO1_H_
+```
+
+```C
+//foo1.c
+#include "foo1.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <signal.h>
+#include <stdbool.h>
+#include <pthread.h>
+#include <assert.h>
+
+
+#define OK 0
+#define ERROR 1
+
+static void* foo1_thread(void*);
+
+struct foo1_struct {
+    const example_t *example;
+    pthread_mutex_t mutex; //protecting example
+    pthread_t thread;
+    bool running;
+};
+
+foo1_t* foo1_create(void) {
+    foo1_t *self = calloc(1, sizeof(*self));
+    if (self != NULL) {
+        pthread_mutex_init(&self->mutex, NULL);
+        self->running = false;
+    } else {
+        //log error
+    }
+    return self;
+};
+
+void foo1_destroy(foo1_t *self) {
+    assert(!self->running);
+    pthread_mutex_destroy(&self->mutex);
+    free(self);
+}
+
+int foo1_start(foo1_t *self) {
+    self->running = true;
+    pthread_create(&self->thread, NULL, foo1_thread, self);
+    return OK;
+}
+
+int foo1_stop(foo1_t *self) {
+    self->running = false;
+    pthread_kill(self->thread, SIGUSR1);
+    pthread_join(self->thread, NULL);
+    return OK;
+}
+
+int foo1_setExample(foo1_t *self, const example_t *example) {
+    pthread_mutex_lock(&self->mutex);
+    self->example = example; //NOTE could be NULL if req is not mandatory
+    pthread_mutex_unlock(&self->mutex);
+    return OK;
+}
+
+static void* foo1_thread(void *userdata) {
+    foo1_t *self = userdata;
+    double result;
+    int rc;
+    while (self->running) {
+        pthread_mutex_lock(&self->mutex);
+        if (self->example != NULL) {
+            rc = self->example->method(self->example->handle, 1, 2.0, &result);
+            if (rc == 0) {
+                printf("Result is %f\n", result);
+            } else {
+                printf("Error invoking method for example\n");
+            }
+        }
+        pthread_mutex_unlock(&self->mutex);
+        usleep(10000000);
+    }
+    return NULL;
+}
+```
+
+```C
+//foo1_activator.c
+#include "dm_activator.h"
+#include "foo1.h"
+
+#include <stdlib.h>
+
+struct activator {
+	foo1_t *foo;
+};
+
+celix_status_t dm_create(bundle_context_pt context, void **userData) {
+    celix_status_t status = CELIX_SUCCESS;
+    struct activator *act = calloc(1, sizeof(*act));
+    if (act != NULL) {
+        act->foo = foo1_create();
+        if (act->foo != NULL) {
+            *userData = act;
+        } else {
+            free(act);
+        }
+    } else {
+        status = CELIX_ENOMEM;
+    }
+    return status;
+}
+
+celix_status_t dm_init(void *userData, bundle_context_pt context, dm_dependency_manager_pt manager) {
+    celix_status_t status = CELIX_SUCCESS;
+    struct activator *activator = userData;
+
+    dm_component_pt cmp = NULL;
+    component_create(context, "FOO1", &cmp);
+    component_setImplementation(cmp, activator->foo);
+
+    /*
+    With the component_setCallbacksSafe we register callbacks when a component is started / stopped using a component
+     with type foo1_t*
+    */
+    component_setCallbacksSafe(cmp, foo1_t*, NULL, foo1_start, foo1_stop, NULL);
+
+    dm_service_dependency_pt dep = NULL;
+    serviceDependency_create(&dep);
+    serviceDependency_setRequired(dep, true);
+    serviceDependency_setService(dep, EXAMPLE_NAME, EXAMPLE_CONSUMER_RANGE, NULL);
+    serviceDependency_setStrategy(dep, DM_SERVICE_DEPENDENCY_STRATEGY_LOCKING);
+
+    /*
+    With the serviceDependency_setCallbacksSafe we register callbacks when a service
+    is added and about to be removed for the component type foo1_t* and service type example_t*.
+
+    We should protect the usage of the
+    service because after removal of the service the memory location of that service
+    could be freed
+    */
+    serviceDependency_setCallbacksSafe(dep, foo1_t*, const example_t*, foo1_setExample, NULL, NULL, NULL, NULL);
+    component_addServiceDependency(cmp, dep);
+
+    dependencyManager_add(manager, cmp);
+
+    return status;
+}
+
+celix_status_t dm_destroy(void *userData, bundle_context_pt context, dm_dependency_manager_pt manager) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator *activator = userData;
+	foo1_destroy(activator->foo);
+	free(activator);
+	return status;
+};
+
+```
+
+### Foo2 example
+
+The Foo2 example shows how to cope with multiple services and how to remove the need for locking by ensuring only access to the services and the services container by a single thread.
+
+```C
+//foo2.h
+#ifndef FOO2_H_
+#define FOO2_H_
+
+#include "example.h"
+
+typedef struct foo2_struct foo2_t;
+
+foo2_t* foo2_create(void);
+void foo2_destroy(foo2_t *self);
+
+int foo2_start(foo2_t *self);
+int foo2_stop(foo2_t *self);
+
+int foo2_addExample(foo2_t *self, const example_t *example);
+int foo2_removeExample(foo2_t *self, const example_t *example);
+
+#endif //FOO2_H_
+```
+
+```C
+//foo2.c
+#include "foo2.h"
+
+#include "array_list.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <signal.h>
+#include <stdbool.h>
+#include <pthread.h>
+#include <assert.h>
+
+
+#define OK 0
+#define ERROR 1
+
+static void* foo2_thread(void*);
+
+struct foo2_struct {
+    array_list_pt examples;
+    pthread_t thread;
+    bool running;
+};
+
+foo2_t* foo2_create(void) {
+    foo2_t *self = calloc(1, sizeof(*self));
+    if (self != NULL) {
+        self->examples = NULL;
+        arrayList_create(&self->examples);
+        self->running = false;
+    } else {
+        //log error
+    }
+    return self;
+};
+
+void foo2_destroy(foo2_t *self) {
+    assert(!self->running);
+    arrayList_destroy(self->examples);
+    free(self);
+}
+
+int foo2_start(foo2_t *self) {
+    self->running = true;
+    pthread_create(&self->thread, NULL, foo2_thread, self);
+    return OK;
+}
+
+int foo2_stop(foo2_t *self) {
+    self->running = false;
+    pthread_kill(self->thread, SIGUSR1);
+    pthread_join(self->thread, NULL);
+    return OK;
+}
+
+int foo2_addExample(foo2_t *self, const example_t *example) {
+    //NOTE foo2 is suspended -> thread is not running  -> safe to update
+    int status = OK;
+    status = arrayList_add(self->examples, (void *)example);
+    return status;
+}
+
+int foo2_removeExample(foo2_t *self, const example_t *example) {
+    //NOTE foo2 is suspended -> thread is not running  -> safe to update
+    int status = OK;
+    status = arrayList_removeElement(self->examples, (void*)example);
+    return status;
+}
+
+static void* foo2_thread(void *userdata) {
+    foo2_t *self = userdata;
+    double result;
+    int rc;
+    while (self->running) {
+        unsigned int size = arrayList_size(self->examples);
+        int i;
+        for (i = 0; i < size; i += 1) {
+            const example_t* example = arrayList_get(self->examples, i);
+            rc = example->method(example->handle, 1, 2.0, &result);
+            if (rc == 0) {
+                printf("Result is %f\n", result);
+            } else {
+                printf("Error invoking method for example\n");
+            }
+        }
+        usleep(10000000);
+    }
+    return NULL;
+
+```
+
+```C
+//foo2_activator.c
+#include "dm_activator.h"
+#include "foo2.h"
+
+#include <stdlib.h>
+
+struct activator {
+	foo2_t *foo;
+};
+
+celix_status_t dm_create(bundle_context_pt context, void **userData) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator *act = calloc(1, sizeof(*act));
+	if (act != NULL) {
+		act->foo = foo2_create();
+        if (act->foo != NULL) {
+            *userData = act;
+        } else {
+            free(act);
+        }
+	} else {
+		status = CELIX_ENOMEM;
+	}
+	return status;
+}
+
+celix_status_t dm_init(void *userData, bundle_context_pt context, dm_dependency_manager_pt manager) {
+    celix_status_t status = CELIX_SUCCESS;
+	struct activator *activator = userData;
+
+	dm_component_pt cmp = NULL;
+	component_create(context, "FOO2", &cmp);
+	component_setImplementation(cmp, activator->foo);
+
+	/*
+	With the component_setCallbacksSafe we register callbacks when a component is started / stopped using a component
+	 with type foo1_t*
+	*/
+    component_setCallbacksSafe(cmp, foo2_t*, NULL, foo2_start, foo2_stop, NULL);
+
+	dm_service_dependency_pt dep = NULL;
+	serviceDependency_create(&dep);
+	serviceDependency_setRequired(dep, false);
+	serviceDependency_setService(dep, EXAMPLE_NAME, EXAMPLE_CONSUMER_RANGE, NULL);
+	serviceDependency_setStrategy(dep, DM_SERVICE_DEPENDENCY_STRATEGY_SUSPEND);
+
+	/*
+	With the serviceDependency_setCallbacksSafe we register callbacks when a service
+	is added and about to be removed for the component type foo1_t* and service type example_t*.
+
+	We should protect the usage of the
+ 	service because after removal of the service the memory location of that service
+	could be freed
+	*/
+    serviceDependency_setCallbacksSafe(dep, foo2_t*, const example_t*, NULL, foo2_addExample, NULL, foo2_removeExample, NULL);
+	component_addServiceDependency(cmp, dep);
+
+	dependencyManager_add(manager, cmp);
+
+    return status;
+}
+
+celix_status_t dm_destroy(void *userData, bundle_context_pt context, dm_dependency_manager_pt manager) {
+	celix_status_t status = CELIX_SUCCESS;
+	struct activator *activator = userData;
+	foo2_destroy(activator->foo);
+	free(activator);
+	return status;
+};
+```
+
+## Locking and Suspending
+ 
+As you may notice, the Foo1 example uses locks. 
+In principle, locking is necessary in order to ensure coherence in case service dependencies are removed/added/changed; on the other hands, locking increases latency and, when misused, can lead to poor performance. 
+For this reason, the serviceDependency interface gives the possibility to choose between a locking and suspend (a non-locking) strategy through the serviceDependency_setStrategy function, as is used in the Foo2 example.
+
+The locking strategy `DM_SERVICE_DEPENDENCY_STRATEGY_LOCKING` notifies the component in case the dependencies' set changes (e.g. a dependency is added/removed): the component is responsible for protecting via locks the dependencies' list and check (always under lock) if the service he's depending on is still available.
+The suspend or non-locking strategy `DM_SERVICE_DEPENDENCY_STRATEGY_SUSPEND` (default when no strategy is explicitly set) reliefs the programmer from dealing with service dependencies' consistency issues: in case this strategy is adopted, the component is stopped and restarted (i.e. temporarily suspended) upon service dependencies' changes.
+
+The suspend strategy has the advantage of reducing locks' usage: of course, suspending the component has its own overhead (e.g. stopping and restarting threads), but this overhead is "paid" only in case of changes in service dependencies, while the locking overhead is always paid.
+
+## See also
+
+See the [C Dependeny Manager](../../libs/dependency_manager/readme.md) and [C Dependency Manager example](../../examples/celix-examples/dm_example) for more information and a more complex working example.