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/05/27 18:53:06 UTC

[58/60] [abbrv] celix git commit: Merge branch 'develop' into feature/CELIX-426-cxx-api

http://git-wip-us.apache.org/repos/asf/celix/blob/2e04253d/libs/framework/include/celix/Properties.h
----------------------------------------------------------------------
diff --cc libs/framework/include/celix/Properties.h
index 0000000,0000000..65fd4ef
new file mode 100644
--- /dev/null
+++ b/libs/framework/include/celix/Properties.h
@@@ -1,0 -1,0 +1,60 @@@
++/**
++ *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 CXX_CELIX_PROPERTIES_H
++#define CXX_CELIX_PROPERTIES_H
++
++#include <string>
++#include <map>
++
++namespace celix {
++
++    using Properties = std::map<std::string, std::string>;
++
++    inline const std::string& getProperty(const Properties& props, const std::string &key, const std::string &defaultValue) noexcept {
++        auto it = props.find(key);
++        if (it != props.end()) {
++            return props.at(key);
++        } else {
++            return defaultValue;
++        }
++    }
++
++    inline int getProperty(const Properties& props, const std::string &key, int defaultValue)  noexcept {
++        std::string val = getProperty(props, key, std::to_string(defaultValue));
++        return std::stoi(val, nullptr, 10);
++    }
++
++    inline unsigned int getProperty(const Properties& props, const std::string &key, unsigned int defaultValue) noexcept {
++        std::string val = getProperty(props, key, std::to_string(defaultValue));
++        return static_cast<unsigned  int>(std::stoul(val, nullptr, 10)); //NOTE no std::stou ??
++    }
++
++    inline long getProperty(const Properties& props, const std::string &key, long defaultValue) noexcept {
++        std::string val = getProperty(props, key, std::to_string(defaultValue));
++        return std::stol(val, nullptr, 10);
++    }
++
++    inline unsigned int getProperty(const Properties& props, const std::string &key, unsigned long defaultValue) noexcept {
++        std::string val = getProperty(props, key, std::to_string(defaultValue));
++        return std::stoul(val, nullptr, 10);
++    }
++}
++
++#endif //CXX_CELIX_PROPERTIES_H

http://git-wip-us.apache.org/repos/asf/celix/blob/2e04253d/libs/framework/include/celix/dm/Component.h
----------------------------------------------------------------------
diff --cc libs/framework/include/celix/dm/Component.h
index 0000000,06aaf20..0edc8e9
mode 000000,100644..100644
--- a/libs/framework/include/celix/dm/Component.h
+++ b/libs/framework/include/celix/dm/Component.h
@@@ -1,0 -1,234 +1,234 @@@
+ /**
+  * 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_DM_COMPONENT_H
 -#define CELIX_DM_COMPONENT_H
++#ifndef CXX_CELIX_DM_COMPONENT_H
++#define CXX_CELIX_DM_COMPONENT_H
+ 
+ #include "celix/dm/types.h"
+ #include "dm_component.h"
+ 
+ #include <map>
+ #include <string>
+ #include <vector>
+ 
+ namespace celix { namespace dm {
+ 
+     class BaseComponent {
+     private:
+         bundle_context_pt context {nullptr};
+         dm_component_pt cCmp {nullptr};
+     public:
+         BaseComponent(const bundle_context_pt con, std::string name) : context{con}, cCmp{nullptr} {
+             component_create(this->context, name.c_str(), &this->cCmp);
+             component_setImplementation(this->cCmp, this);
+         }
+         virtual ~BaseComponent() {}
+ 
+         BaseComponent(const BaseComponent&) = delete;
+         BaseComponent& operator=(const BaseComponent&) = delete;
+ 
+         /**
+          * Returns the C DM Component
+          */
+         dm_component_pt cComponent() const { return this->cCmp; }
+ 
+         /**
+          * Returns the C bundle context
+          */
+         bundle_context_pt bundleContext() const { return this->context; }
+     };
+         
+ 
+     template<class T>
+     class Component : public BaseComponent {
+         using type = T;
+     private:
+         std::unique_ptr<T> instance {nullptr};
+         std::shared_ptr<T> sharedInstance {nullptr};
+         std::vector<T> valInstance {};
+         std::vector<std::shared_ptr<BaseServiceDependency>> dependencies {};
+ 
+         void (T::*initFp)() = {};
+         void (T::*startFp)() = {};
+         void (T::*stopFp)() = {};
+         void (T::*deinitFp)() = {};
+ 
+         int (T::*initFpNoExc)() = {};
+         int (T::*startFpNoExc)() = {};
+         int (T::*stopFpNoExc)() = {};
+         int (T::*deinitFpNoExc)() = {};
+     public:
+         Component(const bundle_context_pt context, std::string name);
+         virtual ~Component();
+ 
+         /**
+          * Creates a Component using the provided bundle context
+          * and component name.
+          * Will use new(nothrow) if exceptions are disabled.
+          * @return newly created DM Component or nullptr
+          */
+         static Component<T>* create(bundle_context_pt, std::string name);
+ 
+         /**
+          * Creates a Component using the provided bundle context.
+          * Will use new(nothrow) if exceptions are disabled.
+          * @return newly created DM Component or nullptr
+          */
+         static Component<T>* create(bundle_context_pt);
+ 
+         /**
+          * Wether the component is valid. Invalid component can occurs when no new components can be created and
+          * exceptions are not allowed.
+          * @return
+          */
+         bool isValid() const;
+ 
+         /**
+          * Get the component instance. If no instance is explicitly set with setInstance than a instance will be create
+          * using a default constructor.
+          *
+          * @return A reference to the component instance.
+          */
+         T& getInstance();
+ 
+         /**
+          * Set the component instance using a shared pointer.
+          *
+          * @return the DM Component reference for chaining (fluent API)
+          */
+         Component<T>& setInstance(std::shared_ptr<T> inst);
+ 
+         /**
+          * Set the component instance using a unique pointer.
+          *
+          * @return the DM Component reference for chaining (fluent API)
+          */
+         Component<T>& setInstance(std::unique_ptr<T>&& inst);
+ 
+         /**
+          * Set the component instance using a value or rval reference
+          * The DM Component will contain the instance.
+          *
+          * @return the DM Component reference for chaining (fluent API)
+          */
+         Component<T>& setInstance(T&& inst);
+ 
+         /**
+          * Adds a C++ interface to provide as service to the Celix framework.
+          *
+          * @param serviceName The service name to use
+          * @param version The version of the interface (e.g. "1.0.0"), can be an empty string
+          * @param properties To (meta) properties to provide with the service
+          * @return the DM Component reference for chaining (fluent API)
+          */
+         template<class I> Component<T>& addInterfaceWithName(const std::string serviceName, const std::string version = std::string{}, const Properties properties = Properties{});
+ 
+         /**
+          * Adds a C++ interface to provide as service to the Celix framework.
+          *
+          * @param serviceName The service name to use
+          * @param version The version of the interface (e.g. "1.0.0"), can be an empty string
+          * @param properties To (meta) properties to provide with the service
+          * @return the DM Component reference for chaining (fluent API)
+          */
+         template<class I> Component<T>& addInterface(const std::string version = std::string{}, const Properties properties = Properties{});
+ 
+         /**
+          * Adds a C interface to provide as service to the Celix framework.
+          *
+          * @param svc The service struct
+          * @param serviceName The service name to use
+          * @param version The version of the interface (e.g. "1.0.0"), can be an empty string
+          * @param properties To (meta) properties to provide with the service
+          */
+         template<class I> Component<T>& addCInterface(const I* svc, const std::string serviceName, const std::string version = std::string{}, const Properties properties = Properties{});
+ 
+ 
+         /**
+          * Creates and adds a C++ service dependency to the component
+          *
+          * @return the Service Dependency reference for chaining (fluent API)
+          */
+         template<class I>
+         ServiceDependency<T,I>& createServiceDependency(const std::string name = std::string{});
+ 
+         /**
+          Removes a C++ service dependency from the component
+          *
+          * @return the DM Component reference for chaining (fluent API)
+          */
+         template<class I>
+         Component<T>& remove(ServiceDependency<T,I>& dep);
+ 
+         /**
+          * Adds a C service dependency to the component
+          *
+          * @return the DM Component reference for chaining (fluent API)
+          */
+         template<typename I>
+         CServiceDependency<T,I>& createCServiceDependency(const std::string name);
+ 
+         /**
+          * Removes a C service dependency to the component
+          *
+          * @return the DM Component reference for chaining (fluent API)
+          */
+         template<typename I>
+         Component<T>& remove(CServiceDependency<T,I>& dep);
+ 
+         /**
+          * Set the callback for the component life cycle control
+          *
+          * @param init The init callback.
+          * @param start The start callback.
+          * @param stop The stop callback.
+          * @param deinit The deinit callback.
+          *
+          * @return the DM Component reference for chaining (fluent API)
+          */
+         Component<T>& setCallbacks(
+             void (T::*init)(),
+             void (T::*start)(),
+             void (T::*stop)(),
+             void (T::*deinit)()
+         );
+ 
+         /**
+          * Set the callback for the component life cycle control
+          * with a int return to indicate an error.
+          *
+          * @param init The init callback.
+          * @param start The start callback.
+          * @param stop The stop callback.
+          * @param deinit The deinit callback.
+          *
+          * @return the DM Component reference for chaining (fluent API)
+          */
+         Component<T>& setCallbacks(
+             int (T::*init)(),
+             int (T::*start)(),
+             int (T::*stop)(),
+             int (T::*deinit)()
+         );
+     };
+ }}
+ 
+ #include "celix/dm/Component_Impl.h"
+ 
 -#endif //CELIX_DM_COMPONENT_H
