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

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


The following commit(s) were added to refs/heads/feature/query_command by this 
push:
     new b331248  gh-144: Adds test for bundle info calls and query shell and 
fixes some issues.
b331248 is described below

commit b33124834ee5805cb91f047aea1ecc2efee3ee6c
Author: Pepijn Noltes <[email protected]>
AuthorDate: Mon Feb 3 21:32:58 2020 +0100

    gh-144: Adds test for bundle info calls and query shell and fixes some 
issues.
    
    Additional:
      - Added a updated celix_ api for the shell
      - Added a cmake option whether to allow deprecated apis (default true).
      - Refactor for updated celix_ shell api.
      - Update component id to uuid.
      - Added component.uuid to service registrations.
---
 CMakeLists.txt                                     |   2 +
 bundles/pubsub/pubsub_admin_udp_mc/CMakeLists.txt  |   2 +-
 .../pubsub/pubsub_admin_udp_mc/src/psa_activator.c |  12 +-
 .../src/calculator_shell_activator.c               |  19 +-
 bundles/shell/remote_shell/src/shell_mediator.h    |   2 +-
 bundles/shell/shell/CMakeLists.txt                 |  17 +-
 .../command.h => api/celix_shell_command.h}        |  41 +--
 .../celix_shell_constants.h}                       |  10 +-
 .../command.h}                                     |  28 +--
 .../shell.h}                                       |  28 +--
 .../{include => deprecated_api}/shell_constants.h  |   6 +-
 bundles/shell/shell/src/activator.c                |  42 ++--
 bundles/shell/shell/src/inspect_command.c          | 277 ---------------------
 bundles/shell/shell/src/query_command.c            |  47 +++-
 .../shell/src/{q_command.c => quit_command.c}      |   2 +-
 bundles/shell/shell/src/shell.c                    |   8 +-
 bundles/shell/shell/src/shell_private.h            |  10 +-
 bundles/shell/shell/src/std_commands.h             |   3 +-
 bundles/shell/shell/test/CMakeLists.txt            |  31 +++
 .../shell/shell/test/src}/run_tests.cpp            |   1 +
 bundles/shell/shell/test/src/shell_tests.cpp       | 105 ++++++++
 .../shell/shell_tui/private/include/shell_tui.h    |   4 +-
 bundles/shell/shell_tui/private/src/activator.c    |   5 +-
 libs/framework/CMakeLists.txt                      |   1 +
 libs/framework/include/celix_bundle.h              |   3 +
 libs/framework/include/celix_dm_component.h        |   2 +
 libs/framework/include/service_tracker.h           |  10 +-
 .../private/mock/service_tracker_customizer_mock.c |   3 -
 libs/framework/private/mock/service_tracker_stub.c |   3 +-
 libs/framework/src/bundle.c                        |  12 +-
 libs/framework/src/dm_component_impl.c             |  60 +++--
 libs/framework/src/framework.c                     |   8 +
 libs/framework/src/service_tracker.c               |  13 +
 libs/framework/src/service_tracker_private.h       |  10 +-
 .../framework/tst/bundle_context_bundles_tests.cpp |  38 ++-
 libs/framework/tst/run_tests.cpp                   |   1 +
 libs/utils/include/celix_errno.h                   |   7 -
 37 files changed, 404 insertions(+), 469 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5d96f25..1c6b562 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -106,6 +106,8 @@ if (CELIX_ADD_OPENSSL_DEP)
     set(CELIX_OPTIONAL_EXTRA_LIBS "OpenSSL::lib")
 endif ()
 
