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:46 UTC

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

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.