++#endif //CXX_CELIX_DM_COMPONENT_H

http://git-wip-us.apache.org/repos/asf/celix/blob/2e04253d/libs/framework/include/celix/dm/DependencyManager.h
----------------------------------------------------------------------
diff --cc libs/framework/include/celix/dm/DependencyManager.h
index 0000000,f90a03c..538edb1
mode 000000,100644..100644
--- a/libs/framework/include/celix/dm/DependencyManager.h
+++ b/libs/framework/include/celix/dm/DependencyManager.h
@@@ -1,0 -1,150 +1,149 @@@
+ /**
+  * 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 CXX_CELIX_DM_DEPENDENCYMANAGER_H
++#define CXX_CELIX_DM_DEPENDENCYMANAGER_H
++
+ 
+ #include "celix/dm/types.h"
+ #include "celix/dm/Component.h"
+ #include "celix/dm/ServiceDependency.h"
+ 
 -#include "bundle_context.h"
+ #include "celix_bundle_context.h"
+ #include "dm_dependency_manager.h"
+ 
+ #include <vector>
+ #include <mutex>
+ 
 -#ifndef CELIX_DM_DEPENDENCYMANAGER_H
 -#define CELIX_DM_DEPENDENCYMANAGER_H
 -
+ namespace celix { namespace dm {
 -
++    
+     class DependencyManager {
+     public:
+         DependencyManager(bundle_context_pt ctx) : context(ctx) {
 -                this->cDepMan = celix_bundleContext_getDependencyManager(ctx);
++            this->cDepMan = celix_bundleContext_getDependencyManager(ctx);
+         }
 -
++        
+         virtual ~DependencyManager() {
 -                this->cDepMan = nullptr;
++            this->cDepMan = nullptr;
+         }
 -
++        
+         DependencyManager(DependencyManager&& mgr) : componentsMutex{} {
 -                std::lock_guard<std::recursive_mutex> lock(this->componentsMutex);
 -                mgr.context = this->context;
 -                mgr.queuedComponents = std::move(this->queuedComponents);
 -                mgr.startedComponents = std::move(this->startedComponents);
 -                mgr.cDepMan = this->cDepMan;
 -                this->cDepMan = nullptr;
 -                this->context = nullptr;
++            std::lock_guard<std::recursive_mutex> lock(this->componentsMutex);
++            mgr.context = this->context;
++            mgr.queuedComponents = std::move(this->queuedComponents);
++            mgr.startedComponents = std::move(this->startedComponents);
++            mgr.cDepMan = this->cDepMan;
++            this->cDepMan = nullptr;
++            this->context = nullptr;
+         }
+         DependencyManager& operator=(DependencyManager&&) = default;
 -
++        
+         DependencyManager(const DependencyManager&) = delete;
+         DependencyManager& operator=(const DependencyManager&) = delete;
 -
++        
+         bundle_context_pt bundleContext() const { return context; }
+         dm_dependency_manager_pt cDependencyManager() const { return cDepMan; }
 -
 -
++        
++        
+         /**
+          * Creates and adds a new DM Component for a component of type T.
+          *
+          * @return Returns a reference to the DM Component
+          */
+         template<class T>
+         Component<T>& createComponent(std::string name = std::string{});
 -
++        
+         /**
+          * Creates and adds a new DM Component for a component of type T and setting
+          * the instance using a unique ptr.
+          *
+          * @return Returns a reference to the DM Component
+          */
+         template<class T>
+         Component<T>& createComponent(std::unique_ptr<T>&& rhs, std::string name = std::string{});
 -
++        
+         /**
+          * Creates and adds a new DM Component for a component of type T and setting
+          * the instance using a shared ptr.
+          *
+          * @return Returns a reference to the DM Component
+          */
+         template<class T>
+         Component<T>& createComponent(std::shared_ptr<T> rhs, std::string name = std::string{});
 -
++        
+         /**
+          * Creates and adds a new DM Component for a component of type T and setting
+          * the instance.
+          *
+          * @return Returns a reference to the DM Component
+          */
+         template<class T>
+         Component<T>& createComponent(T rhs, std::string name = std::string{});
 -
++        
+         /**
+          * Starts the Dependency Manager
+          */
+         void start() {
 -                std::vector<std::unique_ptr<BaseComponent>> toBeStartedComponents {};
 -                {
 -                        std::lock_guard<std::recursive_mutex> lock(componentsMutex);
 -                        for (auto it = queuedComponents.begin(); it != queuedComponents.end(); ++it) {
 -                                toBeStartedComponents.push_back(std::move(*it));
 -                        }
 -                        queuedComponents.clear();
++            std::vector<std::unique_ptr<BaseComponent>> toBeStartedComponents {};
++            {
++                std::lock_guard<std::recursive_mutex> lock(componentsMutex);
++                for (auto it = queuedComponents.begin(); it != queuedComponents.end(); ++it) {
++                    toBeStartedComponents.push_back(std::move(*it));
+                 }
 -                for (auto it = toBeStartedComponents.begin(); it != toBeStartedComponents.end(); ++it) {
 -
 -                        dependencyManager_add(cDepMan, (*it)->cComponent());
 -                        {
 -                                std::lock_guard<std::recursive_mutex> lock(componentsMutex);
 -                                startedComponents.push_back(std::move(*it));
 -                        }
++                queuedComponents.clear();
++            }
++            for (auto it = toBeStartedComponents.begin(); it != toBeStartedComponents.end(); ++it) {
++                
++                dependencyManager_add(cDepMan, (*it)->cComponent());
++                {
++                    std::lock_guard<std::recursive_mutex> lock(componentsMutex);
++                    startedComponents.push_back(std::move(*it));
+                 }
++            }
+         }
 -
++        
+         /**
+          * Removes a component from the  Dependency Manager and destroys it
+          */
+         template<typename T>
+         void destroyComponent(Component<T> &component) {
+             dependencyManager_remove(cDepMan, component.cComponent());
+         }
 -
++        
+         /**
+          * Stops the Dependency Manager
+          */
+         void stop() {
 -                dependencyManager_removeAllComponents(cDepMan);
 -                queuedComponents.clear();
 -                startedComponents.clear();
++            dependencyManager_removeAllComponents(cDepMan);
++            queuedComponents.clear();
++            startedComponents.clear();
+         }
+     private:
+         bundle_context_pt context {nullptr};
+         std::vector<std::unique_ptr<BaseComponent>> queuedComponents {};
+         std::vector<std::unique_ptr<BaseComponent>> startedComponents {};
+         dm_dependency_manager_pt cDepMan {nullptr};
+         std::recursive_mutex componentsMutex{};
+     };
 -
++    
+ }}
+ 
+ #include "celix/dm/DependencyManager_Impl.h"
+ 
 -#endif //CELIX_DM_DEPENDENCYMANAGER_H
++#endif //CXX_CELIX_DM_DEPENDENCYMANAGER_H

http://git-wip-us.apache.org/repos/asf/celix/blob/2e04253d/libs/framework/include/celix/dm/DmActivator.h
----------------------------------------------------------------------
diff --cc libs/framework/include/celix/dm/DmActivator.h
index 0000000,d7aac3c..ee8cde7
mode 000000,100644..100644
--- a/libs/framework/include/celix/dm/DmActivator.h
+++ b/libs/framework/include/celix/dm/DmActivator.h
@@@ -1,0 -1,97 +1,97 @@@
+ /**
+  * 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_DM_ACTIVATOR_H
 -#define CELIX_DM_ACTIVATOR_H
++#ifndef CXX_CELIX_DM_ACTIVATOR_H
++#define CXX_CELIX_DM_ACTIVATOR_H
+ 
+ 
+ #include <utility>
+ 
+ #include "celix/dm/DependencyManager.h"
+ #include "bundle_activator.h"
+ 
+ namespace celix { namespace dm {
+ 
+     class DmActivator {
+     public:
+         DmActivator(DependencyManager& m) : mng(m), ctx{m.bundleContext()}  {}
+         virtual ~DmActivator() = default;
+ 
+         DmActivator(const DmActivator&) = delete;
+         DmActivator& operator=(const DmActivator&) = delete;
+ 
+         DependencyManager& manager() const { return this->mng; }
+ 
+         bundle_context_pt context() const { return this->ctx; }
+ 
+         /**
+          * The init of the DM Activator. Should be overridden by the bundle specific DM activator.
+          *
+          * @param manager A reference to the  Dependency Manager
+          */
+         virtual void init() {};
+ 
+         /**
+          * The init of the DM Activator. Can be overridden by the bundle specific DM activator.
+          *
+          * @param manager A reference to the  Dependency Manager
+          */
+         virtual void deinit() {};
+ 
+         /**
+          * The static method to create a new DM activator.
+          * NOTE that this method in intentionally not implemented in the C++ Dependency Manager library.
+          * This should be done by the bundle specific DM activator.
+          *
+          * @param mng A reference to the Dependency Manager
+          * @returns A pointer to a DmActivator. The Dependency Manager is responsible for deleting the pointer when the bundle is stopped.
+          */
+         static DmActivator* create(DependencyManager& mng);
+ 
+     protected:
+         DependencyManager& mng;
+         bundle_context_pt ctx;
+     private:
+         int start() {
+             celix_status_t status = CELIX_SUCCESS;
+             this->init();
+             this->mng.start();
+ 
+             return status;
+         }
+ 
+         int stop() {
+             celix_status_t status = CELIX_SUCCESS;
+ 
+             this->deinit();
+ 
+             // Remove all components
+             dependencyManager_removeAllComponents(this->mng.cDependencyManager());
+ 
+             return status;
+         }
+ 
+         friend int ::bundleActivator_create(::bundle_context_pt, void**);
+         friend int ::bundleActivator_start(void*, ::bundle_context_pt);
+         friend int ::bundleActivator_stop(void*, ::bundle_context_pt);
+         friend int ::bundleActivator_destroy(void*, ::bundle_context_pt);
+     };
+ }}
+ 
 -#endif //CELIX_DM_ACTIVATOR_H