+set(CELIX_USE_DEPRECATED_API true CACHE BOOL "whether to use and install 
deprecated apis (i.e. header with a celix_ prefix.")
+
 #Libraries and Launcher
 add_subdirectory(libs)
 
diff --git a/bundles/pubsub/pubsub_admin_udp_mc/CMakeLists.txt 
b/bundles/pubsub/pubsub_admin_udp_mc/CMakeLists.txt
index dd0a095..59bdaf1 100644
--- a/bundles/pubsub/pubsub_admin_udp_mc/CMakeLists.txt
+++ b/bundles/pubsub/pubsub_admin_udp_mc/CMakeLists.txt
@@ -33,7 +33,7 @@ target_include_directories(celix_pubsub_admin_udp_multicast 
PRIVATE
         src
 )
 set_target_properties(celix_pubsub_admin_udp_multicast PROPERTIES 
INSTALL_RPATH "$ORIGIN")
-target_link_libraries(celix_pubsub_admin_udp_multicast PRIVATE 
Celix::pubsub_spi Celix::framework Celix::dfi Celix::log_helper Celix::utils)
+target_link_libraries(celix_pubsub_admin_udp_multicast PRIVATE 
Celix::pubsub_spi Celix::framework Celix::dfi Celix::log_helper Celix::utils 
Celix::shell_api)
 
 install_celix_bundle(celix_pubsub_admin_udp_multicast EXPORT celix COMPONENT 
pubsub)
 
diff --git a/bundles/pubsub/pubsub_admin_udp_mc/src/psa_activator.c 
b/bundles/pubsub/pubsub_admin_udp_mc/src/psa_activator.c
index 9b67207..ef887c9 100644
--- a/bundles/pubsub/pubsub_admin_udp_mc/src/psa_activator.c
+++ b/bundles/pubsub/pubsub_admin_udp_mc/src/psa_activator.c
@@ -25,7 +25,7 @@
 
 #include "pubsub_admin.h"
 #include "pubsub_udpmc_admin.h"
-#include "../../../shell/shell/include/command.h"
+#include "celix_shell_command.h"
 
 typedef struct psa_udpmc_activator {
     log_helper_t *logHelper;
@@ -37,7 +37,7 @@ typedef struct psa_udpmc_activator {
     pubsub_admin_service_t adminService;
     long adminSvcId;
 
-    command_service_t cmdSvc;
+    celix_shell_command_t cmdSvc;
     long cmdSvcId;
 } psa_udpmc_activator_t;
 
@@ -89,10 +89,10 @@ int psa_udpmc_start(psa_udpmc_activator_t *act, 
celix_bundle_context_t *ctx) {
         act->cmdSvc.handle = act->admin;
         act->cmdSvc.executeCommand = pubsub_udpmcAdmin_executeCommand;
         celix_properties_t *props = celix_properties_create();
-        celix_properties_set(props, OSGI_SHELL_COMMAND_NAME, "psa_udpmc");
-        celix_properties_set(props, OSGI_SHELL_COMMAND_USAGE, "psa_udpmc");
-        celix_properties_set(props, OSGI_SHELL_COMMAND_DESCRIPTION, "Print the 
information about the TopicSender and TopicReceivers for the UDPMC PSA");
-        act->cmdSvcId = celix_bundleContext_registerService(ctx, &act->cmdSvc, 
OSGI_SHELL_COMMAND_SERVICE_NAME, props);
+        celix_properties_set(props, CELIX_SHELL_COMMAND_NAME, "psa_udpmc");
+        celix_properties_set(props, CELIX_SHELL_COMMAND_USAGE, "psa_udpmc");
+        celix_properties_set(props, CELIX_SHELL_COMMAND_DESCRIPTION, "Print 
the information about the TopicSender and TopicReceivers for the UDPMC PSA");
+        act->cmdSvcId = celix_bundleContext_registerService(ctx, &act->cmdSvc, 
CELIX_SHELL_COMMAND_SERVICE_NAME, props);
     }
 
     return status;
diff --git 
a/bundles/remote_services/examples/calculator_shell/src/calculator_shell_activator.c
 
b/bundles/remote_services/examples/calculator_shell/src/calculator_shell_activator.c
index 65e9324..fe47c1d 100644
--- 
a/bundles/remote_services/examples/calculator_shell/src/calculator_shell_activator.c
+++ 
b/bundles/remote_services/examples/calculator_shell/src/calculator_shell_activator.c
@@ -16,13 +16,6 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-/**
- * calculator_shell_activator.c
- *
- *  \date       Oct 13, 2011
- *  \author     <a href="mailto:[email protected]";>Apache Celix Project 
Team</a>
- *  \copyright  Apache License, Version 2.0
- */
 
 #include <stdlib.h>
 #include <string.h>
@@ -38,16 +31,16 @@
 
 struct activator {
     service_registration_t *addCommand;
-    command_service_t *addCmd;
-    command_service_t *addCmdSrv;
+    celix_shell_command_t *addCmd;
+    celix_shell_command_t *addCmdSrv;
 
     service_registration_t *subCommand;
-    command_service_t *subCmd;
-    command_service_t *subCmdSrv;
+    celix_shell_command_t *subCmd;
+    celix_shell_command_t *subCmdSrv;
 
     service_registration_t *sqrtCommand;
-    command_service_t *sqrtCmd;
-    command_service_t *sqrtCmdSrv;
+    celix_shell_command_t *sqrtCmd;
+    celix_shell_command_t *sqrtCmdSrv;
 };
 
 celix_status_t bundleActivator_create(celix_bundle_context_t *context, void 
**userData) {
diff --git a/bundles/shell/remote_shell/src/shell_mediator.h 
b/bundles/shell/remote_shell/src/shell_mediator.h
index 56320b3..4d1a98e 100644
--- a/bundles/shell/remote_shell/src/shell_mediator.h
+++ b/bundles/shell/remote_shell/src/shell_mediator.h
@@ -41,7 +41,7 @@ struct shell_mediator {
        celix_thread_mutex_t mutex;
 
        //protected by mutex
-       shell_service_pt shellService;
+       celix_shell_t *shellService;
 };
 typedef struct shell_mediator *shell_mediator_pt;
 
diff --git a/bundles/shell/shell/CMakeLists.txt 
b/bundles/shell/shell/CMakeLists.txt
index c1037b7..f0ad7ae 100644
--- a/bundles/shell/shell/CMakeLists.txt
+++ b/bundles/shell/shell/CMakeLists.txt
@@ -20,11 +20,16 @@ if (SHELL)
 
        add_library(shell_api INTERFACE)
        target_include_directories(shell_api INTERFACE
-                       $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>
+                       $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/api>
                        $<INSTALL_INTERFACE:include/celix/shell>
        )
        install(TARGETS shell_api EXPORT celix COMPONENT shell)
-       install(DIRECTORY include/ DESTINATION include/celix/shell COMPONENT 
shell)
+       install(DIRECTORY api/ DESTINATION include/celix/shell COMPONENT shell)
+
+       if (CELIX_USE_DEPRECATED_API)
+               target_include_directories(shell_api INTERFACE 
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/deprecated_api>)
+               install(DIRECTORY deprecated_api/ DESTINATION 
include/celix/shell COMPONENT shell)
+       endif ()
 
     add_celix_bundle(shell
         SYMBOLIC_NAME "apache_celix_shell"
@@ -41,11 +46,10 @@ if (SHELL)
           src/update_command
           src/uninstall_command
           src/log_command
-          src/inspect_command
           src/help_command
                  src/dm_shell_list_command
                  src/query_command.c
-                 src/q_command.c
+                 src/quit_command.c
        )
        target_include_directories(shell PRIVATE src)
        target_link_libraries(shell PRIVATE Celix::shell_api CURL::libcurl 
Celix::log_service_api Celix::log_helper)
@@ -55,4 +59,9 @@ if (SHELL)
        #Setup target aliases to match external usage
        add_library(Celix::shell_api ALIAS shell_api)
        add_library(Celix::shell ALIAS shell)
+
+
+       if (ENABLE_TESTING)
+               add_subdirectory(test)
+       endif()
 endif (SHELL)
diff --git a/bundles/shell/shell/include/command.h 
b/bundles/shell/shell/api/celix_shell_command.h
similarity index 64%
rename from bundles/shell/shell/include/command.h
rename to bundles/shell/shell/api/celix_shell_command.h
index df1310b..94cc990 100644
--- a/bundles/shell/shell/include/command.h
+++ b/bundles/shell/shell/api/celix_shell_command.h
@@ -16,29 +16,25 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-/**
- * command.h
- *
- *  \date       Aug 13, 2010
- *  \author     <a href="mailto:[email protected]";>Apache Celix Project 
Team</a>
- *  \copyright  Apache License, Version 2.0
- */
 
-#ifndef COMMAND_H_
-#define COMMAND_H_
+#ifndef CELIX_SHELL_COMMAND_H_
+#define CELIX_SHELL_COMMAND_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
 
 #include "celix_errno.h"
 #include <stdio.h>
 
-#define OSGI_SHELL_COMMAND_NAME "command.name"
-#define OSGI_SHELL_COMMAND_USAGE "command.usage"
-#define OSGI_SHELL_COMMAND_DESCRIPTION "command.description"
+#define CELIX_SHELL_COMMAND_NAME                "command.name"
+#define CELIX_SHELL_COMMAND_USAGE               "command.usage"
+#define CELIX_SHELL_COMMAND_DESCRIPTION         "command.description"
 
-static const char * const OSGI_SHELL_COMMAND_SERVICE_NAME = "commandService";
-static const char * const OSGI_SHELL_COMMAND_SERVICE_VERSION = "1.0.0";
+#define  CELIX_SHELL_COMMAND_SERVICE_NAME       "celix_shell_command"
+#define  CELIX_SHELL_COMMAND_SERVICE_VERSION    "1.0.0"
 
-typedef struct commandService command_service_t;
-typedef command_service_t * command_service_pt;
+typedef struct celix_shell_command celix_shell_command_t;
 
 /**
  * The command service can be used to register additional shell commands.
@@ -47,10 +43,17 @@ typedef command_service_t * command_service_pt;
  *  - command.usage: optional, string describing how tu use the command e.g. 
'lb [-l | -s | -u]'
  *  - command.description: optional, string describing the command e.g. 'list 
bundles.'
  */
-struct commandService {
+struct celix_shell_command {
     void *handle;
-    celix_status_t (*executeCommand)(void *handle, char* commandLine, FILE 
*outStream, FILE *errorStream);
+
+    //TODO fix commandLine arg, needs to be const char* (increase version to 
2.0.0)
+    celix_status_t (*executeCommand)(void *handle, char *commandLine, FILE 
*outStream, FILE *errorStream);
 };
 
 
-#endif /* COMMAND_H_ */
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* CELIX_SHELL_COMMAND_H_ */
diff --git a/bundles/shell/shell/include/shell_constants.h 
b/bundles/shell/shell/api/celix_shell_constants.h
similarity index 77%
copy from bundles/shell/shell/include/shell_constants.h
copy to bundles/shell/shell/api/celix_shell_constants.h
index 4ff67c0..26d7581 100644
--- a/bundles/shell/shell/include/shell_constants.h
+++ b/bundles/shell/shell/api/celix_shell_constants.h
@@ -17,10 +17,10 @@
  * under the License.
  */
 
-#ifndef SHELL_CONSTANTS_H_
-#define SHELL_CONSTANTS_H_
+#ifndef CELIX_SHELL_CONSTANTS_H_
+#define CELIX_SHELL_CONSTANTS_H_
 
-#define SHELL_USE_ANSI_COLORS "SHELL_USE_ANSI_COLORS"
-#define SHELL_USE_ANSI_COLORS_DEFAULT_VALUE "true"
+#define CELIX_SHELL_USE_ANSI_COLORS                 "SHELL_USE_ANSI_COLORS"
+#define CELIX_SHELL_USE_ANSI_COLORS_DEFAULT_VALUE   "true"
 
-#endif /* SHELL_CONSTANTS_H_ */
+#endif /* CELIX_SHELL_CONSTANTS_H_ */
diff --git a/bundles/shell/shell/include/dm_shell_list_command.h 
b/bundles/shell/shell/deprecated_api/command.h
similarity index 56%
copy from bundles/shell/shell/include/dm_shell_list_command.h
copy to bundles/shell/shell/deprecated_api/command.h
index 22263bc..9bfd726 100644
--- a/bundles/shell/shell/include/dm_shell_list_command.h
+++ b/bundles/shell/shell/deprecated_api/command.h
@@ -17,26 +17,20 @@
  * under the License.
  */
 
-#ifndef DM_SHELL_LIST_COMMAND_H_
-#define DM_SHELL_LIST_COMMAND_H_
+#ifndef COMMAND_H_
+#define COMMAND_H_
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+#include "celix_shell_command.h"
 
-#include <stdlib.h>
-#include <string.h>
-#include "command.h"
+#define OSGI_SHELL_COMMAND_NAME             CELIX_SHELL_COMMAND_NAME
+#define OSGI_SHELL_COMMAND_USAGE            CELIX_SHELL_COMMAND_USAGE
+#define OSGI_SHELL_COMMAND_DESCRIPTION      CELIX_SHELL_COMMAND_DESCRIPTION
 
-typedef struct dm_command_handle {
-    bundle_context_pt context;
-    bool useColors;
-} dm_command_handle_t;
+#define OSGI_SHELL_COMMAND_SERVICE_NAME     CELIX_SHELL_COMMAND_SERVICE_NAME
+#define OSGI_SHELL_COMMAND_SERVICE_VERSION  CELIX_SHELL_COMMAND_SERVICE_VERSION
 
-void dmListCommand_execute(dm_command_handle_t* handle, char * line, FILE 
*out, FILE *err);
+typedef celix_shell_command_t command_service_t; //use celix_command.h instead
+typedef celix_shell_command_t* command_service_pt; //use celix_command.h 
instead
 
-#ifdef __cplusplus
-}
-#endif
 
-#endif //DM_SHELL_LSIT_COMMAND_H_
\ No newline at end of file
+#endif /* COMMAND_H_ */
diff --git a/bundles/shell/shell/include/dm_shell_list_command.h 
b/bundles/shell/shell/deprecated_api/shell.h
similarity index 65%
rename from bundles/shell/shell/include/dm_shell_list_command.h
rename to bundles/shell/shell/deprecated_api/shell.h
index 22263bc..8d4034d 100644
--- a/bundles/shell/shell/include/dm_shell_list_command.h
+++ b/bundles/shell/shell/deprecated_api/shell.h
@@ -16,27 +16,17 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+#ifndef SHELL_H_
+#define SHELL_H_
 
-#ifndef DM_SHELL_LIST_COMMAND_H_
-#define DM_SHELL_LIST_COMMAND_H_
+__attribute__((deprecated))
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+#include "celix_shell.h"
 
-#include <stdlib.h>
-#include <string.h>
-#include "command.h"
+#define OSGI_SHELL_SERVICE_NAME     CELIX_SHELL_SERVICE_NAME
+#define OSGI_SHELL_SERVICE_VERSION  CELIX_SHELL_SERVICE_VERSION
 
-typedef struct dm_command_handle {
-    bundle_context_pt context;
-    bool useColors;
-} dm_command_handle_t;
+typedef celix_shell_t shell_service_t; //use celix_shell.h instead
+typedef celix_shell_t* shell_service_pt; //use celix_shell.h instead
 
-void dmListCommand_execute(dm_command_handle_t* handle, char * line, FILE 
*out, FILE *err);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif //DM_SHELL_LSIT_COMMAND_H_
\ No newline at end of file
+#endif /* SHELL_H_ */
diff --git a/bundles/shell/shell/include/shell_constants.h 
b/bundles/shell/shell/deprecated_api/shell_constants.h
similarity index 81%
rename from bundles/shell/shell/include/shell_constants.h
rename to bundles/shell/shell/deprecated_api/shell_constants.h
index 4ff67c0..37f1750 100644
--- a/bundles/shell/shell/include/shell_constants.h
+++ b/bundles/shell/shell/deprecated_api/shell_constants.h
@@ -20,7 +20,9 @@
 #ifndef SHELL_CONSTANTS_H_
 #define SHELL_CONSTANTS_H_
 
-#define SHELL_USE_ANSI_COLORS "SHELL_USE_ANSI_COLORS"
-#define SHELL_USE_ANSI_COLORS_DEFAULT_VALUE "true"
+#include "celix_shell_constants.h"
+
+#define SHELL_USE_ANSI_COLORS                   CELIX_SHELL_USE_ANSI_COLORS
+#define SHELL_USE_ANSI_COLORS_DEFAULT_VALUE     
CELIX_SHELL_USE_ANSI_COLORS_DEFAULT_VALUE
 
 #endif /* SHELL_CONSTANTS_H_ */
diff --git a/bundles/shell/shell/src/activator.c 
b/bundles/shell/shell/src/activator.c
index 486cccd..38170ff 100644
--- a/bundles/shell/shell/src/activator.c
+++ b/bundles/shell/shell/src/activator.c
@@ -40,14 +40,14 @@ struct command {
     char *name;
     char *description;
     char *usage;
-    command_service_t service;
+    celix_shell_command_t service;
     celix_properties_t *props;
     long svcId; //used for service (un)registration
 };
 
 struct shell_bundle_activator {
     shell_t *shell;
-    shell_service_t shellService;
+    celix_shell_t shellService;
        long shellSvcId;
        long trackerId;
 
@@ -137,19 +137,12 @@ celix_status_t 
bundleActivator_create(celix_bundle_context_t* ctx, void **_pptr)
                 };
         activator->std_commands[8] =
                 (struct command) {
-                        .exec = inspectCommand_execute,
-                        .name = "inspect",
-                        .description = "inspect services and components.",
-                        .usage = "inspect (service) (capability|requirement) 
[<id> ...]"
-                };
-        activator->std_commands[9] =
-                (struct command) {
                         .exec = dmListCommand_execute,
                         .name = "dm",
                         .description = "Gives an overview of the component 
managed by a dependency manager.",
                         .usage = "dm [wtf] [f|full] [<Bundle ID> [<Bundle ID> 
[...]]]"
                 };
-        activator->std_commands[10] =
+        activator->std_commands[9] =
                 (struct command) {
                     .exec = queryCommand_execute,
                     .name = "query",
@@ -162,12 +155,19 @@ celix_status_t 
bundleActivator_create(celix_bundle_context_t* ctx, void **_pptr)
                     "\n\tIf the -p option is provided, only query for provided 
services.",
                     .usage = "query [bundleId ...] [-v] [-p] [-r] [query ...]"
                 };
-        activator->std_commands[11] =
+        activator->std_commands[10] =
                 (struct command) {
-                        .exec = qCommand_execute,
+                        .exec = queryCommand_execute,
                         .name = "q",
+                        .description = "Proxy for query command (see 'help 
query')",
+                        .usage = "q [bundleId ...] [-v] [-p] [-r] [query ...]"
+                };
+        activator->std_commands[11] =
+                (struct command) {
+                        .exec = quitCommand_execute,
+                        .name = "quit",
                         .description = "Quit (exit) framework.",
-                        .usage = "q"
+                        .usage = "quit"
                 };
         activator->std_commands[12] =
                 (struct command) { NULL, NULL, NULL, NULL, {NULL,NULL}, NULL, 
-1L }; /*marker for last element*/
@@ -180,9 +180,9 @@ celix_status_t 
bundleActivator_create(celix_bundle_context_t* ctx, void **_pptr)
                 break;
             }
 
-            celix_properties_set(activator->std_commands[i].props, 
OSGI_SHELL_COMMAND_NAME, activator->std_commands[i].name);
-            celix_properties_set(activator->std_commands[i].props, 
OSGI_SHELL_COMMAND_USAGE, activator->std_commands[i].usage);
-            celix_properties_set(activator->std_commands[i].props, 
OSGI_SHELL_COMMAND_DESCRIPTION, activator->std_commands[i].description);
+            celix_properties_set(activator->std_commands[i].props, 
CELIX_SHELL_COMMAND_NAME, activator->std_commands[i].name);
+            celix_properties_set(activator->std_commands[i].props, 
CELIX_SHELL_COMMAND_USAGE, activator->std_commands[i].usage);
+            celix_properties_set(activator->std_commands[i].props, 
CELIX_SHELL_COMMAND_DESCRIPTION, activator->std_commands[i].description);
             celix_properties_set(activator->std_commands[i].props, 
CELIX_FRAMEWORK_SERVICE_LANGUAGE, CELIX_FRAMEWORK_SERVICE_C_LANGUAGE);
 
             activator->std_commands[i].service.handle = ctx;
@@ -221,8 +221,8 @@ celix_status_t bundleActivator_start(void *activatorData, 
celix_bundle_context_t
         activator->shellService.getCommands = (void*)shell_getCommands;
 
         celix_service_registration_options_t opts = 
CELIX_EMPTY_SERVICE_REGISTRATION_OPTIONS;
-        opts.serviceName = OSGI_SHELL_SERVICE_NAME;
-        opts.serviceVersion = OSGI_SHELL_SERVICE_VERSION;
+        opts.serviceName = CELIX_SHELL_SERVICE_NAME;
+        opts.serviceVersion = CELIX_SHELL_SERVICE_VERSION;
         opts.svc = &activator->shellService;
 
         activator->shellSvcId = 
celix_bundleContext_registerServiceWithOptions(ctx, &opts);
@@ -234,7 +234,7 @@ celix_status_t bundleActivator_start(void *activatorData, 
celix_bundle_context_t
            opts.addWithProperties = (void*) shell_addCommand;
            opts.removeWithProperties = (void*) shell_removeCommand;
            opts.filter.ignoreServiceLanguage = true;
-           opts.filter.serviceName = OSGI_SHELL_COMMAND_SERVICE_NAME;
+           opts.filter.serviceName = CELIX_SHELL_COMMAND_SERVICE_NAME;
            activator->trackerId = 
celix_bundleContext_trackServicesWithOptions(ctx, &opts);
     }
 
@@ -243,8 +243,8 @@ celix_status_t bundleActivator_start(void *activatorData, 
celix_bundle_context_t
         for (unsigned int i = 0; activator->std_commands[i].exec != NULL; i++) 
{
             celix_service_registration_options_t opts = 
CELIX_EMPTY_SERVICE_REGISTRATION_OPTIONS;
             opts.svc = &activator->std_commands[i].service;
-            opts.serviceName = OSGI_SHELL_COMMAND_SERVICE_NAME;
-            opts.serviceVersion = OSGI_SHELL_COMMAND_SERVICE_VERSION;
+            opts.serviceName = CELIX_SHELL_COMMAND_SERVICE_NAME;
+            opts.serviceVersion = CELIX_SHELL_COMMAND_SERVICE_VERSION;
             opts.properties = activator->std_commands[i].props;
             activator->std_commands[i].svcId = 
celix_bundleContext_registerServiceWithOptions(ctx, &opts);
         }
diff --git a/bundles/shell/shell/src/inspect_command.c 
b/bundles/shell/shell/src/inspect_command.c
deleted file mode 100644
index 67bb69b..0000000
--- a/bundles/shell/shell/src/inspect_command.c
+++ /dev/null
@@ -1,277 +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.
- */
-/**
- * inspect_command.c
- *
- *  \date       Oct 13, 2011
- *  \author            <a href="mailto:[email protected]";>Apache Celix 
Project Team</a>
- *  \copyright Apache License, Version 2.0
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "array_list.h"
-#include "bundle_context.h"
-
-#include "std_commands.h"
-
-#define SERVICE_TYPE "service"
-#define CAPABILITY "capability"
-#define REQUIREMENT "requirement"
-
-celix_status_t inspectCommand_printExportedServices(bundle_context_pt context, 
array_list_pt ids, FILE *outStream, FILE *errStream);
-celix_status_t inspectCommand_printImportedServices(bundle_context_pt context, 
array_list_pt ids, FILE *outStream, FILE *errStream);
-
-celix_status_t inspectCommand_execute(void *handle, char * commandline, FILE 
*outStream, FILE *errStream) {
-       celix_status_t status = CELIX_SUCCESS;
-
-       bundle_context_pt context = handle;
-
-       char *token;
-       strtok_r(commandline, " ", &token);
-       char *type = strtok_r(NULL, " ", &token);
-       if (type != NULL) {
-               char *direction = strtok_r(NULL, " ", &token);
-               if (direction != NULL) {
-                       array_list_pt ids = NULL;
-                       char *id = strtok_r(NULL, " ", &token);
-
-                       arrayList_create(&ids);
-                       while (id != NULL) {
-                               arrayList_add(ids, id);
-                               id = strtok_r(NULL, " ", &token);
-                       }
-
-                       if (strcmp(type, SERVICE_TYPE) == 0) {
-                               if (strcmp(direction, CAPABILITY) == 0) {
-                                       status = 
inspectCommand_printExportedServices(context, ids, outStream, errStream);
-                                       if (status != CELIX_SUCCESS) {
-                                               fprintf(errStream, "INSPECT: 
Error\n");
-                                       }
-                               } else if (strcmp(direction, REQUIREMENT) == 0) 
{
-                    status = inspectCommand_printImportedServices(context, 
ids, outStream, errStream);
-                    if (status != CELIX_SUCCESS) {
-                                               fprintf(errStream, "INSPECT: 
Error\n");
-                    }
-                               } else {
-                                       fprintf(errStream, "INSPECT: Invalid 
argument\n");
-                               }
-                       } else {
-                               fprintf(errStream, "INSPECT: Invalid 
argument\n");
-                       }
-                       arrayList_destroy(ids);
-               } else {
-                       fprintf(errStream, "INSPECT: Too few arguments\n");
-               }
-       } else {
-               fprintf(errStream, "INSPECT: Too few arguments\n");
-       }
-       return status;
-}
-
-celix_status_t inspectCommand_printExportedServices(bundle_context_pt context, 
array_list_pt ids, FILE *outStream, FILE *errStream) {
-       celix_status_t status = CELIX_SUCCESS;
-       array_list_pt bundles = NULL;
-
-       if (arrayList_isEmpty(ids)) {
-               status = bundleContext_getBundles(context, &bundles);
-       } else {
-               unsigned int i;
-
-               arrayList_create(&bundles);
-               for (i = 0; i < arrayList_size(ids); i++) {
-                       char *idStr = (char *) arrayList_get(ids, i);
-                       long id = atol(idStr);
-                       bundle_pt b = NULL;
-                       celix_status_t st = 
bundleContext_getBundleById(context, id, &b);
-                       if (st == CELIX_SUCCESS) {
-                               arrayList_add(bundles, b);
-                       } else {
-                               fprintf(outStream, "INSPECT: Invalid bundle ID: 
%ld\n", id);
-                       }
-               }
-       }
-
-       if (status == CELIX_SUCCESS) {
-               unsigned int i = 0;
-               for (i = 0; i < arrayList_size(bundles); i++) {
-                       bundle_pt bundle = (bundle_pt) arrayList_get(bundles, 
i);
-
-                       if (i > 0) {
-                               fprintf(outStream, "\n");
-                       }
-
-                       if (bundle != NULL) {
-                               array_list_pt refs = NULL;
-
-                               if (bundle_getRegisteredServices(bundle, &refs) 
== CELIX_SUCCESS) {
-                                       module_pt module = NULL;
-                                       const char * name = NULL;
-                                       status = 
bundle_getCurrentModule(bundle, &module);
-                                       if (status == CELIX_SUCCESS) {
-                                               status = 
module_getSymbolicName(module, &name);
-                                               if (status == CELIX_SUCCESS) {
-                                                       fprintf(outStream, "%s 
provides services:\n", name);
-                                                       fprintf(outStream, 
"==============\n");
-
-                                                       if (refs == NULL || 
arrayList_size(refs) == 0) {
-                                                               
fprintf(outStream, "Nothing\n");
-                                                       } else {
-                                                               unsigned int j 
= 0;
-                                                               for (j = 0; j < 
arrayList_size(refs); j++) {
-                                                                       
service_reference_pt ref = (service_reference_pt) arrayList_get(refs, j);
-                                                                       
unsigned int size = 0;
-                                                                       char 
**keys;
-
-                                                                       
serviceReference_getPropertyKeys(ref, &keys, &size);
-                                                                       for 
(int k = 0; k < size; k++) {
-                                                                           
char *key = keys[k];
-                                                                           
const char *value = NULL;
-                                                                           
serviceReference_getProperty(ref, key, &value);
-
-                                                                               
fprintf(outStream, "%s = %s\n", key, value);
-                                                                       }
-
-                                                                       
free(keys);
-
-//                                                                     
objectClass = properties_get(props, (char *) OSGI_FRAMEWORK_OBJECTCLASS);
-//                                                                     
sprintf(line, "ObjectClass = %s\n", objectClass);
-                                                                       if ((j 
+ 1) < arrayList_size(refs)) {
-                                                                               
fprintf(outStream, "----\n");
-                                                                       }
-                                                               }
-                                                       }
-                                               }
-                                       }
-                               }
-
-                               if(refs!=NULL){
-                                       arrayList_destroy(refs);
-                               }
-                       }
-               }
-       }
-
-       if (bundles != NULL) {
-           arrayList_destroy(bundles);
-       }
-
-       return status;
-}
-
-celix_status_t inspectCommand_printImportedServices(bundle_context_pt context, 
array_list_pt ids, FILE *outStream, FILE *errStream) {
-    celix_status_t status = CELIX_SUCCESS;
-    array_list_pt bundles = NULL;
-
-    if (arrayList_isEmpty(ids)) {
-        status = bundleContext_getBundles(context, &bundles);
-    } else {
-        unsigned int i;
-
-        arrayList_create(&bundles);
-        for (i = 0; i < arrayList_size(ids); i++) {
-            char *idStr = (char *) arrayList_get(ids, i);
-            long id = atol(idStr);
-            bundle_pt b = NULL;
-            celix_status_t st = bundleContext_getBundleById(context, id, &b);
-            if (st == CELIX_SUCCESS) {
-                arrayList_add(bundles, b);
-            } else {
-                               fprintf(outStream, "INSPECT: Invalid bundle ID: 
%ld\n", id);
-            }
-        }
-    }
-
-    if (status == CELIX_SUCCESS) {
-        unsigned int i = 0;
-        for (i = 0; i < arrayList_size(bundles); i++) {
-            bundle_pt bundle = (bundle_pt) arrayList_get(bundles, i);
-
-            if (i > 0) {
-                               fprintf(outStream, "\n");
-            }
-
-            if (bundle != NULL) {
-                array_list_pt refs = NULL;
-
-                if (bundle_getServicesInUse(bundle, &refs) == CELIX_SUCCESS) {
-                    module_pt module = NULL;
-                    const char * name = NULL;
-                    status = bundle_getCurrentModule(bundle, &module);
-                    if (status == CELIX_SUCCESS) {
-                        status = module_getSymbolicName(module, &name);
-                        if (status == CELIX_SUCCESS) {
-                                                       fprintf(outStream, "%s 
requires services:\n", name);
-                                                       fprintf(outStream, 
"==============\n");
-
-                            if (refs == NULL || arrayList_size(refs) == 0) {
-                                                               
fprintf(outStream, "Nothing\n");
-                            } else {
-                                unsigned int j = 0;
-                                for (j = 0; j < arrayList_size(refs); j++) {
-                                    service_reference_pt ref = 
(service_reference_pt) arrayList_get(refs, j);
-                                    bundle_pt usedBundle = NULL;
-                                    module_pt usedModule = NULL;
-                                    const char *usedSymbolicName = NULL;
-                                    long usedBundleId;
-
-                                    serviceReference_getBundle(ref, 
&usedBundle);
-                                    bundle_getBundleId(usedBundle, 
&usedBundleId);
-                                    bundle_getCurrentModule(usedBundle, 
&usedModule);
-                                    module_getSymbolicName(usedModule, 
&usedSymbolicName);
-
-                                                                       
fprintf(outStream, "%s [%ld]\n", usedSymbolicName, usedBundleId);
-
-                                    unsigned int size = 0;
-                                    char **keys;
-
-                                    serviceReference_getPropertyKeys(ref, 
&keys, &size);
-                                    for (int k = 0; k < size; k++) {
-                                        char *key = keys[k];
-                                        const char *value = NULL;
-                                        serviceReference_getProperty(ref, key, 
&value);
-
-                                                                               
fprintf(outStream, "%s = %s\n", key, value);
-                                    }
-                                    free(keys);
-
-//                                  objectClass = properties_get(props, (char 
*) OSGI_FRAMEWORK_OBJECTCLASS);
-//                                  sprintf(line, "ObjectClass = %s\n", 
objectClass);
-                                    if ((j + 1) < arrayList_size(refs)) {
-                                                                               
fprintf(outStream, "----\n");
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-
-                if(refs!=NULL){
-                       arrayList_destroy(refs);
-                }
-            }
-        }
-    }
-
-    arrayList_destroy(bundles);
-
-
-    return status;
-}
diff --git a/bundles/shell/shell/src/query_command.c 
b/bundles/shell/shell/src/query_command.c
index 9d06049..1cc4707 100644
--- a/bundles/shell/shell/src/query_command.c
+++ b/bundles/shell/shell/src/query_command.c
@@ -41,6 +41,8 @@ struct query_options {
 struct bundle_callback_data {
     const struct query_options *opts;
     FILE *sout;
+    size_t nrOfProvidedServicesFound;
+    size_t nrOfRequestedServicesFound;
 };
 
 static bool queryCommand_printProvidedService(const struct query_options 
*opts, celix_bundle_service_list_entry_t *entry) {
@@ -89,9 +91,16 @@ static void queryCommand_callback(void *handle, const 
celix_bundle_t *bnd) {
         for (int i = 0; i < celix_arrayList_size(services); ++i) {
             celix_bundle_service_list_entry_t *entry = 
celix_arrayList_get(services, i);
             if (queryCommand_printProvidedService(data->opts, entry)) {
+                data->nrOfProvidedServicesFound += 1;
                 queryCommand_printBundleHeader(data->sout, bnd, 
&printBundleCalled);
-                fprintf(data->sout, "|- Provided service '%s' [id = %li]\n", 
entry->serviceName, entry->serviceId); //TODO underline if color enabled
+                fprintf(data->sout, "|- Provided service '%s' [id = %li]\n", 
entry->serviceName, entry->serviceId);
                 if (data->opts->verbose) {
+                    const char *cmpUUID = 
celix_properties_get(entry->serviceProperties, "component.uuid", NULL);
+                    if (cmpUUID != NULL) {
+                        //TODO add context to opts
+                        //TODO add celix_dependencyManager_createInfoForUUID() 
                   }
+                        //TODO print component name
+                    }
                     fprintf(data->sout, "   |- Is factory: %s\n", 
entry->factory ? "true" : "false");
                     fprintf(data->sout, "   |- Properties:\n");
                     const char *key;
@@ -109,8 +118,12 @@ static void queryCommand_callback(void *handle, const 
celix_bundle_t *bnd) {
         for (int i = 0; i < celix_arrayList_size(trackers); ++i) {
             celix_bundle_service_tracker_list_entry_t *entry = 
celix_arrayList_get(trackers, i);
             if (queryCommand_printRequestedService(data->opts, entry)) {
+                data->nrOfRequestedServicesFound += 1;
                 queryCommand_printBundleHeader(data->sout, bnd, 
&printBundleCalled);
                 fprintf(data->sout, "|- Service tracker '%s'\n", 
entry->filter);
+                if (data->opts->verbose) {
+                    fprintf(data->sout,"   |- nr of tracked services %lu\n", 
entry->nrOfTrackedServices);
+                }
             }
         }
         celix_bundle_destroyServiceTrackerList(trackers);
@@ -122,27 +135,39 @@ static void queryCommand_callback(void *handle, const 
celix_bundle_t *bnd) {
 }
 
 
-static void queryCommand_listServicesForBundle(celix_bundle_context_t *ctx, 
long bndId, const struct query_options *opts, FILE *sout, FILE *serr) {
-    struct bundle_callback_data data;
-    data.opts = opts;
-    data.sout = sout;
-    bool called = celix_bundleContext_useBundle(ctx, bndId, &data, 
queryCommand_callback);
+static void queryCommand_listServicesForBundle(celix_bundle_context_t *ctx, 
long bndId, struct bundle_callback_data *data, const struct query_options 
*opts, FILE *sout, FILE *serr) {
+    bool called = celix_bundleContext_useBundle(ctx, bndId, data, 
queryCommand_callback);
     if (!called) {
         fprintf(serr, "Bundle %li not installed!", bndId);
     }
 }
 
 static void queryCommand_listServices(celix_bundle_context_t *ctx, const 
struct query_options *opts, FILE *sout, FILE *serr) {
+    struct bundle_callback_data data;
+    data.opts = opts;
+    data.sout = sout;
+    data.nrOfProvidedServicesFound = 0;
+    data.nrOfRequestedServicesFound = 0;
+
     if (opts->bndId >= 0L) {
-        queryCommand_listServicesForBundle(ctx, opts->bndId, opts, sout, serr);
+        queryCommand_listServicesForBundle(ctx, opts->bndId, &data, opts, 
sout, serr);
     } else {
         celix_array_list_t *bundleIds = celix_bundleContext_listBundles(ctx);
         for (int i = 0; i < celix_arrayList_size(bundleIds); ++i) {
             long bndId = celix_arrayList_getLong(bundleIds, i);
-            queryCommand_listServicesForBundle(ctx, bndId, opts, sout, serr);
+            queryCommand_listServicesForBundle(ctx, bndId, &data, opts, sout, 
serr);
         }
         celix_arrayList_destroy(bundleIds);
     }
+
+    if (data.nrOfRequestedServicesFound == 0 && data.nrOfProvidedServicesFound 
== 0) {
+        fprintf(sout, "No results\n");
+    } else {
+        fprintf(sout, "Query result:\n");
+        fprintf(sout, "|- Provided services found %lu\n", 
data.nrOfProvidedServicesFound);
+        fprintf(sout, "|- Requested services found %lu\n", 
data.nrOfRequestedServicesFound);
+        fprintf(sout, "\n");
+    }
 }
 
 
@@ -150,6 +175,8 @@ celix_status_t queryCommand_execute(void *_ptr, char 
*command_line_str, FILE *so
     celix_status_t status = CELIX_SUCCESS;
     bundle_context_t* ctx = _ptr;
 
+    char *commandLine = celix_utils_strdup(command_line_str); //note 
command_line_str should be treated as const.
+
     struct query_options opts;
     memset(&opts, 0, sizeof(opts));
     opts.bndId = -1L;
@@ -171,7 +198,7 @@ celix_status_t queryCommand_execute(void *_ptr, char 
*command_line_str, FILE *so
         char *sub_str = NULL;
         char *save_ptr = NULL;
 
-        strtok_r(command_line_str, OSGI_SHELL_COMMAND_SEPARATOR, &save_ptr);
+        strtok_r(commandLine, OSGI_SHELL_COMMAND_SEPARATOR, &save_ptr);
         sub_str = strtok_r(NULL, OSGI_SHELL_COMMAND_SEPARATOR, &save_ptr);
         while (sub_str != NULL) {
             if (strcmp(sub_str, "-v") == 0) {
@@ -210,6 +237,8 @@ celix_status_t queryCommand_execute(void *_ptr, char 
*command_line_str, FILE *so
         }
     }
 
+    free(commandLine);
+
     if (validCommand) {
         queryCommand_listServices(ctx, &opts, sout, serr);
     }
diff --git a/bundles/shell/shell/src/q_command.c 
b/bundles/shell/shell/src/quit_command.c
similarity index 87%
rename from bundles/shell/shell/src/q_command.c
rename to bundles/shell/shell/src/quit_command.c
index db60e61..1b5d6eb 100644
--- a/bundles/shell/shell/src/q_command.c
+++ b/bundles/shell/shell/src/quit_command.c
@@ -19,7 +19,7 @@
 
 #include "celix_bundle_context.h"
 
-celix_status_t qCommand_execute(void *_ptr, char *command_line_str 
__attribute__((unused)), FILE *sout, FILE *serr __attribute__((unused))) {
+celix_status_t quitCommand_execute(void *_ptr, char *command_line_str 
__attribute__((unused)), FILE *sout, FILE *serr __attribute__((unused))) {
     bundle_context_t* ctx = _ptr;
     fprintf(sout, "Quitting framework\n");
     celix_bundleContext_stopBundle(ctx, 0L);
diff --git a/bundles/shell/shell/src/shell.c b/bundles/shell/shell/src/shell.c
index bc67700..0fa876c 100644
--- a/bundles/shell/shell/src/shell.c
+++ b/bundles/shell/shell/src/shell.c
@@ -55,7 +55,7 @@ void shell_destroy(shell_t *shell) {
     }
 }
 
-celix_status_t shell_addCommand(shell_t *shell, command_service_t *svc, const 
celix_properties_t *props) {
+celix_status_t shell_addCommand(shell_t *shell, celix_shell_command_t *svc, 
const celix_properties_t *props) {
     celix_status_t status = CELIX_SUCCESS;
     const char *name = celix_properties_get(props, "command.name", NULL);
 
@@ -80,7 +80,7 @@ celix_status_t shell_addCommand(shell_t *shell, 
command_service_t *svc, const ce
     return status;
 }
 
-celix_status_t shell_removeCommand(shell_t *shell, command_service_t *svc, 
const celix_properties_t *props) {
+celix_status_t shell_removeCommand(shell_t *shell, celix_shell_command_t *svc, 
const celix_properties_t *props) {
     celix_status_t status = CELIX_SUCCESS;
     const char *name = celix_properties_get(props, "command.name", NULL);
 
@@ -131,7 +131,7 @@ celix_status_t shell_getCommandUsage(shell_t *shell, const 
char *commandName, ch
     celixThreadMutex_lock(&shell->mutex);
     celix_shell_command_entry_t *entry = hashMap_get(shell->commandServices, 
commandName);
     if (entry != NULL) {
-        const char *usage = celix_properties_get(entry->props, 
OSGI_SHELL_COMMAND_USAGE, "N/A");
+        const char *usage = celix_properties_get(entry->props, 
CELIX_SHELL_COMMAND_USAGE, "N/A");
         *outUsage = strndup(usage, 1024*1024*10);
     } else {
         *outUsage = NULL;
@@ -148,7 +148,7 @@ celix_status_t shell_getCommandDescription(shell_t *shell, 
const char *commandNa
     celixThreadMutex_lock(&shell->mutex);
     celix_shell_command_entry_t *entry = hashMap_get(shell->commandServices, 
commandName);
     if (entry != NULL) {
-        const char *desc = celix_properties_get(entry->props, 
OSGI_SHELL_COMMAND_DESCRIPTION, "N/A");
+        const char *desc = celix_properties_get(entry->props, 
CELIX_SHELL_COMMAND_DESCRIPTION, "N/A");
         *outDescription = strndup(desc, 1024*1024*10);
     } else {
         *outDescription = NULL;
diff --git a/bundles/shell/shell/src/shell_private.h 
b/bundles/shell/shell/src/shell_private.h
index b845ef1..496fcc0 100644
--- a/bundles/shell/shell/src/shell_private.h
+++ b/bundles/shell/shell/src/shell_private.h
@@ -28,14 +28,14 @@
 #define SHELL_PRIVATE_H_
 
 #include "bundle_context.h"
-#include "shell.h"
+#include "celix_shell.h"
 #include "hash_map.h"
-#include "command.h"
+#include "celix_shell_command.h"
 #include "log_helper.h"
 
 typedef struct celix_shell_command_entry {
     long svcId;
-    command_service_t *svc;
+    celix_shell_command_t *svc;
     const celix_properties_t *props;
 } celix_shell_command_entry_t;
 
@@ -49,8 +49,8 @@ typedef struct shell shell_t;
 
 shell_t* shell_create(celix_bundle_context_t *ctx);
 void shell_destroy(shell_t *shell);
-celix_status_t shell_addCommand(shell_t *shell, command_service_t *svc, const 
celix_properties_t *props);
-celix_status_t shell_removeCommand(shell_t *shell, command_service_t *svc, 
const celix_properties_t *props);
+celix_status_t shell_addCommand(shell_t *shell, celix_shell_command_t *svc, 
const celix_properties_t *props);
+celix_status_t shell_removeCommand(shell_t *shell, celix_shell_command_t *svc, 
const celix_properties_t *props);
 
 celix_status_t shell_executeCommand(shell_t *shell, const char *commandLine, 
FILE *out, FILE *err);
 
diff --git a/bundles/shell/shell/src/std_commands.h 
b/bundles/shell/shell/src/std_commands.h
index ef15f93..aabe95a 100644
--- a/bundles/shell/shell/src/std_commands.h
+++ b/bundles/shell/shell/src/std_commands.h
@@ -40,10 +40,9 @@ celix_status_t installCommand_execute(void *handle, char * 
commandline, FILE *ou
 celix_status_t uninstallCommand_execute(void *handle, char * commandline, FILE 
*outStream, FILE *errStream);
 celix_status_t updateCommand_execute(void *handle, char * commandline, FILE 
*outStream, FILE *errStream);
 celix_status_t logCommand_execute(void *handle, char * commandline, FILE 
*outStream, FILE *errStream);
-celix_status_t inspectCommand_execute(void *handle, char * commandline, FILE 
*outStream, FILE *errStream);
 celix_status_t helpCommand_execute(void *handle, char * commandline, FILE 
*outStream, FILE *errStream);
 celix_status_t dmListCommand_execute(void* handle, char * line, FILE *out, 
FILE *err);
-celix_status_t qCommand_execute(void *_ptr, char *command_line_str, FILE 
*sout, FILE *serr);
+celix_status_t quitCommand_execute(void *_ptr, char *command_line_str, FILE 
*sout, FILE *serr);
 
 
 #endif
diff --git a/bundles/shell/shell/test/CMakeLists.txt 
b/bundles/shell/shell/test/CMakeLists.txt
new file mode 100644
index 0000000..9e7023f
--- /dev/null
+++ b/bundles/shell/shell/test/CMakeLists.txt
@@ -0,0 +1,31 @@
+# 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.
+
+find_package(CppUTest REQUIRED)
+
+add_executable(test_shell
+    src/run_tests.cpp
+    src/shell_tests.cpp
+)
+
+target_link_libraries(test_shell Celix::framework CURL::libcurl 
${CPPUTEST_LIBRARY} Celix::shell_api)
+add_dependencies(test_shell shell_bundle)
+target_compile_definitions(test_shell PRIVATE 
-DSHELL_BUNDLE_LOCATION=\"$<TARGET_PROPERTY:shell,BUNDLE_FILE>\")
+
+add_test(NAME test_shell COMMAND test_shell)
+SETUP_TARGET_FOR_COVERAGE(test_shell_cov test_shell 
${CMAKE_BINARY_DIR}/coverage/test_shell/test_shell ..)
+
diff --git a/libs/framework/tst/run_tests.cpp 
b/bundles/shell/shell/test/src/run_tests.cpp
similarity index 94%
copy from libs/framework/tst/run_tests.cpp
copy to bundles/shell/shell/test/src/run_tests.cpp
index c0d52be..efaee82 100644
--- a/libs/framework/tst/run_tests.cpp
+++ b/bundles/shell/shell/test/src/run_tests.cpp
@@ -21,5 +21,6 @@
 #include "CppUTest/CommandLineTestRunner.h"
 
 int main(int argc, char** argv) {
+    MemoryLeakWarningPlugin::turnOffNewDeleteOverloads();
     return RUN_ALL_TESTS(argc, argv);
 }
\ No newline at end of file
diff --git a/bundles/shell/shell/test/src/shell_tests.cpp 
b/bundles/shell/shell/test/src/shell_tests.cpp
new file mode 100644
index 0000000..4600c80
--- /dev/null
+++ b/bundles/shell/shell/test/src/shell_tests.cpp
@@ -0,0 +1,105 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <thread>
+#include <chrono>
+#include <iostream>
+#include <mutex>
+#include <condition_variable>
+
+#include <zconf.h>
+
+#include "celix_api.h"
+#include "command.h"
+
+#include <CppUTest/TestHarness.h>
+#include <CppUTest/CommandLineTestRunner.h>
+
+#ifdef SHELL_BUNDLE_LOCATION
+const char * const SHELL_BUNDLE = SHELL_BUNDLE_LOCATION;
+#endif
+
+#ifdef __APPLE__
+#include "memstream/open_memstream.h"
+#else
+#include <stdio.h>
+#endif
+
+
+TEST_GROUP(CelixShellTests) {
+    framework_t* fw = nullptr;
+    bundle_context_t *ctx = nullptr;
+    celix_properties_t *properties = nullptr;
+
+    void setup() {
+        properties = celix_properties_create();
+        celix_properties_set(properties, "LOGHELPER_ENABLE_STDOUT_FALLBACK", 
"true");
+        celix_properties_set(properties, "org.osgi.framework.storage.clean", 
"onFirstInit");
+        celix_properties_set(properties, "org.osgi.framework.storage", 
".cacheBundleContextTestFramework");
+
+        fw = celix_frameworkFactory_createFramework(properties);
+        ctx = framework_getContext(fw);
+
+        long bndId = celix_bundleContext_installBundle(ctx, SHELL_BUNDLE, 
true);
+        CHECK_TRUE(bndId >= 0);
+    }
+
+    void teardown() {
+        celix_frameworkFactory_destroyFramework(fw);
+    }
+};
+
+TEST(CelixShellTests, shellBundleInstalledTest) {
+    auto *bndIds = celix_bundleContext_listBundles(ctx);
+    CHECK_EQUAL(1, celix_arrayList_size(bndIds));
+    celix_arrayList_destroy(bndIds);
+}
+
+TEST(CelixShellTests, queryTest) {
+    celix_service_use_options_t opts{};
+    opts.filter.serviceName = OSGI_SHELL_COMMAND_SERVICE_NAME;
+    opts.filter.filter = "(command.name=query)";
+    opts.waitTimeoutInSeconds = 1.0;
+    opts.use = [](void */*handle*/, void *svc) {
+        auto *command = static_cast<command_service_t*>(svc);
+        CHECK_TRUE(command != nullptr);
+
+        {
+            char *buf = nullptr;
+            size_t len;
+            FILE *sout = open_memstream(&buf, &len);
+            command->executeCommand(command->handle, (char *) "query", sout, 
sout);
+            fclose(sout);
+            STRCMP_CONTAINS("Provided services found 1", buf); //note could be 
11, 12, etc
+            //STRCMP_CONTAINS("Requested services found 1", buf); //note very 
explicit, could be improved
+            free(buf);
+        }
+        {
+            char *buf = nullptr;
+            size_t len;
+            FILE *sout = open_memstream(&buf, &len);
+            command->executeCommand(command->handle, (char *) "query 0", sout, 
sout); //note query framework bundle -> no results
+            fclose(sout);
+            STRCMP_CONTAINS("No results", buf); //note could be 11, 12, etc
+            free(buf);
+        }
+    };
+    bool called = celix_bundleContext_useServiceWithOptions(ctx, &opts);
+    CHECK_TRUE(called);
+}
diff --git a/bundles/shell/shell_tui/private/include/shell_tui.h 
b/bundles/shell/shell_tui/private/include/shell_tui.h
index 05786e3..90061ad 100644
--- a/bundles/shell/shell_tui/private/include/shell_tui.h
+++ b/bundles/shell/shell_tui/private/include/shell_tui.h
@@ -30,7 +30,7 @@
 #include <stdlib.h>
 
 #include "celix_threads.h"
-#include "shell.h"
+#include "celix_shell.h"
 
 typedef struct shell_tui shell_tui_t ;
 
@@ -39,6 +39,6 @@ celix_status_t shellTui_start(shell_tui_t* shellTui);
 celix_status_t shellTui_stop(shell_tui_t* shellTui);
 void shellTui_destroy(shell_tui_t* shellTui);
 
-celix_status_t shellTui_setShell(shell_tui_t* shellTui, shell_service_t* svc);
+celix_status_t shellTui_setShell(shell_tui_t* shellTui, celix_shell_t* svc);
 
 #endif /* SHELL_TUI_H_ */
diff --git a/bundles/shell/shell_tui/private/src/activator.c 
b/bundles/shell/shell_tui/private/src/activator.c
index fb422a2..9dc4da5 100644
--- a/bundles/shell/shell_tui/private/src/activator.c
+++ b/bundles/shell/shell_tui/private/src/activator.c
@@ -28,6 +28,7 @@
 
 
 #include "shell_tui.h"
+#include "celix_shell.h"
 #include "service_tracker.h"
 
 #define SHELL_USE_ANSI_CONTROL_SEQUENCES "SHELL_USE_ANSI_CONTROL_SEQUENCES"
@@ -35,7 +36,7 @@
 typedef struct shell_tui_activator {
     shell_tui_t* shellTui;
     long trackerId;
-    shell_service_t* currentSvc;
+    celix_shell_t* currentSvc;
     bool useAnsiControlSequences;
 } shell_tui_activator_t;
 
@@ -67,7 +68,7 @@ celix_status_t bundleActivator_create(bundle_context_pt 
context, void **userData
 
         {
             celix_service_tracking_options_t opts = 
CELIX_EMPTY_SERVICE_TRACKING_OPTIONS;
-            opts.filter.serviceName = OSGI_SHELL_SERVICE_NAME;
+            opts.filter.serviceName = CELIX_SHELL_SERVICE_NAME;
             opts.callbackHandle = activator->shellTui;
             opts.set = (void*)shellTui_setShell;
 
diff --git a/libs/framework/CMakeLists.txt b/libs/framework/CMakeLists.txt
index 0ad8364..1d0a14c 100644
--- a/libs/framework/CMakeLists.txt
+++ b/libs/framework/CMakeLists.txt
@@ -132,6 +132,7 @@ if (ENABLE_TESTING AND FRAMEWORK_TESTS)
         private/mock/resolver_mock.c
         private/mock/version_mock.c
         private/mock/service_registry_mock.c
+        private/mock/service_tracker_stub.c
         src/bundle.c
         src/celix_errorcodes.c
         private/mock/celix_log_mock.c)
diff --git a/libs/framework/include/celix_bundle.h 
b/libs/framework/include/celix_bundle.h
index c6a2ab0..4cb898b 100644
--- a/libs/framework/include/celix_bundle.h
+++ b/libs/framework/include/celix_bundle.h
@@ -19,6 +19,8 @@
 
 #include "celix_types.h"
 #include "bundle_state.h"
+#include "celix_properties.h"
+#include "celix_array_list.h"
 
 #ifndef CELIX_BUNDLE_H_
 #define CELIX_BUNDLE_H_
@@ -97,6 +99,7 @@ typedef struct celix_bundle_service_tracker_list_entry {
     char *filter;
     char *serviceName;
     long bundleOwner;
+    size_t nrOfTrackedServices;
 } celix_bundle_service_tracker_list_entry_t;
 
 
diff --git a/libs/framework/include/celix_dm_component.h 
b/libs/framework/include/celix_dm_component.h
index 8a645cc..38bb88b 100644
--- a/libs/framework/include/celix_dm_component.h
+++ b/libs/framework/include/celix_dm_component.h
@@ -32,6 +32,8 @@
 extern "C" {
 #endif
 
+#define CELIX_DM_COMPONENT_UUID     "component.uuid"
+
 typedef enum celix_dm_component_state_enum {
     DM_CMP_STATE_INACTIVE = 1,
     DM_CMP_STATE_WAITING_FOR_REQUIRED = 2,
diff --git a/libs/framework/include/service_tracker.h 
b/libs/framework/include/service_tracker.h
index a8bc6b1..4b58e10 100644
--- a/libs/framework/include/service_tracker.h
+++ b/libs/framework/include/service_tracker.h
@@ -16,13 +16,6 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-/**
- * service_tracker.h
- *
- *  \date       Apr 20, 2010
- *  \author            <a href="mailto:[email protected]";>Apache Celix 
Project Team</a>
- *  \copyright Apache License, Version 2.0
- */
 
 #ifndef SERVICE_TRACKER_H_
 #define SERVICE_TRACKER_H_
@@ -70,6 +63,9 @@ FRAMEWORK_EXPORT void 
*serviceTracker_getServiceByReference(service_tracker_t *t
 
 FRAMEWORK_EXPORT void serviceTracker_serviceChanged(celix_service_listener_t 
*listener, celix_service_event_t *event);
 
+FRAMEWORK_EXPORT size_t serviceTracker_nrOfTrackedServices(service_tracker_t 
*tracker);
+
+
 
 
 
/**********************************************************************************************************************
diff --git a/libs/framework/private/mock/service_tracker_customizer_mock.c 
b/libs/framework/private/mock/service_tracker_customizer_mock.c
index 0fc80d5..5174245 100644
--- a/libs/framework/private/mock/service_tracker_customizer_mock.c
+++ b/libs/framework/private/mock/service_tracker_customizer_mock.c
@@ -82,6 +82,3 @@ celix_status_t 
serviceTrackerCustomizer_getRemovedFunction(service_tracker_custo
                        ->withOutputParameter("function", (void **) function);
        return mock_c()->returnValue().value.intValue;
 }
-
-
-
diff --git a/libs/framework/private/mock/service_tracker_stub.c 
b/libs/framework/private/mock/service_tracker_stub.c
index b33cd46..c1ef8dc 100644
--- a/libs/framework/private/mock/service_tracker_stub.c
+++ b/libs/framework/private/mock/service_tracker_stub.c
@@ -20,4 +20,5 @@
 #include "service_tracker.h"
 
 void celix_serviceTracker_syncForContext(void *_ignore){}
-void celix_serviceTracker_syncForFramework(void *_ignore){}
\ No newline at end of file
+void celix_serviceTracker_syncForFramework(void *_ignore){}
+size_t serviceTracker_nrOfTrackedServices(service_tracker_t *tracker) { return 
0; }
\ No newline at end of file
diff --git a/libs/framework/src/bundle.c b/libs/framework/src/bundle.c
index 9b1d4bf..9ba5d87 100644
--- a/libs/framework/src/bundle.c
+++ b/libs/framework/src/bundle.c
@@ -668,6 +668,7 @@ void 
celix_bundle_destroyRegisteredServicesList(celix_array_list_t* list) {
             celix_properties_destroy(entry->serviceProperties);
             free(entry);
         }
+        celix_arrayList_destroy(list);
     }
 }
 
@@ -675,19 +676,13 @@ celix_array_list_t* 
celix_bundle_listServiceTrackers(const celix_bundle_t *bnd)
     celix_array_list_t* result = celix_arrayList_create();
     //FIXME: should not fall back to bundle context, but for now that is were 
the trackers are stored.
     celixThreadMutex_lock(&bnd->context->mutex);
-    //hash_map_t *serviceTrackers; //key = trackerId, value = 
celix_service_tracker_t*
     hash_map_iterator_t iter = 
hashMapIterator_construct(bnd->context->serviceTrackers);
     while (hashMapIterator_hasNext(&iter)) {
         celix_service_tracker_t *tracker = hashMapIterator_nextValue(&iter);
         celix_bundle_service_tracker_list_entry_t *entry = calloc(1, 
sizeof(*entry));
         entry->filter = celix_utils_strdup(tracker->filter);
-        celix_filter_t *f = celix_filter_create(entry->filter);
-        if (f != NULL) {
-            const char *sn = celix_filter_findAttribute(f, 
OSGI_FRAMEWORK_OBJECTCLASS);
-            if (sn != NULL) {
-                entry->serviceName = celix_utils_strdup(sn);
-            }
-        }
+        entry->nrOfTrackedServices = 
serviceTracker_nrOfTrackedServices(tracker);
+        entry->serviceName = celix_utils_strdup(tracker->serviceName);
         entry->bundleOwner = celix_bundle_getId(bnd);
 
         if (entry->serviceName != NULL) {
@@ -711,5 +706,6 @@ void 
celix_bundle_destroyServiceTrackerList(celix_array_list_t* list) {
             free(entry->serviceName);
             free(entry);
         }
+        celix_arrayList_destroy(list);
     }
 }
\ No newline at end of file
diff --git a/libs/framework/src/dm_component_impl.c 
b/libs/framework/src/dm_component_impl.c
index 70bdfaa..b76f8e9 100644
--- a/libs/framework/src/dm_component_impl.c
+++ b/libs/framework/src/dm_component_impl.c
@@ -16,17 +16,12 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-/**
- * dm_component_impl.c
- *
- *  \date       9 Oct 2014
- *  \author     <a href="mailto:[email protected]";>Apache Celix Project 
Team</a>
- *  \copyright  Apache License, Version 2.0
- */
+
 
 #include <stdarg.h>
 #include <stdlib.h>
 #include <string.h>
+#include <uuid/uuid.h>
 
 #include "celix_constants.h"
 #include "filter.h"
@@ -65,8 +60,8 @@ struct celix_dm_component_struct {
 typedef struct dm_interface_struct {
     char* serviceName;
     const void* service;
-    properties_pt properties;
-    service_registration_pt registration;
+    celix_properties_t *properties;
+    long svcId;
 } dm_interface_t;
 
 struct dm_executor_struct {
@@ -131,7 +126,13 @@ static celix_status_t 
component_resume(celix_dm_component_t *component, celix_dm
 
 celix_dm_component_t* celix_dmComponent_create(bundle_context_t *context, 
const char* name) {
     celix_dm_component_t *component = calloc(1, sizeof(*component));
-    snprintf(component->id, DM_COMPONENT_MAX_ID_LENGTH, "%p", component);
+
+    //gen uuid
+    uuid_t uid;
+    uuid_generate(uid);
+    uuid_unparse(uid, component->id);
+    //snprintf(component->id, DM_COMPONENT_MAX_ID_LENGTH, "%p", component);
+
     snprintf(component->name, DM_COMPONENT_MAX_NAME_LENGTH, "%s", name == NULL 
? "n/a" : name);
 
     component->context = context;
@@ -374,22 +375,24 @@ celix_status_t 
celix_dmComponent_addInterface(celix_dm_component_t *component, c
     char *name = strdup(serviceName);
 
     if (properties == NULL) {
-        properties = properties_create();
+        properties = celix_properties_create();
     }
 
     if ((properties_get(properties, CELIX_FRAMEWORK_SERVICE_VERSION) == NULL) 
&& (serviceVersion != NULL)) {
-        properties_set(properties, CELIX_FRAMEWORK_SERVICE_VERSION, 
serviceVersion);
+        celix_properties_set(properties, CELIX_FRAMEWORK_SERVICE_VERSION, 
serviceVersion);
     }
 
     if (component->setCLanguageProperty && properties_get(properties, 
CELIX_FRAMEWORK_SERVICE_LANGUAGE) == NULL) { //always set default lang to C
-        properties_set(properties, CELIX_FRAMEWORK_SERVICE_LANGUAGE, 
CELIX_FRAMEWORK_SERVICE_C_LANGUAGE);
+        celix_properties_set(properties, CELIX_FRAMEWORK_SERVICE_LANGUAGE, 
CELIX_FRAMEWORK_SERVICE_C_LANGUAGE);
     }
 
+    celix_properties_set(properties, CELIX_DM_COMPONENT_UUID, 
(char*)component->id);
+
     if (interface && name) {
         interface->serviceName = name;
         interface->service = service;
         interface->properties = properties;
-        interface->registration = NULL;
+        interface->svcId= -1L;
         celixThreadMutex_lock(&component->mutex);
         arrayList_add(component->dm_interfaces, interface);
         celixThreadMutex_unlock(&component->mutex);
@@ -1247,11 +1250,14 @@ static celix_status_t 
component_registerServices(celix_dm_component_t *component
         celixThreadMutex_lock(&component->mutex);
         for (i = 0; i < arrayList_size(component->dm_interfaces); i++) {
             dm_interface_t *interface = 
arrayList_get(component->dm_interfaces, i);
-            if (interface->registration == NULL) {
-                properties_pt regProps = NULL;
-                properties_copy(interface->properties, &regProps);
-                bundleContext_registerService(component->context, 
interface->serviceName, interface->service, regProps,
-                                              &interface->registration);
+            if (interface->svcId == -1L) {
+                celix_properties_t *regProps = 
celix_properties_copy(interface->properties);
+                celix_service_registration_options_t opts = 
CELIX_EMPTY_SERVICE_REGISTRATION_OPTIONS;
+                opts.properties = regProps;
+                opts.svc = (void*)interface->service;
+                opts.serviceName = interface->serviceName;
+                opts.serviceLanguage = celix_properties_get(regProps, 
CELIX_FRAMEWORK_SERVICE_LANGUAGE, NULL);
+                interface->svcId = 
celix_bundleContext_registerServiceWithOptions(component->context, &opts);
             }
         }
         celixThreadMutex_unlock(&component->mutex);
@@ -1263,17 +1269,23 @@ static celix_status_t 
component_registerServices(celix_dm_component_t *component
 static celix_status_t component_unregisterServices(celix_dm_component_t 
*component) {
     celix_status_t status = CELIX_SUCCESS;
 
-    unsigned int i;
+    celix_array_list_t *ids = celix_arrayList_create();
 
     celixThreadMutex_lock(&component->mutex);
-    for (i = 0; i < arrayList_size(component->dm_interfaces); i++) {
+    for (int i = 0; i < celix_arrayList_size(component->dm_interfaces); ++i) {
            dm_interface_t *interface = arrayList_get(component->dm_interfaces, 
i);
-
-           serviceRegistration_unregister(interface->registration);
-           interface->registration = NULL;
+           celix_arrayList_addLong(ids, interface->svcId);
+           interface->svcId = -1L;
     }
     celixThreadMutex_unlock(&component->mutex);
 
+    for (int i = 0; i < celix_arrayList_size(ids); ++i) {
+        long svcId = celix_arrayList_getLong(ids, i);
+        celix_bundleContext_unregisterService(component->context, svcId);
+    }
+
+    celix_arrayList_destroy(ids);
+
     return status;
 }
 
diff --git a/libs/framework/src/framework.c b/libs/framework/src/framework.c
index 0d586ec..d90b9de 100644
--- a/libs/framework/src/framework.c
+++ b/libs/framework/src/framework.c
@@ -979,6 +979,14 @@ celix_status_t fw_startBundle(framework_pt framework, 
bundle_pt bundle, int opti
 
                         if (status != CELIX_SUCCESS) {
                             //state is still STARTING, back to resolved
+                            bool createCalled = activator != NULL && 
activator->userData != NULL;
+                            if (createCalled) {
+                                destroy(activator->userData, context);
+                            }
+                            bundle_setContext(bundle, NULL);
+                            bundle_setActivator(bundle, NULL);
+                            bundleContext_destroy(context);
+                            free(activator);
                             framework_setBundleStateAndNotify(framework, 
bundle, OSGI_FRAMEWORK_BUNDLE_RESOLVED);
                         }
                     }
diff --git a/libs/framework/src/service_tracker.c 
b/libs/framework/src/service_tracker.c
index 9b24de8..dd29d78 100644
--- a/libs/framework/src/service_tracker.c
+++ b/libs/framework/src/service_tracker.c
@@ -24,6 +24,7 @@
 #include "framework_private.h"
 #include <assert.h>
 #include <unistd.h>
+#include <celix_api.h>
 
 #include "service_tracker_private.h"
 #include "bundle_context.h"
@@ -147,6 +148,7 @@ celix_status_t serviceTracker_destroy(service_tracker_pt 
tracker) {
            serviceTrackerCustomizer_destroy(tracker->customizer);
        }
 
+    free(tracker->serviceName);
        free(tracker->filter);
        free(tracker);
 
@@ -449,6 +451,16 @@ void 
serviceTracker_serviceChanged(celix_service_listener_t *listener, celix_ser
     }
 }
 
+size_t serviceTracker_nrOfTrackedServices(service_tracker_t *tracker) {
+    size_t result = 0;
+    celixThreadRwlock_readLock(&tracker->instanceLock);
+    celixThreadRwlock_readLock(&tracker->instance->lock);
+    result = (size_t) arrayList_size(tracker->instance->trackedServices);
+    celixThreadRwlock_unlock(&tracker->instance->lock);
+    celixThreadRwlock_unlock(&tracker->instanceLock);
+    return result;
+}
+
 static celix_status_t serviceTracker_track(celix_service_tracker_instance_t 
*instance, service_reference_pt reference, celix_service_event_t *event) {
        celix_status_t status = CELIX_SUCCESS;
 
@@ -726,6 +738,7 @@ celix_service_tracker_t* 
celix_serviceTracker_createWithOptions(
         tracker = calloc(1, sizeof(*tracker));
         if (tracker != NULL) {
             tracker->context = ctx;
+            tracker->serviceName = 
celix_utils_strdup(opts->filter.serviceName);
 
             //setting callbacks
             tracker->callbackHandle = opts->callbackHandle;
diff --git a/libs/framework/src/service_tracker_private.h 
b/libs/framework/src/service_tracker_private.h
index a28204c..47b8fa7 100644
--- a/libs/framework/src/service_tracker_private.h
+++ b/libs/framework/src/service_tracker_private.h
@@ -16,13 +16,6 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-/**
- * service_tracker_private.h
- *
- *  \date       Feb 6, 2013
- *  \author     <a href="mailto:[email protected]";>Apache Celix Project 
Team</a>
- *  \copyright  Apache License, Version 2.0
- */
 
 #ifndef SERVICE_TRACKER_PRIVATE_H_
 #define SERVICE_TRACKER_PRIVATE_H_
@@ -72,7 +65,8 @@ typedef struct celix_service_tracker_instance {
 struct celix_serviceTracker {
        bundle_context_t *context;
 
-       char * filter;
+       char* serviceName;
+       char* filter;
        service_tracker_customizer_t *customizer;
 
        void *callbackHandle;
diff --git a/libs/framework/tst/bundle_context_bundles_tests.cpp 
b/libs/framework/tst/bundle_context_bundles_tests.cpp
index d492875..9f8794b 100644
--- a/libs/framework/tst/bundle_context_bundles_tests.cpp
+++ b/libs/framework/tst/bundle_context_bundles_tests.cpp
@@ -283,6 +283,7 @@ TEST(CelixBundleContextBundlesTests, trackBundlesTest) {
     CHECK_EQUAL(2, data.count);
 
     /* TODO does not work -> stopping bundle event is never forward to the 
bundle listener ?? very old bug?
+     * See gh-145
     celix_bundleContext_uninstallBundle(ctx, bundleId2);
     {
         std::unique_lock<std::mutex> lock{data.mutex};
@@ -378,4 +379,39 @@ TEST(CelixBundleContextBundlesTests, 
useBundlesConcurrentTest) {
     std::cout << "use thread joined" << std::endl;
     uninstallThread.join();
     std::cout << "uninstall thread joined" << std::endl;
-};*/
\ No newline at end of file
+};*/
+
+TEST(CelixBundleContextBundlesTests, bundleInfoTests) {
+    struct data {
+        int provideCount{0};
+        int requestedCount{0};
+    };
+    struct data data;
+
+    void (*updateCountFp)(void *, const celix_bundle_t*) = [](void *handle, 
const celix_bundle_t *bnd) {
+        auto *data = static_cast<struct data*>(handle);
+        auto *trackers = celix_bundle_listServiceTrackers(bnd);
+        auto *services = celix_bundle_listRegisteredServices(bnd);
+        data->requestedCount = celix_arrayList_size(trackers);
+        data->provideCount = celix_arrayList_size(services);
+        celix_bundle_destroyServiceTrackerList(trackers);
+        celix_bundle_destroyRegisteredServicesList(services);
+    };
+
+    bool called = celix_bundleContext_useBundle(ctx, 0, &data, updateCountFp);
+    CHECK_TRUE(called);
+    CHECK_EQUAL(0, data.provideCount);
+    CHECK_EQUAL(0, data.requestedCount);
+
+
+    long svcId = celix_bundleContext_registerService(ctx, (void*)0x42, 
"NopService", NULL);
+    long trackerId = celix_bundleContext_trackServices(ctx, "AService", NULL, 
NULL, NULL);
+
+    called = celix_bundleContext_useBundle(ctx, 0, &data, updateCountFp);
+    CHECK_TRUE(called);
+    CHECK_EQUAL(1, data.provideCount);
+    CHECK_EQUAL(1, data.requestedCount);
+
+    celix_bundleContext_unregisterService(ctx, svcId);
+    celix_bundleContext_stopTracker(ctx, trackerId);
+}
\ No newline at end of file
diff --git a/libs/framework/tst/run_tests.cpp b/libs/framework/tst/run_tests.cpp
index c0d52be..efaee82 100644
--- a/libs/framework/tst/run_tests.cpp
+++ b/libs/framework/tst/run_tests.cpp
@@ -21,5 +21,6 @@
 #include "CppUTest/CommandLineTestRunner.h"
 
 int main(int argc, char** argv) {
+    MemoryLeakWarningPlugin::turnOffNewDeleteOverloads();
     return RUN_ALL_TESTS(argc, argv);
 }
\ No newline at end of file
diff --git a/libs/utils/include/celix_errno.h b/libs/utils/include/celix_errno.h
index fa08a13..6be0053 100644
--- a/libs/utils/include/celix_errno.h
+++ b/libs/utils/include/celix_errno.h
@@ -16,13 +16,6 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-/**
- * celix_errno.h
- *
- *  \date       Feb 15, 2011
- *  \author     <a href="mailto:[email protected]";>Apache Celix Project 
Team</a>
- *  \copyright  Apache License, Version 2.0
- */
 
 /*!
  * \file

Reply via email to