++#endif //CXX_CELIX_DM_ACTIVATOR_H

http://git-wip-us.apache.org/repos/asf/celix/blob/2e04253d/libs/framework/include/celix/dm/Properties.h
----------------------------------------------------------------------
diff --cc libs/framework/include/celix/dm/Properties.h
index 0000000,bb4fd78..fc485ca
mode 000000,100644..100644
--- a/libs/framework/include/celix/dm/Properties.h
+++ b/libs/framework/include/celix/dm/Properties.h
@@@ -1,0 -1,30 +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.
+  */
+ 
 -#ifndef CELIX_DM_PROPERTIES_H
 -#define CELIX_DM_PROPERTIES_H
++#ifndef CXX_CELIX_DM_PROPERTIES_H
++#define CXX_CELIX_DM_PROPERTIES_H
+ 
 -#include <map>
 -#include <string>
++#include "celix/Properties.h"
+ 
+ namespace celix { namespace dm {
 -    using Properties = std::map<std::string, std::string>;
++    using Properties = celix::Properties;
+ }}
+ 
 -#endif //CELIX_DM_PROPERTIES_H
++#endif //CXX_CELIX_DM_PROPERTIES_H

http://git-wip-us.apache.org/repos/asf/celix/blob/2e04253d/libs/framework/include/celix/dm/ServiceDependency.h
----------------------------------------------------------------------
diff --cc libs/framework/include/celix/dm/ServiceDependency.h
index 0000000,f439b82..b2b6afb
mode 000000,100644..100644
--- a/libs/framework/include/celix/dm/ServiceDependency.h
+++ b/libs/framework/include/celix/dm/ServiceDependency.h
@@@ -1,0 -1,326 +1,326 @@@
+ /**
+  * 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_DM_SERVICEDEPENDENCY_H
 -#define CELIX_DM_SERVICEDEPENDENCY_H
++#ifndef CXX_CELIX_DM_SERVICEDEPENDENCY_H
++#define CXX_CELIX_DM_SERVICEDEPENDENCY_H
+ 
+ #include "dm_service_dependency.h"
+ #include "celix/dm/types.h"
+ 
+ #include <map>
+ #include <string>
+ #include <list>
+ #include <tuple>
+ #include <memory>
+ #include <iostream>
+ #include <functional>
+ 
+ namespace celix { namespace dm {
+ 
+     class DependencyManager; //forward declaration
+ 
+     enum class DependencyUpdateStrategy {
+         suspend,
+         locking
+     };
+ 
+     class BaseServiceDependency {
+     protected:
+         const bool valid;
+         dm_service_dependency_pt cServiceDep {nullptr};
+ 
+         void setDepStrategy(DependencyUpdateStrategy strategy) {
+             if (!valid) {
+                 return;
+             }
+             if (strategy == DependencyUpdateStrategy::locking) {
+                 serviceDependency_setStrategy(this->cServiceDependency(), DM_SERVICE_DEPENDENCY_STRATEGY_LOCKING);
+             } else if (strategy == DependencyUpdateStrategy::suspend) {
+                 serviceDependency_setStrategy(this->cServiceDependency(), DM_SERVICE_DEPENDENCY_STRATEGY_SUSPEND);
+             } else {
+                 std::cerr << "Unexpected dependency update strategy. Cannot convert for dm_depdendency\n";
+             }
+         }
+     public:
+         BaseServiceDependency(bool v)  : valid{v} {
+             if (this->valid) {
+                 serviceDependency_create(&this->cServiceDep);
+                 //NOTE using suspend as default strategy
+                 serviceDependency_setStrategy(this->cServiceDep,  DM_SERVICE_DEPENDENCY_STRATEGY_SUSPEND);
+             }
+         }
+ 
+         virtual ~BaseServiceDependency() = default;
+ 
+         BaseServiceDependency(const BaseServiceDependency&) = delete;
+         BaseServiceDependency& operator=(const BaseServiceDependency&) = delete;
+ 
+         /**
+          * Wether the service dependency is valid.
+          */
+         bool isValid() const { return valid; }
+ 
+         /**
+          * Returns the C DM service dependency
+          */
+         dm_service_dependency_pt cServiceDependency() const { return cServiceDep; }
+     };
+ 
+     template<class T>
+     class TypedServiceDependency :  public BaseServiceDependency {
+         using cmpType = T;
+     protected:
+         T* componentInstance {nullptr};
+     public:
+         TypedServiceDependency(bool valid) : BaseServiceDependency(valid) {}
+         virtual ~TypedServiceDependency() = default;
+ 
+         TypedServiceDependency(const TypedServiceDependency&) = delete;
+         TypedServiceDependency& operator=(const TypedServiceDependency&) = delete;
+         TypedServiceDependency(TypedServiceDependency&&) = default;
+         TypedServiceDependency& operator=(TypedServiceDependency&&) = default;
+ 
+         /**
+          * Set the component instance with a pointer
+          */
+         void setComponentInstance(T* cmp) { componentInstance = cmp;}
+     };
+ 
+     template<class T, typename I>
+     class CServiceDependency : public TypedServiceDependency<T> {
+         using type = I;
+     public:
+         CServiceDependency(const std::string name, bool valid = true);
+         virtual ~CServiceDependency() = default;
+ 
+         /**
+          * Sets the service version range for the C service dependency.
+          *
+          * @param serviceVersionRange The service version range, can be an empty string
+          * @return the C service dependency reference for chaining (fluent API)
+          */
+         CServiceDependency<T,I>& setVersionRange(const std::string serviceVersionRange);
+ 
+         /**
+          * Sets the service filter for the C service dependency.
+          *
+          * @param filter The (additional) filter to use (e.g. "(location=front)")
+          * @return the C service dependency reference for chaining (fluent API)
+          */
+         CServiceDependency<T,I>& setFilter(const std::string filter);
+ 
+         /**
+          * Specify if the service dependency is required. Default is false
+          *
+          * @return the C service dependency reference for chaining (fluent API)
+          */
+         CServiceDependency<T,I>& setRequired(bool req);
+ 
+         /**
+          * Specify if the update strategy to use
+          *
+          * @return the C service dependency reference for chaining (fluent API)
+          */
+         CServiceDependency<T,I>& setStrategy(DependencyUpdateStrategy strategy);
+ 
+         /**
+          * Set the set callback for when the service dependency becomes available
+          *
+          * @return the C service dependency reference for chaining (fluent API)
+          */
+         CServiceDependency<T,I>& setCallbacks(void (T::*set)(const I* service));
+ 
+         /**
+          * Set the set callback for when the service dependency becomes available
+          *
+          * @return the C service dependency reference for chaining (fluent API)
+          */
+         CServiceDependency<T,I>& setCallbacks(void (T::*set)(const I* service, Properties&& properties));
+ 
+         /**
+          * Set the set callback for when the service dependency becomes available
+          *
+          * @return the C service dependency reference for chaining (fluent API)
+          */
+         CServiceDependency<T,I>& setCallbacks(std::function<void(const I* service, Properties&& properties)> set);
+ 
+         /**
+          * Set the add and remove callback for when the services of service dependency are added or removed.
+          *
+          * @return the C service dependency reference for chaining (fluent API)
+          */
+         CServiceDependency<T,I>& setCallbacks(void (T::*add)(const I* service),  void (T::*remove)(const I* service));
+ 
+         /**
+          * Set the add and remove callback for when the services of service dependency are added or removed.
+          *
+          * @return the C service dependency reference for chaining (fluent API)
+          */
+         CServiceDependency<T,I>& setCallbacks(
+                 void (T::*add)(const I* service, Properties&& properties),
+                 void (T::*remove)(const I* service, Properties&& properties)
+         );
+ 
+         /**
+          * Set the add and remove callback for when the services of service dependency are added or removed.
+          *
+          * @return the C service dependency reference for chaining (fluent API)
+          */
+         CServiceDependency<T,I>& setCallbacks(
+ 		std::function<void(const I* service, Properties&& properties)> add,
+ 		std::function<void(const I* service, Properties&& properties)> remove
+         );
+ 
+         /**
+          * Specify if the service dependency should add a service.lang filter part if it is not already present
+          * For C service dependencies 'service.lang=C' will be added.
+          */
+         CServiceDependency<T,I>& setAddLanguageFilter(bool addLang);
+     private:
+         std::string name {};
+         std::string filter {};
+         std::string versionRange {};
+ 
+         std::function<void(const I* service, Properties&& properties)> setFp{nullptr};
+         std::function<void(const I* service, Properties&& properties)> addFp{nullptr};
+         std::function<void(const I* service, Properties&& properties)> removeFp{nullptr};
+ 
+         void setupCallbacks();
+         int invokeCallback(std::function<void(const I*, Properties&&)> fp, service_reference_pt  ref, const void* service);
+ 
+         void setupService();
+     };
+ 
+     template<class T, class I>
+     class ServiceDependency : public TypedServiceDependency<T> {
+         using type = I;
+     public:
+         ServiceDependency(const std::string name = std::string{}, bool valid = true);
+         virtual ~ServiceDependency() = default;
+ 
+         /**
+          * Set the service name of the service dependency.
+          *
+          * @return the C++ service dependency reference for chaining (fluent API)
+          */
+         ServiceDependency<T,I>& setName(const std::string name);
+ 
+         /**
+          * Set the service filter of the service dependency.
+          *
+          * @return the C++ service dependency reference for chaining (fluent API)
+          */
+         ServiceDependency<T,I>& setFilter(const std::string filter);
+ 
+         /**
+          * Set the service version range of the service dependency.
+          *
+          * @return the C++ service dependency reference for chaining (fluent API)
+          */
+         ServiceDependency<T,I>& setVersionRange(const std::string versionRange);
+ 
+         /**
+          * Set the set callback for when the service dependency becomes available
+          *
+          * @return the C++ service dependency reference for chaining (fluent API)
+          */
+         ServiceDependency<T,I>& setCallbacks(void (T::*set)(I* service));
+ 
+         /**
+          * Set the set callback for when the service dependency becomes available
+          *
+          * @return the C++ service dependency reference for chaining (fluent API)
+          */
+         ServiceDependency<T,I>& setCallbacks(void (T::*set)(I* service, Properties&& properties));
+ 
+         /**
+          * Set the set callback for when the service dependency becomes available
+          *
+          * @return the C service dependency reference for chaining (fluent API)
+          */
+         ServiceDependency<T,I>& setCallbacks(std::function<void(I* service, Properties&& properties)> set);
+ 
+         /**
+          * Set the add and remove callback for when the services of service dependency are added or removed.
+          *
+          * @return the C++ service dependency reference for chaining (fluent API)
+          */
+         ServiceDependency<T,I>& setCallbacks(void (T::*add)(I* service),  void (T::*remove)(I* service));
+ 
+         /**
+          * Set the add and remove callback for when the services of service dependency are added or removed.
+          *
+          * @return the C++ service dependency reference for chaining (fluent API)
+          */
+         ServiceDependency<T,I>& setCallbacks(
+                 void (T::*add)(I* service, Properties&& properties),
+                 void (T::*remove)(I* service, Properties&& properties)
+         );
+ 
+         /**
+          * Set the add and remove callback for when the services of service dependency are added or removed.
+          *
+          * @return the C service dependency reference for chaining (fluent API)
+          */
+         ServiceDependency<T,I>& setCallbacks(
+ 		std::function<void(I* service, Properties&& properties)> add,
+ 		std::function<void(I* service, Properties&& properties)> remove
+         );
+ 
+         /**
+          * Specify if the service dependency is required. Default is false
+          *
+          * @return the C service dependency reference for chaining (fluent API)
+          */
+         ServiceDependency<T,I>& setRequired(bool req);
+ 
+         /**
+          * Specify if the update strategy to use
+          *
+          * @return the C service dependency reference for chaining (fluent API)
+          */
+         ServiceDependency<T,I>& setStrategy(DependencyUpdateStrategy strategy);
+ 
+         /**
+          * Specify if the service dependency should add a service.lang filter part if it is not already present
+          * For C++ service dependencies 'service.lang=C++' will be added.
+          * Should be called before
+          */
+         ServiceDependency<T,I>& setAddLanguageFilter(bool addLang);
+     private:
+         bool addCxxLanguageFilter {true};
+         std::string name {};
+         std::string filter {};
+         std::string versionRange {};
+         std::string modifiedFilter {};
+ 
+         std::function<void(I* service, Properties&& properties)> setFp{nullptr};
+         std::function<void(I* service, Properties&& properties)> addFp{nullptr};
+         std::function<void(I* service, Properties&& properties)> removeFp{nullptr};
+ 
+         void setupService();
+         void setupCallbacks();
+         int invokeCallback(std::function<void(I*, Properties&&)> fp, service_reference_pt  ref, const void* service);
+     };
+ }}
+ 
+ #include "celix/dm/ServiceDependency_Impl.h"
+ 
+ 
 -#endif //CELIX_DM_SERVICEDEPENDENCY_H
++#endif //CXX_CELIX_DM_SERVICEDEPENDENCY_H

http://git-wip-us.apache.org/repos/asf/celix/blob/2e04253d/libs/framework/include/celix/dm/types.h
----------------------------------------------------------------------
diff --cc libs/framework/include/celix/dm/types.h
index 0000000,43f0f04..8b7b120
mode 000000,100644..100644
--- a/libs/framework/include/celix/dm/types.h
+++ b/libs/framework/include/celix/dm/types.h
@@@ -1,0 -1,90 +1,90 @@@
+ /**
+  * Licensed to the Apache Software Foundation (ASF) under one
+  * or more contributor license agreements.  See the NOTICE file
+  * distributed with this work for additional information
+  * regarding copyright ownership.  The ASF licenses this file
+  * to you under the Apache License, Version 2.0 (the
+  * "License"); you may not use this file except in compliance
+  * with the License.  You may obtain a copy of the License at
+  *
+  *   http://www.apache.org/licenses/LICENSE-2.0
+  *
+  * Unless required by applicable law or agreed to in writing,
+  * software distributed under the License is distributed on an
+  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+  *  KIND, either express or implied.  See the License for the
+  * specific language governing permissions and limitations
+  * under the License.
+  */
+ 
 -#ifndef CELIX_DM_TYPES_H
 -#define CELIX_DM_TYPES_H
++#ifndef CXX_CELIX_DM_TYPES_H
++#define CXX_CELIX_DM_TYPES_H
+ 
+ #include <map>
+ #include <string>
+ #include <list>
+ #include <tuple>
+ #include <typeinfo>
+ #include <memory>
+ #include <cxxabi.h>
+ #include <string.h>
+ #include "celix/dm/Properties.h"
+ #include <stdlib.h>
+ #include <iostream>
+ 
+ namespace celix { namespace dm {
+     //forward declarations
+     class DependencyManager;
+ 
+ 
+     class BaseServiceDependency;
+ 
+     template<class T, typename I>
+     class CServiceDependency;
+ 
+     template<class T, class I>
+     class ServiceDependency;
+ 
+     /**
+      * Returns the deferred type name for the template I
+      */
+     template<typename INTERFACE_TYPENAME>
+     const std::string typeName() {
+         std::string result;
+ 
+ #ifdef __GXX_RTTI
+         result = typeid(INTERFACE_TYPENAME).name();
+         int status = 0;
+         char* demangled_name {abi::__cxa_demangle(result.c_str(), NULL, NULL, &status)};
+         if(status == 0) {
+             result = std::string{demangled_name};
+             free(demangled_name);
+         }
+ #else
+         const char *templateStr = "INTERFACE_TYPENAME = ";
+         const size_t templateStrLen = strlen(templateStr);
+ 
+         result = __PRETTY_FUNCTION__; //USING pretty function to retrieve the filled in template argument without using typeid()
+         size_t bpos = result.find(templateStr) + templateStrLen; //find begin pos after INTERFACE_TYPENAME = entry
+         size_t epos = bpos;
+         while (isalnum(result[epos]) || result[epos] == '_' || result[epos] == ':') {
+             epos += 1;
+         }
+         size_t len = epos - bpos;
+         result = result.substr(bpos, len);
+ #endif
+ 
+ //        std::cout << "PRETTY IS '" << __PRETTY_FUNCTION__ << "'\n";
+ //        std::cout << "RESULT IS '" << result << "'\n";
+ 
+         if (result.empty()) {
+             std::cerr << "Cannot infer type name in function call '" << __PRETTY_FUNCTION__ << "'\n'";
+         }
+ 
+ 
+         return result;
+     }
+ 
+ }}
+ 
 -#endif //CELIX_DM_TYPES_H
++#endif //CXX_CELIX_DM_TYPES_H

http://git-wip-us.apache.org/repos/asf/celix/blob/2e04253d/libs/framework/include/celix/impl/BundleContextImpl.h
----------------------------------------------------------------------
diff --cc libs/framework/include/celix/impl/BundleContextImpl.h
index 0000000,0000000..67f079b
new file mode 100644
--- /dev/null
+++ b/libs/framework/include/celix/impl/BundleContextImpl.h
@@@ -1,0 -1,0 +1,554 @@@
++/**
++ *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_IMPL_BUNDLECONTEXTIMPL_H
++#define CELIX_IMPL_BUNDLECONTEXTIMPL_H
++
++#include <mutex>
++#include <cstring>
++#include <memory>
++
++#include "bundle_context.h"
++#include "service_tracker.h"
++
++#include "celix/impl/BundleImpl.h"
++#include "celix/dm/DependencyManager.h"
++#include "celix_service_factory.h"
++
++namespace celix {
++
++    namespace impl {
++        struct ServiceTrackingEntryFunctions {
++            std::function<void(void *)> set{};
++            std::function<void(void *, const celix::Properties &)> setWithProperties{};
++            std::function<void(void *, const celix::Properties &, const celix::Bundle &)> setWithOwner{};
++
++            std::function<void(void *)> add{};
++            std::function<void(void *, const celix::Properties &)> addWithProperties{};
++            std::function<void(void *, const celix::Properties &, const celix::Bundle &)> addWithOwner{};
++
++            std::function<void(void *)> remove{};
++            std::function<void(void *, const celix::Properties &)> removeWithProperties{};
++            std::function<void(void *, const celix::Properties &, const celix::Bundle &)> removeWithOwner{};
++        };
++
++        struct ServiceRegistrationEntry {
++            ServiceRegistrationEntry() {
++                std::memset(&this->cOpts, 0, sizeof(this->cOpts));
++                std::memset(&this->factory, 0, sizeof(this->factory));
++            }
++
++            celix_service_factory_t factory = {nullptr, nullptr, nullptr};
++            celix_service_registration_options_t cOpts = {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr};
++        };
++
++        struct ServiceTrackingEntry {
++            celix_service_tracking_options_t cOpts{{nullptr, nullptr, nullptr, nullptr}, nullptr, nullptr, nullptr, nullptr,
++                                                   nullptr, nullptr, nullptr, nullptr, nullptr, nullptr};
++            std::unique_ptr<ServiceTrackingEntryFunctions> functions{nullptr};
++        };
++    }
++
++    struct BundleContext::Impl {
++        Impl(celix_bundle_context_t *_c_ctx, celix::Framework &_fw) : c_ctx(_c_ctx), fw(_fw), bnd(c_ctx), dm(c_ctx) {}
++        ~Impl() = default;
++
++        Impl(const Impl&) = delete;
++        Impl& operator=(const Impl&) = delete;
++        Impl(Impl&&) = delete;
++        Impl& operator=(Impl&&) = delete;
++
++        //initialized in ctor
++        bundle_context_t *c_ctx;
++        celix::Framework& fw;
++        celix::impl::BundleImpl bnd;
++        celix::dm::DependencyManager dm;
++
++        std::mutex mutex{};
++        std::map<long,celix::impl::ServiceTrackingEntry> trackingEntries{};
++        std::map<long,celix::impl::ServiceRegistrationEntry> registrationEntries{};
++
++        long registerServiceInternal(celix::impl::ServiceRegistrationEntry &&entry) noexcept;
++        long trackServicesInternal(celix::impl::ServiceTrackingEntry &&entry) noexcept;
++        bool useServiceInternal(const std::string &serviceName, const std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept;
++        void useServicesInternal(const std::string &serviceName, const std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept;
++    };
++}
++
++namespace {
++    static celix::Properties createFromCProps(const celix_properties_t *c_props) {
++        celix::Properties result{};
++        const char *key = nullptr;
++        CELIX_PROPERTIES_FOR_EACH(const_cast<celix_properties_t *>(c_props), key) {
++            result[key] = celix_properties_get(c_props, key);
++        }
++        return result;
++    }
++}
++
++inline celix::BundleContext::BundleContext(bundle_context_t *ctx, celix::Framework& fw) {
++    this->pimpl = std::unique_ptr<celix::BundleContext::Impl>{new celix::BundleContext::Impl(ctx, fw)};
++}
++
++inline celix::BundleContext::~BundleContext() {
++    //NOTE no need to destroy the c bundle context -> done by c framework
++    {
++        //clearing service registration
++        std::lock_guard<std::mutex> lock{this->pimpl->mutex};
++        for (auto &pair : this->pimpl->registrationEntries) {
++            celix_bundleContext_unregisterService(this->pimpl->c_ctx, pair.first);
++        }
++        this->pimpl->registrationEntries.clear();
++    }
++
++    {
++        //clearing tracker entries
++        std::lock_guard<std::mutex> lock{this->pimpl->mutex};
++        for (auto &pair : this->pimpl->trackingEntries) {
++            celix_bundleContext_stopTracker(this->pimpl->c_ctx, pair.first);
++        }
++        this->pimpl->trackingEntries.clear();
++    }
++
++    this->pimpl->c_ctx = nullptr;
++    this->pimpl = nullptr;
++}
++
++
++inline void celix::BundleContext::unregisterService(long serviceId) noexcept {
++    std::lock_guard<std::mutex> lock{this->pimpl->mutex};
++    celix_bundleContext_unregisterService(this->pimpl->c_ctx, serviceId);
++    auto it = this->pimpl->registrationEntries.find(serviceId);
++    if (it != this->pimpl->registrationEntries.end()) {
++        this->pimpl->registrationEntries.erase(it);
++    }
++}
++
++inline std::vector<long> celix::BundleContext::findServices(const std::string &/*serviceName*/, const std::string &/*versionRange*/, const std::string &/*filter*/, const std::string &/*lang = ""*/) noexcept {
++    std::vector<long> result{};
++//                auto use = [&result](void *, const celix::Properties &props, const celix::Bundle &) {
++//                    long id = celix::getProperty(props, OSGI_FRAMEWORK_SERVICE_ID, -1);
++//                    if (id >= 0) {
++//                        result.push_back(id);
++//                    }
++//                };
++    //TODO useServicesWithOptions this->useServicesInternal(serviceName, versionRange, filter, use);
++    return result;
++}
++
++inline void celix::BundleContext::stopTracker(long trackerId) noexcept {
++    std::lock_guard<std::mutex> lock{this->pimpl->mutex};
++    celix_bundleContext_stopTracker(this->pimpl->c_ctx, trackerId);
++    auto it = this->pimpl->trackingEntries.find(trackerId);
++    if (it != this->pimpl->trackingEntries.end()) {
++        this->pimpl->trackingEntries.erase(it);
++    }
++}
++
++inline std::string celix::BundleContext::getProperty(const std::string &key, std::string defaultValue) noexcept {
++    const char *val = nullptr;
++    bundleContext_getPropertyWithDefault(this->pimpl->c_ctx, key.c_str(), defaultValue.c_str(), &val);
++    return std::string{val};
++}
++
++
++//    long celix::BundleContext::registerEmbeddedBundle(
++//            std::string /*id*/,
++//            std::function<void(celix::BundleContext & ctx)> /*start*/,
++//            std::function<void(celix::BundleContext & ctx)> /*stop*/,
++//            celix::Properties /*manifest*/,
++//            bool /*autoStart*/
++//    ) noexcept  {
++//        return -1; //TODO
++//    };
++//
++//    void registerEmbeddedBundle(const celix::BundleRegistrationOptions &/*opts*/) noexcept override {
++//        //TODO
++//    }
++
++inline long celix::BundleContext::installBundle(const std::string &bundleLocation, bool autoStart) noexcept {
++    long bndId = -1;
++    if (this->pimpl->c_ctx != nullptr) {
++        bundle_t *bnd = nullptr;
++        bundleContext_installBundle(this->pimpl->c_ctx, bundleLocation.c_str(), &bnd);
++        if (bnd != nullptr) {
++            bundle_getBundleId(bnd, &bndId);
++            if (autoStart) {
++                bundle_start(bnd);
++            }
++        }
++    }
++    return bndId;
++}
++
++
++inline void celix::BundleContext::useBundles(const std::function<void(const celix::Bundle &bnd)> &use) noexcept {
++    auto c_use = [](void *handle, const celix_bundle_t *c_bnd) {
++        auto *func =  static_cast<std::function<void(const celix::Bundle &bnd)>*>(handle);
++        auto m_bnd = const_cast<celix_bundle_t*>(c_bnd);
++        celix::impl::BundleImpl bnd{m_bnd};
++        (*func)(bnd);
++    };
++    celix_bundleContext_useBundles(this->pimpl->c_ctx, (void*)(&use), c_use);
++}
++
++inline bool celix::BundleContext::useBundle(long bundleId, const std::function<void(const celix::Bundle &bnd)> &use) noexcept {
++    auto c_use = [](void *handle, const celix_bundle_t *c_bnd) {
++        auto *func =  static_cast<std::function<void(const celix::Bundle &bnd)>*>(handle);
++        auto m_bnd = const_cast<celix_bundle_t*>(c_bnd);
++        celix::impl::BundleImpl bnd{m_bnd};
++        (*func)(bnd);
++    };
++    return celix_bundleContext_useBundle(this->pimpl->c_ctx, bundleId, (void*)(&use), c_use);
++}
++
++inline celix::Framework& celix::BundleContext::getFramework() noexcept {
++    return this->pimpl->fw;
++}
++
++inline celix::Bundle& celix::BundleContext::getBundle() noexcept {
++    return this->pimpl->bnd;
++};
++
++inline celix::dm::DependencyManager& celix::BundleContext::getDependencyManager() noexcept {
++    return this->pimpl->dm;
++}
++
++inline long celix::BundleContext::Impl::registerServiceInternal(celix::impl::ServiceRegistrationEntry&& entry) noexcept {
++    long svcId = celix_bundleContext_registerServiceWithOptions(this->c_ctx, &entry.cOpts);
++    if (svcId >= 0) {
++        std::lock_guard<std::mutex> lock{this->mutex};
++        this->registrationEntries[svcId] = std::move(entry);
++    }
++    return svcId;
++}
++
++inline long celix::BundleContext::Impl::trackServicesInternal(celix::impl::ServiceTrackingEntry &&entry) noexcept {
++    long trkId = celix_bundleContext_trackServicesWithOptions(this->c_ctx, &entry.cOpts);
++    if (trkId >= 0) {
++        std::lock_guard<std::mutex> lock{this->mutex};
++        this->trackingEntries[trkId] = std::move(entry);
++    }
++    return trkId;
++}
++
++inline bool celix::BundleContext::Impl::useServiceInternal(
++        const std::string &serviceName,
++        const std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept {
++    auto c_use = [](void *handle, void *svc, const celix_properties_t *c_props, const celix_bundle_t *c_svcOwner) {
++        auto *fn = static_cast<const std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &svcOwner)> *>(handle);
++        celix::Properties props = createFromCProps(c_props);
++        celix_bundle_t *m_bnd = const_cast<celix_bundle_t*>(c_svcOwner);
++        celix::impl::BundleImpl bnd{m_bnd};
++        (*fn)(svc, props, bnd);
++    };
++
++    celix_service_use_options_t opts;
++    std::memset(&opts, 0, sizeof(opts));
++
++    opts.filter.serviceName = serviceName.empty() ? nullptr : serviceName.c_str();;
++    opts.filter.serviceLanguage = celix::Constants::SERVICE_CXX_LANG;
++    opts.callbackHandle = (void*)&use;
++    opts.useWithOwner = c_use;
++
++    return celix_bundleContext_useServiceWithOptions(this->c_ctx, &opts);
++}
++
++inline void celix::BundleContext::Impl::useServicesInternal(
++        const std::string &serviceName,
++        const std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept {
++    auto c_use = [](void *handle, void *svc, const celix_properties_t *c_props, const celix_bundle_t *c_svcOwner) {
++        auto *fn = static_cast<const std::function<void(void *svc, const celix::Properties &props, const celix::Bundle &svcOwner)> *>(handle);
++        celix::Properties props = createFromCProps(c_props);
++        celix_bundle_t *m_bnd = const_cast<celix_bundle_t*>(c_svcOwner);
++        celix::impl::BundleImpl bnd{m_bnd};
++        (*fn)(svc, props, bnd);
++    };
++
++    celix_service_use_options_t opts;
++    std::memset(&opts, 0, sizeof(opts));
++
++    opts.filter.serviceName = serviceName.empty() ? nullptr : serviceName.c_str();;
++    opts.filter.serviceLanguage = celix::Constants::SERVICE_CXX_LANG;
++    opts.callbackHandle = (void*)&use;
++    opts.useWithOwner = c_use;
++
++    celix_bundleContext_useServicesWithOptions(this->c_ctx, &opts);
++}
++
++
++template<typename I>
++long celix::BundleContext::registerService(I *svc, const std::string &serviceName, Properties props) noexcept {
++    celix::ServiceRegistrationOptions<I> opts{*svc, serviceName};
++    opts.properties = std::move(props);
++    return this->registerServiceWithOptions(opts);
++}
++
++template<typename I>
++long celix::BundleContext::registerCService(I *svc, const std::string &serviceName, Properties props) noexcept {
++    static_assert(std::is_pod<I>::value, "Service I must be a 'Plain Old Data' object");
++    celix::ServiceRegistrationOptions<I> opts{*svc, serviceName};
++    opts.properties = std::move(props);
++    opts.serviceLanguage = celix::Constants::SERVICE_C_LANG;
++    return this->registerServiceWithOptions(opts);
++}
++
++template<typename I>
++long celix::BundleContext::registerServiceFactory(celix::IServiceFactory<I> *factory, const std::string &serviceName, celix::Properties props) {
++    celix::ServiceRegistrationOptions<I> opts{factory, serviceName};
++    opts.properties = std::move(props);
++    return this->registerServiceWithOptions(opts);
++}
++
++template<typename I>
++long celix::BundleContext::registerCServiceFactory(IServiceFactory<I> *factory, const std::string &serviceName, celix::Properties props) {
++    static_assert(std::is_pod<I>::value, "Service I must be a 'Plain Old Data' object");
++    celix::ServiceRegistrationOptions<I> opts{factory, serviceName};
++    opts.properties = std::move(props);
++    opts.serviceLanguage = celix::Constants::SERVICE_C_LANG;
++    return this->registerServiceWithOptions(opts);
++}
++
++template<typename I>
++long celix::BundleContext::registerServiceWithOptions(const celix::ServiceRegistrationOptions<I>& opts) noexcept {
++    celix_properties_t *c_props = celix_properties_create();
++    for (auto &pair : opts.properties) {
++        celix_properties_set(c_props, pair.first.c_str(), pair.second.c_str());
++    }
++
++    celix::impl::ServiceRegistrationEntry re{};
++
++    re.cOpts = CELIX_EMPTY_SERVICE_REGISTRATION_OPTIONS;
++    if (opts.svc != nullptr) {
++        re.cOpts.svc = static_cast<void *>(opts.svc);
++    } else if (opts.factory != nullptr) {
++        auto c_getService = [](void *handle, const celix_bundle_t *requestingBundle, const celix_properties_t *svcProperties) -> void* {
++            celix::IServiceFactory<I> *f = static_cast<celix::IServiceFactory<I>*>(handle);
++            auto mbnd = const_cast<celix_bundle_t*>(requestingBundle);
++            celix::impl::BundleImpl bundle{mbnd};
++            celix::Properties props = createFromCProps(svcProperties);
++            I *svc = f->getService(bundle, props);
++            return static_cast<void*>(svc);
++        };
++        auto c_ungetService = [](void *handle, const celix_bundle_t *requestingBundle, const celix_properties_t *svcProperties) {
++            celix::IServiceFactory<I> *f = static_cast<celix::IServiceFactory<I>*>(handle);
++            auto mbnd = const_cast<celix_bundle_t*>(requestingBundle);
++            celix::impl::BundleImpl bundle{mbnd};
++            celix::Properties props = createFromCProps(svcProperties);
++            f->ungetService(bundle, props);
++        };
++        re.factory.handle = static_cast<void*>(opts.factory);
++        re.factory.getService = c_getService;
++        re.factory.ungetService = c_ungetService;
++        re.cOpts.factory = &re.factory;
++    }
++
++    re.cOpts.serviceName = opts.serviceName.c_str();
++    re.cOpts.serviceVersion = opts.serviceVersion.c_str();
++    re.cOpts.serviceLanguage = opts.serviceLanguage.c_str();
++    re.cOpts.properties = c_props;
++
++    return this->pimpl->registerServiceInternal(std::move(re));
++}
++
++template<typename I>
++long celix::BundleContext::trackService(const std::string &serviceName, std::function<void(I *svc)> set) noexcept {
++    celix::ServiceTrackingOptions<I> opts{serviceName};
++    opts.set = std::move(set);
++    return this->trackServicesWithOptions<I>(opts);
++}
++
++template<typename I>
++long celix::BundleContext::trackServices(const std::string &serviceName,
++        std::function<void(I *svc)> add, std::function<void(I *svc)> remove) noexcept {
++    celix::ServiceTrackingOptions<I> opts{serviceName};
++    opts.add = std::move(add);
++    opts.remove = std::move(remove);
++    return this->trackServicesWithOptions<I>(opts);
++}
++
++template<typename I>
++long celix::BundleContext::trackServicesWithOptions(const celix::ServiceTrackingOptions<I>& opts) {
++    celix::impl::ServiceTrackingEntry entry{};
++    entry.functions = std::unique_ptr<celix::impl::ServiceTrackingEntryFunctions>{new celix::impl::ServiceTrackingEntryFunctions()};
++
++    auto set = opts.set;
++    if (set) {
++        auto voidfunc = [set](void *voidSvc) {
++            I *typedSvc = static_cast<I*>(voidSvc);
++            set(typedSvc);
++        };
++        entry.functions->set = voidfunc;
++        entry.cOpts.set = [](void *handle, void *svc) {
++            auto *fentry = static_cast<celix::impl::ServiceTrackingEntryFunctions*>(handle);
++            (fentry->set)(svc);
++        };
++    }
++
++    auto setWithProperties = opts.setWithProperties;
++    if (setWithProperties) {
++        auto voidfunc = [setWithProperties](void *voidSvc, const celix::Properties &props) {
++            I *typedSvc = static_cast<I*>(voidSvc);
++            setWithProperties(typedSvc, props);
++        };
++        entry.functions->setWithProperties = voidfunc;
++        entry.cOpts.setWithProperties = [](void *handle, void *svc, const celix_properties_t *c_props) {
++            auto *fentry = static_cast<celix::impl::ServiceTrackingEntryFunctions*>(handle);
++            celix::Properties props = createFromCProps(c_props);
++            (fentry->setWithProperties)(svc, props);
++        };
++    }
++
++    auto setWithOwner = opts.setWithOwner;
++    if (setWithOwner) {
++        auto voidfunc = [setWithOwner](void *voidSvc, const celix::Properties &props, const celix::Bundle &bnd) {
++            I *typedSvc = static_cast<I*>(voidSvc);
++            setWithOwner(typedSvc, props, bnd);
++        };
++        entry.functions->setWithOwner = voidfunc;
++        entry.cOpts.setWithOwner = [](void *handle, void *svc, const celix_properties_t *c_props, const celix_bundle_t *c_bnd) {
++            auto *fentry = static_cast<celix::impl::ServiceTrackingEntryFunctions*>(handle);
++            celix::Properties props = createFromCProps(c_props);
++            auto m_bnd = const_cast<celix_bundle_t *>(c_bnd);
++            celix::impl::BundleImpl bnd{m_bnd};
++            (fentry->setWithOwner)(svc, props, bnd);
++        };
++    }
++
++    auto add = opts.add;
++    if (add) {
++        auto voidfunc = [add](void *voidSvc) {
++            I *typedSvc = static_cast<I*>(voidSvc);
++            add(typedSvc);
++        };
++        entry.functions->add = voidfunc;
++        entry.cOpts.add = [](void *handle, void *svc) {
++            auto *fentry = static_cast<celix::impl::ServiceTrackingEntryFunctions*>(handle);
++            (fentry->add)(svc);
++        };
++    }
++
++    auto addWithProperties = opts.addWithProperties;
++    if (addWithProperties) {
++        auto voidfunc = [addWithProperties](void *voidSvc, const celix::Properties &props) {
++            I *typedSvc = static_cast<I*>(voidSvc);
++            addWithProperties(typedSvc, props);
++        };
++        entry.functions->addWithProperties = voidfunc;
++        entry.cOpts.addWithProperties = [](void *handle, void *svc, const celix_properties_t *c_props) {
++            auto *fentry = static_cast<celix::impl::ServiceTrackingEntryFunctions*>(handle);
++            celix::Properties props = createFromCProps(c_props);
++            (fentry->addWithProperties)(svc, props);
++        };
++    }
++
++    auto addWithOwner = opts.setWithOwner;
++    if (addWithOwner) {
++        auto voidfunc = [addWithOwner](void *voidSvc, const celix::Properties &props, const celix::Bundle &bnd) {
++            I *typedSvc = static_cast<I*>(voidSvc);
++            addWithOwner(typedSvc, props, bnd);
++        };
++        entry.functions->addWithOwner = voidfunc;
++        entry.cOpts.addWithOwner = [](void *handle, void *svc, const celix_properties_t *c_props, const celix_bundle_t *c_bnd) {
++            auto *fentry = static_cast<celix::impl::ServiceTrackingEntryFunctions*>(handle);
++            celix::Properties props = createFromCProps(c_props);
++            auto m_bnd = const_cast<celix_bundle_t *>(c_bnd);
++            celix::impl::BundleImpl bnd{m_bnd};
++            (fentry->addWithOwner)(svc, props, bnd);
++        };
++    }
++
++    auto remove = opts.remove;
++    if (remove) {
++        auto voidfunc = [remove](void *voidSvc) {
++            I *typedSvc = static_cast<I*>(voidSvc);
++            remove(typedSvc);
++        };
++        entry.functions->remove = voidfunc;
++        entry.cOpts.remove = [](void *handle, void *svc) {
++            auto *fentry = static_cast<celix::impl::ServiceTrackingEntryFunctions*>(handle);
++            (fentry->add)(svc);
++        };
++    }
++
++    auto removeWithProperties = opts.removeWithProperties;
++    if (removeWithProperties) {
++        auto voidfunc = [removeWithProperties](void *voidSvc, const celix::Properties &props) {
++            I *typedSvc = static_cast<I*>(voidSvc);
++            removeWithProperties(typedSvc, props);
++        };
++        entry.functions->removeWithProperties = voidfunc;
++        entry.cOpts.removeWithProperties = [](void *handle, void *svc, const celix_properties_t *c_props) {
++            auto *fentry = static_cast<celix::impl::ServiceTrackingEntryFunctions*>(handle);
++            celix::Properties props = createFromCProps(c_props);
++            (fentry->removeWithProperties)(svc, props);
++        };
++    }
++
++    auto removeWithOwner = opts.removeWithOwner;
++    if (removeWithOwner) {
++        auto voidfunc = [removeWithOwner](void *voidSvc, const celix::Properties &props, const celix::Bundle &bnd) {
++            I *typedSvc = static_cast<I*>(voidSvc);
++            removeWithOwner(typedSvc, props, bnd);
++        };
++        entry.functions->removeWithOwner = voidfunc;
++        entry.cOpts.removeWithOwner = [](void *handle, void *svc, const celix_properties_t *c_props, const celix_bundle_t *c_bnd) {
++            auto *fentry = static_cast<celix::impl::ServiceTrackingEntryFunctions*>(handle);
++            celix::Properties props = createFromCProps(c_props);
++            auto m_bnd = const_cast<celix_bundle_t *>(c_bnd);
++            celix::impl::BundleImpl bnd{m_bnd};
++            (fentry->removeWithOwner)(svc, props, bnd);
++        };
++    }
++
++    entry.cOpts.filter.serviceName = opts.filter.serviceName.c_str();
++    entry.cOpts.filter.serviceLanguage = opts.filter.serviceLanguage.c_str();
++    entry.cOpts.filter.versionRange = opts.filter.versionRange.c_str();
++    entry.cOpts.filter.filter = opts.filter.filter.c_str();
++
++    entry.cOpts.callbackHandle = entry.functions.get();
++
++    return this->pimpl->trackServicesInternal(std::move(entry));
++}
++
++template<typename I>
++bool celix::BundleContext::useServiceWithId(long serviceId, const std::string &/*serviceName*/ /*sanity*/, const std::function<void(I &svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &/*use*/) noexcept {
++    std::string filter = std::string{"(service.id="} + std::to_string(serviceId) + std::string{")"};
++    //TODO use useServiceWithOptions return this->useService<I>(serviceName, "", filter, use);
++    return false;
++}
++
++template<typename I>
++bool celix::BundleContext::useService(const std::string &serviceName, const std::function<void(I &svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept {
++    return this->pimpl->useServiceInternal(serviceName, [use](void *voidSvc, const celix::Properties &props, const celix::Bundle &svcOwner) {
++        I *typedSvc = static_cast<I*>(voidSvc);
++        use(*typedSvc, props, svcOwner);
++    });
++}
++
++template<typename I>
++void celix::BundleContext::useServices(const std::string &serviceName, const std::function<void(I &svc, const celix::Properties &props, const celix::Bundle &svcOwner)> &use) noexcept {
++    this->pimpl->useServicesInternal(serviceName, [use](void *voidSvc, const celix::Properties &props, const celix::Bundle &svcOwner) {
++        I *typedSvc = static_cast<I*>(voidSvc);
++        use(*typedSvc, props, svcOwner);
++    });
++}
++
++
++#endif //CELIX_IMPL_BUNDLECONTEXTIMPL_H

http://git-wip-us.apache.org/repos/asf/celix/blob/2e04253d/libs/framework/include/celix/impl/BundleImpl.h
----------------------------------------------------------------------
diff --cc libs/framework/include/celix/impl/BundleImpl.h
index 0000000,0000000..e56a5b7
new file mode 100644
--- /dev/null
+++ b/libs/framework/include/celix/impl/BundleImpl.h
@@@ -1,0 -1,0 +1,180 @@@
++/**
++ *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_IMPL_BUNDLEIMPL_H
++#define CELIX_IMPL_BUNDLEIMPL_H
++
++#include "celix_bundle.h"
++#include "celix_bundle_context.h"
++
++namespace celix {
++
++    //forward declaration
++
++    namespace impl {
++        class BundleImpl : public celix::Bundle {
++        public:
++            BundleImpl(celix_bundle_context_t *c_ctx) : c_bnd(nullptr) {
++                bundleContext_getBundle(c_ctx, &this->c_bnd);
++            }
++
++            BundleImpl(celix_bundle_t *b) : c_bnd(b) {
++            }
++
++            virtual ~BundleImpl() {
++                //no need to destroy the c bundle context -> done by c framework
++                this->c_bnd = nullptr;
++            }
++
++            BundleImpl(const BundleImpl&) = delete;
++            BundleImpl& operator=(const BundleImpl&) = delete;
++
++            BundleImpl(BundleImpl&& rhs) : c_bnd{nullptr} {
++                using std::swap;
++                swap(this->c_bnd, rhs.c_bnd);
++            }
++
++            BundleImpl& operator=(BundleImpl&& rhs) {
++                using std::swap;
++                swap(this->c_bnd, rhs.c_bnd);
++                return *this;
++            }
++
++            bool isSystemBundle() const noexcept  override {
++                bool r;
++                bundle_isSystemBundle(this->c_bnd, &r);
++                return r;
++            }
++
++            void * getHandle() const noexcept override {
++                return bundle_getHandle(this->c_bnd);
++            }
++
++            BundleState getState() const noexcept  override {
++                bundle_state_e c_state;
++                bundle_getState(this->c_bnd, &c_state);
++                return this->fromCState(c_state);
++            }
++
++            long getBundleId() const noexcept  override {
++                long id{-1};
++                bundle_getBundleId(this->c_bnd, &id);
++                return id;
++            }
++
++            std::string getBundleLocation() const noexcept  override {
++                std::string location{};
++                const char *loc = nullptr;
++                bundle_getBundleLocation(this->c_bnd, &loc);
++                if (loc != nullptr) {
++                    location = std::string{loc};
++                }
++                return location;
++            }
++
++            std::string getBundleCache() const noexcept  override {
++                std::string cache{};
++                const char *c = celix_bundle_getEntry(this->c_bnd, ".");
++                if (c != nullptr) {
++                    cache = std::string{c};
++                }
++                return cache;
++            }
++
++            std::string getBundleName() const noexcept override {
++                std::string name{};
++                module_pt mod = nullptr;
++                bundle_getCurrentModule(this->c_bnd, &mod);
++                if (mod != nullptr) {
++                    name = module_getId(mod);
++                }
++                return name;
++            }
++
++            std::string getBundleSymbolicName() const noexcept override {
++                std::string name{};
++                module_pt mod = nullptr;
++                bundle_getCurrentModule(this->c_bnd, &mod);
++                if (mod != nullptr) {
++                    const char *n = nullptr;
++                    module_getSymbolicName(mod, &n);
++                    if (n != nullptr) {
++                        name = n;
++                    }
++                }
++                return name;
++            }
++
++            std::string getBundleVersion() const noexcept override {
++                return std::string{}; //TODO
++//                std::string version{};
++//                module_pt mod = nullptr;
++//                bundle_getCurrentModule(this->c_bnd, &mod);
++//                if (mod != nullptr) {
++//                    auto version = module_getVersion(mod);
++//                    //TODO
++//                }
++//                return version;
++            }
++
++            celix::Properties getManifestAsProperties() const noexcept  override {
++                return celix::Properties{}; //TODO
++            }
++
++            void start() noexcept override {
++                bundle_start(this->c_bnd);
++            }
++
++            void stop() noexcept override {
++                bundle_stop(this->c_bnd);
++            }
++
++            void uninstall() noexcept override {
++                bundle_uninstall(this->c_bnd);
++            }
++
++        private:
++            BundleState fromCState(bundle_state_e c_state) const {
++                switch(c_state) {
++                    case OSGI_FRAMEWORK_BUNDLE_UNKNOWN:
++                        return BundleState::UNKNOWN;
++                    case OSGI_FRAMEWORK_BUNDLE_UNINSTALLED:
++                        return BundleState::INSTALLED;
++                    case OSGI_FRAMEWORK_BUNDLE_INSTALLED:
++                        return BundleState::INSTALLED;
++                    case OSGI_FRAMEWORK_BUNDLE_RESOLVED:
++                        return BundleState::RESOLVED;
++                    case OSGI_FRAMEWORK_BUNDLE_STOPPING:
++                        return BundleState::STOPPING;
++                    case OSGI_FRAMEWORK_BUNDLE_ACTIVE:
++                        return BundleState::ACTIVE;
++                    case OSGI_FRAMEWORK_BUNDLE_STARTING:
++                        return BundleState::STARTING;
++                    default:
++                        ;//passs
++                }
++                return BundleState::UNKNOWN;
++            };
++
++            celix_bundle_t *c_bnd;
++        };
++    }
++}
++
++#endif //CELIX_IMPL_BUNDLEIMPL_H

http://git-wip-us.apache.org/repos/asf/celix/blob/2e04253d/libs/framework/include/celix/impl/FrameworkImpl.h
----------------------------------------------------------------------
diff --cc libs/framework/include/celix/impl/FrameworkImpl.h
index 0000000,0000000..45e5ea5
new file mode 100644
--- /dev/null
+++ b/libs/framework/include/celix/impl/FrameworkImpl.h
@@@ -1,0 -1,0 +1,127 @@@
++/**
++ *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 CXX_CELIX_IMPL_FRAMEWORKIMPL_H
++#define CXX_CELIX_IMPL_FRAMEWORKIMPL_H
++
++#include "celix_framework_factory.h"
++#include "framework.h"
++
++#include "celix/impl/BundleContextImpl.h"
++#include "celix/impl/BundleImpl.h"
++
++namespace celix {
++
++    namespace impl {
++
++        class FrameworkImpl : public celix::Framework {
++        public:
++            FrameworkImpl(celix_bundle_context_t *c_ctx) : owner(false) {
++                bundleContext_getFramework(c_ctx, &this->c_fwm);
++                this->setFrameworkContext();
++            }
++
++            FrameworkImpl(framework_t *c_fw) : owner(false) {
++                //wrapper framework
++                this->c_fwm = c_fw;
++                //assume started framework
++                this->setFrameworkContext();
++            }
++
++            FrameworkImpl(const FrameworkImpl&) = delete;
++            FrameworkImpl& operator=(const FrameworkImpl&) = delete;
++            FrameworkImpl(FrameworkImpl&&) = delete;
++            FrameworkImpl& operator=(FrameworkImpl&&) = delete;
++
++            FrameworkImpl(celix::Properties config) : owner(true) {
++                //framework which also owns the underlining c framework
++                auto c_config = properties_create();
++                for (auto &pair : config) {
++                    properties_set(c_config, pair.first.c_str(), pair.second.c_str());
++                }
++                this->c_fwm = frameworkFactory_newFramework(c_config); //should be started
++
++                this->setFrameworkContext();
++            };
++
++            virtual ~FrameworkImpl() {
++                if (this->owner && this->c_fwm != nullptr) {
++                    framework_stop(this->c_fwm);
++                    framework_waitForStop(this->c_fwm);
++                    framework_destroy(this->c_fwm);
++                }
++            }
++
++            virtual void start() noexcept override {
++                framework_start(this->c_fwm);
++            }
++
++            virtual void stop() noexcept override {
++                framework_stop(this->c_fwm);
++            }
++
++            virtual void waitForStop() noexcept override {
++                framework_waitForStop(this->c_fwm);
++            }
++            //TODO also in c virtual void breakWaitForStops() noexcept = 0;
++
++            std::string getUUID() const noexcept override {
++                //TODO return std::string{celix_framework_getUUID(this->c_fwm)};
++                return "TODO";
++            }
++
++            celix::BundleContext& getFrameworkContext() noexcept override {
++                BundleContext &ctx = this->bundleContextsCache.at(0);
++                return ctx;
++            }
++
++            celix::Bundle& getFrameworkBundle() noexcept override {
++                if (this->fwBundle.size() == 0) {
++                    celix_bundle_t* c_bnd = nullptr;
++                    framework_getFrameworkBundle(this->c_fwm, &c_bnd);
++                    this->fwBundle.emplace_back(c_bnd);
++
++                }
++                return this->fwBundle[0];
++            }
++
++        private:
++
++            void setFrameworkContext() {
++                //create and set framework bundle context (replace invalid bundle context)
++                bundle_t *fwmBundle = nullptr;
++                bundle_context_t *fwmCtx = nullptr;
++                framework_getFrameworkBundle(this->c_fwm, &fwmBundle);
++                bundle_getContext(fwmBundle, &fwmCtx);
++                this->bundleContextsCache.emplace(std::piecewise_construct,
++                                                    std::forward_as_tuple(0L),
++                                                    std::forward_as_tuple(fwmCtx, *this));
++            }
++
++
++            bool owner;
++            framework_t *c_fwm{nullptr};
++            std::map<long,celix::BundleContext> bundleContextsCache{};
++            std::vector<celix::impl::BundleImpl> fwBundle{}; //optional entry
++
++        };
++    }
++}
++
++#endif //CXX_CELIX_IMPL_FRAMEWORKIMPL_H