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

sseifert pushed a commit to branch master
in repository 
https://gitbox.apache.org/repos/asf/sling-org-apache-sling-testing-osgi-mock.git


The following commit(s) were added to refs/heads/master by this push:
     new 5259ab9  SLING-11698 Full support for ComponentServiceObjects (#24)
5259ab9 is described below

commit 5259ab9f849c6637c3422a417a4316258e94b0f2
Author: Stefan Seifert <[email protected]>
AuthorDate: Tue Nov 22 22:47:53 2022 +0100

    SLING-11698 Full support for ComponentServiceObjects (#24)
---
 .../sling/testing/mock/osgi/MockBundleContext.java |  14 ++-
 .../sling/testing/mock/osgi/OsgiServiceUtil.java   |  91 ++++++++++------
 ...eferencesOsgiR6ComponentServiceObjectsTest.java |  34 ++++++
 ...ckBundleContextDynamicReferencesOsgiR6Test.java |   7 +-
 ...ctionComponentServiceObjectsReferencesTest.java |  34 ++++++
 ...icGreedyConstructorInjectionReferencesTest.java |   6 +-
 .../testing/mock/osgi/OsgiServiceUtilTest.java     |  12 ++-
 test-services/pom.xml                              |   7 +-
 .../osgi/testsvc/osgiserviceutil/DictionaryTo.java |  42 ++++++++
 .../osgi/testsvc/osgiserviceutil/Service3.java     |  11 +-
 .../testsvc/osgiserviceutil/Service3OsgiR6.java    | 118 ++-------------------
 ...Service3OsgiR6ComponentServiceObjectsImpl.java} |  69 ++++++------
 ...Service3OsgiR6.java => Service3OsgiR6Impl.java} |  15 +--
 ...uctorInjectionComponentServiceObjectsImpl.java} |  61 ++++++-----
 ...rvice3StaticGreedyConstructorInjectionImpl.java |   1 +
 .../osgiserviceutil/Service3StaticGreedyImpl.java  |  11 +-
 16 files changed, 290 insertions(+), 243 deletions(-)

diff --git 
a/core/src/main/java/org/apache/sling/testing/mock/osgi/MockBundleContext.java 
b/core/src/main/java/org/apache/sling/testing/mock/osgi/MockBundleContext.java
index 9c5c2e9..b247b6f 100644
--- 
a/core/src/main/java/org/apache/sling/testing/mock/osgi/MockBundleContext.java
+++ 
b/core/src/main/java/org/apache/sling/testing/mock/osgi/MockBundleContext.java
@@ -142,7 +142,7 @@ class MockBundleContext implements BundleContext {
 
         MockServiceRegistration<?> registration = new 
MockServiceRegistration<>(this.bundle, clazzes, service, properties, this);
         this.registeredServices.add(registration);
-        handleRefsUpdateOnRegister(registration, this);
+        handleRefsUpdateOnRegister(registration);
         notifyServiceListeners(ServiceEvent.REGISTERED, 
registration.getReference());
         return registration;
     }
@@ -160,7 +160,7 @@ class MockBundleContext implements BundleContext {
      * @param bundleContext Bundle context
      */
     @SuppressWarnings("unchecked")
-    private void handleRefsUpdateOnRegister(MockServiceRegistration<?> 
registration, BundleContext bundleContext) {
+    private void handleRefsUpdateOnRegister(MockServiceRegistration<?> 
registration) {
 
         // handle DYNAMIC references to this registration
         List<ReferenceInfo<?>> affectedDynamicReferences = 
OsgiServiceUtil.getMatchingDynamicReferences(registeredServices, registration);
@@ -179,8 +179,7 @@ class MockBundleContext implements BundleContext {
                 case MANDATORY_MULTIPLE:
                 case OPTIONAL_MULTIPLE:
                 case OPTIONAL_UNARY:
-                    OsgiServiceUtil.invokeBindMethod(reference, 
referenceInfo.getServiceRegistration().getService(),
-                            new ServiceInfo(registration), bundleContext);
+                    OsgiServiceUtil.invokeBindMethod(reference, 
referenceInfo.getServiceRegistration().getService(), new 
ServiceInfo(registration));
                     break;
                 default:
                     throw new RuntimeException("Unepxected cardinality: " + 
reference.getCardinality());
@@ -220,7 +219,7 @@ class MockBundleContext implements BundleContext {
 
         boolean wasRemoved = this.registeredServices.remove(registration);
         if (wasRemoved) {
-            handleRefsUpdateOnUnregister(registration, this);
+            handleRefsUpdateOnUnregister(registration);
             notifyServiceListeners(ServiceEvent.UNREGISTERING, 
registration.getReference());
         } else {
             throw new IllegalStateException("Service was already 
unregistered");
@@ -251,7 +250,7 @@ class MockBundleContext implements BundleContext {
      * @param bundleContext Bundle context
      */
     @SuppressWarnings("unchecked")
-    private void handleRefsUpdateOnUnregister(MockServiceRegistration<?> 
registration, BundleContext bundleContext) {
+    private void handleRefsUpdateOnUnregister(MockServiceRegistration<?> 
registration) {
 
         // handle DYNAMIC references to this registration
         List<ReferenceInfo<?>> affectedDynamicReferences = 
OsgiServiceUtil.getMatchingDynamicReferences(registeredServices, registration);
@@ -264,8 +263,7 @@ class MockBundleContext implements BundleContext {
                 case OPTIONAL_MULTIPLE:
                 case OPTIONAL_UNARY:
                     // it is currently not checked if for a MANDATORY_UNARY or 
MANDATORY_MULTIPLE reference the last reference is removed
-                    OsgiServiceUtil.invokeUnbindMethod(reference, 
referenceInfo.getServiceRegistration().getService(),
-                            new ServiceInfo(registration), bundleContext);
+                    OsgiServiceUtil.invokeUnbindMethod(reference, 
referenceInfo.getServiceRegistration().getService(), new 
ServiceInfo(registration));
                     break;
                 default:
                     throw new RuntimeException("Unepxected cardinality: " + 
reference.getCardinality());
diff --git 
a/core/src/main/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtil.java 
b/core/src/main/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtil.java
index 6adc7b3..80460e8 100644
--- a/core/src/main/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtil.java
+++ b/core/src/main/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtil.java
@@ -50,7 +50,6 @@ import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceObjects;
 import org.osgi.framework.ServiceReference;
 import org.osgi.service.component.ComponentContext;
 import org.osgi.service.component.ComponentServiceObjects;
@@ -577,7 +576,7 @@ final class OsgiServiceUtil {
             switch (reference.getFieldCollectionType()) {
                 case SERVICE:
                     matchingServices.stream()
-                        .map(ServiceInfo::getServiceInstance)
+                        .map(ServiceInfo::getService)
                         .forEach(collection::add);
                     break;
                 case REFERENCE:
@@ -585,6 +584,9 @@ final class OsgiServiceUtil {
                         .map(ServiceInfo::getServiceReference)
                         .forEach(collection::add);
                     break;
+                case SERVICEOBJECTS:
+                    collection.addAll(matchingServices);
+                    break;
                 default:
                     throw new RuntimeException("Field collection type '" + 
reference.getFieldCollectionType() + "' not supported "
                             + "for reference '" + reference.getName()  + "' (" 
+ type.getName() +  ") into constructor parameter " + parameterIndex + " for 
class " +  targetClass.getName());
@@ -598,13 +600,18 @@ final class OsgiServiceUtil {
 
             // 1. assignable from service instance
             if 
(parameterType.isAssignableFrom(reference.getInterfaceTypeAsClass())) {
-                return firstServiceInfo.map(ServiceInfo::getServiceInstance);
+                return firstServiceInfo.map(ServiceInfo::getService);
             }
 
             // 2. ServiceReference
             if (parameterType == ServiceReference.class) {
                 return firstServiceInfo.map(ServiceInfo::getServiceReference);
             }
+
+            // 3. ServiceReference
+            if (parameterType == ComponentServiceObjects.class) {
+                return firstServiceInfo;
+            }
         }
 
         // no match
@@ -627,7 +634,7 @@ final class OsgiServiceUtil {
             }
             if (reference.isCardinalityMultiple()) {
                 // make sure at least empty array is set
-                invokeBindUnbindMethod(reference, target, null, bundleContext, 
true);
+                invokeBindUnbindMethod(reference, target, null, true);
             }
         }
 
@@ -646,11 +653,11 @@ final class OsgiServiceUtil {
 
         // try to invoke bind method
         for (ServiceInfo<?> matchingService : matchingServices) {
-            invokeBindUnbindMethod(reference, target, matchingService, 
bundleContext, true);
+            invokeBindUnbindMethod(reference, target, matchingService, true);
         }
     }
 
-    private static void invokeBindUnbindMethod(Reference reference, Object 
target, ServiceInfo<?> serviceInfo, BundleContext bundleContext, boolean bind) {
+    private static void invokeBindUnbindMethod(Reference reference, Object 
target, ServiceInfo<?> serviceInfo, boolean bind) {
         Class<?> targetClass = target.getClass();
 
         // try to invoke bind method
@@ -669,7 +676,7 @@ final class OsgiServiceUtil {
             // 2. ComponentServiceObjects
             method = getMethod(targetClass, methodName, new Class<?>[] { 
ComponentServiceObjects.class });
             if (method != null) {
-                invokeMethod(target, method, new Object[] { 
toComponentServiceObjects(bundleContext.getServiceObjects(serviceInfo.getServiceReference()))
 });
+                invokeMethod(target, method, new Object[] { serviceInfo });
                 return;
             }
 
@@ -677,7 +684,7 @@ final class OsgiServiceUtil {
             Class<?> interfaceType = reference.getInterfaceTypeAsClass();
             method = getMethodWithAssignableTypes(targetClass, methodName, new 
Class<?>[] { interfaceType });
             if (method != null) {
-                invokeMethod(target, method, new Object[] { 
serviceInfo.getServiceInstance() });
+                invokeMethod(target, method, new Object[] { 
serviceInfo.getService() });
                 return;
             }
 
@@ -698,10 +705,10 @@ final class OsgiServiceUtil {
                         args[i] = serviceInfo.getServiceReference();
                     }
                     else if (method.getParameterTypes()[i] == 
ComponentServiceObjects.class) {
-                        args[i] = 
toComponentServiceObjects(bundleContext.getServiceObjects(serviceInfo.getServiceReference()));
+                        args[i] = serviceInfo;
                     }
                     else if 
(method.getParameterTypes()[i].isAssignableFrom(interfaceType)) {
-                        args[i] = serviceInfo.getServiceInstance();
+                        args[i] = serviceInfo.getService();
                     }
                     else if (method.getParameterTypes()[i] == Map.class) {
                         args[i] = serviceInfo.getServiceConfig();
@@ -723,12 +730,16 @@ final class OsgiServiceUtil {
                 switch (reference.getFieldCollectionType()) {
                     case SERVICE:
                     case REFERENCE:
+                    case SERVICEOBJECTS:
                         Object item = null;
                         if (serviceInfo != null) {
-                            item = serviceInfo.getServiceInstance();
+                            item = serviceInfo.getService();
                             if (reference.getFieldCollectionType() == 
FieldCollectionType.REFERENCE) {
                                 item = serviceInfo.getServiceReference();
                             }
+                            else if (reference.getFieldCollectionType() == 
FieldCollectionType.SERVICEOBJECTS) {
+                                item = serviceInfo;
+                            }
                         }
                         Field field = getCollectionField(targetClass, 
fieldName);
                         if (field != null) {
@@ -753,7 +764,7 @@ final class OsgiServiceUtil {
                 Class<?> interfaceType = reference.getInterfaceTypeAsClass();
                 Field field = getFieldWithAssignableType(targetClass, 
fieldName, interfaceType);
                 if (field != null) {
-                    setField(target, field, bind && serviceInfo != null ? 
serviceInfo.getServiceInstance() : null);
+                    setField(target, field, bind && serviceInfo != null ? 
serviceInfo.getService() : null);
                     return;
                 }
 
@@ -763,28 +774,18 @@ final class OsgiServiceUtil {
                     setField(target, field, bind && serviceInfo != null ? 
serviceInfo.getServiceReference() : null);
                     return;
                 }
+
+                // 3. ComponentServiceObjects
+                field = getField(targetClass, fieldName, 
ComponentServiceObjects.class);
+                if (field != null) {
+                    setField(target, field, bind && serviceInfo != null ? 
serviceInfo : null);
+                    return;
+                }
             }
         }
 
     }
 
-    private static <T> ComponentServiceObjects<T> 
toComponentServiceObjects(ServiceObjects<T> serviceObjects) {
-        return new ComponentServiceObjects<T>() {
-            @Override
-            public T getService() {
-                return serviceObjects.getService();
-            }
-            @Override
-            public void ungetService(T service) {
-                serviceObjects.ungetService(service);
-            }
-            @Override
-            public ServiceReference<T> getServiceReference() {
-                return serviceObjects.getServiceReference();
-            }
-        };
-    }
-
     @SuppressWarnings("unchecked")
     private static void addToCollection(Object target, Field field, Object 
item) {
         try {
@@ -845,8 +846,8 @@ final class OsgiServiceUtil {
      * @param serviceInfo Service on which to invoke the method
      * @param bundleContext Bundle context
      */
-    public static void invokeBindMethod(Reference reference, Object target, 
ServiceInfo serviceInfo, BundleContext bundleContext) {
-        invokeBindUnbindMethod(reference,  target, serviceInfo, bundleContext, 
true);
+    public static void invokeBindMethod(Reference reference, Object target, 
ServiceInfo<?> serviceInfo) {
+        invokeBindUnbindMethod(reference,  target, serviceInfo, true);
     }
 
     /**
@@ -856,8 +857,8 @@ final class OsgiServiceUtil {
      * @param serviceInfo Service on which to invoke the method
      * @param bundleContext Bundle context
      */
-    public static void invokeUnbindMethod(Reference reference, Object target, 
ServiceInfo serviceInfo, BundleContext bundleContext) {
-        invokeBindUnbindMethod(reference,  target, serviceInfo, bundleContext, 
false);
+    public static void invokeUnbindMethod(Reference reference, Object target, 
ServiceInfo<?> serviceInfo) {
+        invokeBindUnbindMethod(reference,  target, serviceInfo, false);
     }
 
     @SuppressWarnings("unchecked")
@@ -942,7 +943,7 @@ final class OsgiServiceUtil {
         return references;
     }
 
-    static class ServiceInfo<T> {
+    static class ServiceInfo<T> implements ComponentServiceObjects<T> {
 
         private final T serviceInstance;
         private final Map<String, Object> serviceConfig;
@@ -960,7 +961,7 @@ final class OsgiServiceUtil {
             this.serviceReference = registration.getReference();
         }
 
-        public T getServiceInstance() {
+        public T getService() {
             return this.serviceInstance;
         }
 
@@ -972,6 +973,26 @@ final class OsgiServiceUtil {
             return serviceReference;
         }
 
+        @Override
+        public void ungetService(T service) {
+            // nothing to do
+        }
+
+        @Override
+        @SuppressWarnings("null")
+        public int hashCode() {
+            return serviceInstance.hashCode();
+        }
+
+        @Override
+        @SuppressWarnings("null")
+        public boolean equals(Object obj) {
+            if (obj instanceof ServiceInfo) {
+                return 
serviceInstance.equals(((ServiceInfo)obj).serviceInstance);
+            }
+            return false;
+        }
+
     }
 
     static class ReferenceInfo<T> {
diff --git 
a/core/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextDynamicReferencesOsgiR6ComponentServiceObjectsTest.java
 
b/core/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextDynamicReferencesOsgiR6ComponentServiceObjectsTest.java
new file mode 100644
index 0000000..0b04165
--- /dev/null
+++ 
b/core/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextDynamicReferencesOsgiR6ComponentServiceObjectsTest.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.testing.mock.osgi;
+
+import 
org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.Service3OsgiR6;
+import 
org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.Service3OsgiR6ComponentServiceObjectsImpl;
+import org.junit.runner.RunWith;
+import org.mockito.junit.MockitoJUnitRunner;
+
+@RunWith(MockitoJUnitRunner.class)
+public class 
MockBundleContextDynamicReferencesOsgiR6ComponentServiceObjectsTest extends 
MockBundleContextDynamicReferencesOsgiR6Test {
+
+    @Override
+    protected Service3OsgiR6 newService3OsgiR6() {
+        return new Service3OsgiR6ComponentServiceObjectsImpl();
+    }
+
+}
diff --git 
a/core/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextDynamicReferencesOsgiR6Test.java
 
b/core/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextDynamicReferencesOsgiR6Test.java
index 4bebcf4..db6d6d1 100644
--- 
a/core/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextDynamicReferencesOsgiR6Test.java
+++ 
b/core/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextDynamicReferencesOsgiR6Test.java
@@ -23,6 +23,7 @@ import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertSame;
 
 import 
org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.Service3OsgiR6;
+import 
org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.Service3OsgiR6Impl;
 import 
org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.ServiceInterface1;
 import 
org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.ServiceInterface1Optional;
 import 
org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.ServiceInterface2;
@@ -74,7 +75,7 @@ public class MockBundleContextDynamicReferencesOsgiR6Test {
         reg1a = 
bundleContext.registerService(ServiceInterface1.class.getName(), dependency1a, 
null);
         reg2a = 
bundleContext.registerService(ServiceInterface2.class.getName(), dependency2a, 
null);
 
-        service = new Service3OsgiR6();
+        service = newService3OsgiR6();
         MockOsgi.injectServices(service, bundleContext);
         MockOsgi.activate(service, bundleContext);
         bundleContext.registerService(Service3OsgiR6.class.getName(), service, 
MapUtil.toDictionary(ImmutableMap.<String,Object>of("reference3DynamicFiltered.target","(prop1=def)")));
@@ -85,6 +86,10 @@ public class MockBundleContextDynamicReferencesOsgiR6Test {
         assertDependencies3();
     }
 
+    protected Service3OsgiR6 newService3OsgiR6() {
+        return new Service3OsgiR6Impl();
+    }
+
     @Test
     public void testAddRemoveOptionalUnaryService() {
         ServiceRegistration reg1aOptional = 
bundleContext.registerService(ServiceInterface1Optional.class.getName(), 
dependency1aOptional, null);
diff --git 
a/core/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextStaticGreedyConstructorInjectionComponentServiceObjectsReferencesTest.java
 
b/core/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextStaticGreedyConstructorInjectionComponentServiceObjectsReferencesTest.java
new file mode 100644
index 0000000..45abff3
--- /dev/null
+++ 
b/core/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextStaticGreedyConstructorInjectionComponentServiceObjectsReferencesTest.java
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.testing.mock.osgi;
+
+import 
org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.Service3StaticGreedy;
+import 
org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.Service3StaticGreedyConstructorInjectionComponentServiceObjectsImpl;
+import org.junit.runner.RunWith;
+import org.mockito.junit.MockitoJUnitRunner;
+
+@RunWith(MockitoJUnitRunner.class)
+public class 
MockBundleContextStaticGreedyConstructorInjectionComponentServiceObjectsReferencesTest
  extends MockBundleContextStaticGreedyConstructorInjectionReferencesTest {
+
+    @Override
+    protected Class<? extends Service3StaticGreedy> 
getService3StaticGreedyClass() {
+        return 
Service3StaticGreedyConstructorInjectionComponentServiceObjectsImpl.class;
+    }
+
+}
diff --git 
a/core/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextStaticGreedyConstructorInjectionReferencesTest.java
 
b/core/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextStaticGreedyConstructorInjectionReferencesTest.java
index 1673f93..ce0bebf 100644
--- 
a/core/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextStaticGreedyConstructorInjectionReferencesTest.java
+++ 
b/core/src/test/java/org/apache/sling/testing/mock/osgi/MockBundleContextStaticGreedyConstructorInjectionReferencesTest.java
@@ -72,7 +72,7 @@ public class 
MockBundleContextStaticGreedyConstructorInjectionReferencesTest {
         reg1a = 
bundleContext.registerService(ServiceInterface1.class.getName(), dependency1a, 
null);
         reg2a = 
bundleContext.registerService(ServiceInterface2.class.getName(), dependency2a, 
null);
 
-        Service3StaticGreedy service = 
MockOsgi.activateInjectServices(Service3StaticGreedyConstructorInjectionImpl.class,
 bundleContext);
+        Service3StaticGreedy service = 
MockOsgi.activateInjectServices(getService3StaticGreedyClass(), bundleContext);
         bundleContext.registerService(Service3StaticGreedy.class.getName(), 
service, null);
 
         assertDependency1(dependency1a);
@@ -81,6 +81,10 @@ public class 
MockBundleContextStaticGreedyConstructorInjectionReferencesTest {
         assertDependencies3();
     }
 
+    protected Class<? extends Service3StaticGreedy> 
getService3StaticGreedyClass() {
+        return Service3StaticGreedyConstructorInjectionImpl.class;
+    }
+
     @Test
     public void testAddRemoveOptionalUnaryService() {
         ServiceRegistration reg1aOptional = 
bundleContext.registerService(ServiceInterface1Optional.class.getName(), 
dependency1aOptional, null);
diff --git 
a/core/src/test/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtilTest.java
 
b/core/src/test/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtilTest.java
index 3e428ce..53eb85f 100644
--- 
a/core/src/test/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtilTest.java
+++ 
b/core/src/test/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtilTest.java
@@ -36,6 +36,8 @@ import 
org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.Service1;
 import org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.Service2;
 import org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.Service3;
 import 
org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.Service3OsgiR6;
+import 
org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.Service3OsgiR6ComponentServiceObjectsImpl;
+import 
org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.Service3OsgiR6Impl;
 import org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.Service4;
 import org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.Service5;
 import 
org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil.ServiceFactory1;
@@ -110,7 +112,15 @@ public class OsgiServiceUtilTest {
 
     @Test
     public void testService3OsgiR6() {
-        Service3OsgiR6 service3 = new Service3OsgiR6();
+        testService3OsgiR6(new Service3OsgiR6Impl());
+    }
+
+    @Test
+    public void testService3OsgiR6ComponentServiceObjects() {
+        testService3OsgiR6(new Service3OsgiR6ComponentServiceObjectsImpl());
+    }
+
+    private void testService3OsgiR6(Service3OsgiR6 service3) {
         assertTrue(MockOsgi.injectServices(service3, bundleContext));
 
         Dictionary<String, Object> service3Config = new Hashtable<String, 
Object>();
diff --git a/test-services/pom.xml b/test-services/pom.xml
index 5fa4708..a627f48 100644
--- a/test-services/pom.xml
+++ b/test-services/pom.xml
@@ -35,7 +35,12 @@
       This module is only used in the unit tests of osgi-mock.core.
       The sample OSGi components and services are not part of the osgi-mock 
test source to allow bnd plugin to auto-generate the metadata for them.
     </description>
-    
+
+    <properties>
+        <!-- Skip sonarqube analysis for this test services project - it's 
only used for unit tests -->
+        <sonar.skip>true</sonar.skip>
+    </properties>
+
     <dependencies>
         <dependency>
             <groupId>org.osgi</groupId>
diff --git 
a/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/DictionaryTo.java
 
b/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/DictionaryTo.java
new file mode 100644
index 0000000..8b5f111
--- /dev/null
+++ 
b/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/DictionaryTo.java
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+package org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil;
+
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+
+final class DictionaryTo {
+
+    private DictionaryTo() {
+        // static methods only
+    }
+
+    public static Map<String,Object> map(Dictionary<String,Object> dictionary) 
{
+        Map<String,Object> result = new HashMap<>();
+        Enumeration<String> keys = dictionary.keys();
+        while (keys.hasMoreElements()) {
+            String key = keys.nextElement();
+            result.put(key, dictionary.get(key));
+        }
+        return result;
+    }
+
+}
diff --git 
a/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3.java
 
b/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3.java
index 6f0bd12..fb48824 100644
--- 
a/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3.java
+++ 
b/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3.java
@@ -19,8 +19,6 @@
 package org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil;
 
 import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
@@ -69,14 +67,7 @@ public class Service3 implements ServiceInterface2 {
     @Activate
     private void activate(ComponentContext ctx) {
         this.componentContext = ctx;
-
-        // copy properties dictionary to config map
-        this.config = new HashMap<>();
-        Enumeration<String> keys = ctx.getProperties().keys();
-        while (keys.hasMoreElements()) {
-            String key = keys.nextElement();
-            this.config.put(key, ctx.getProperties().get(key));
-        }
+        this.config = DictionaryTo.map(ctx.getProperties());
     }
 
     @Deactivate
diff --git 
a/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3OsgiR6.java
 
b/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3OsgiR6.java
index 17ad401..b8745b8 100644
--- 
a/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3OsgiR6.java
+++ 
b/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3OsgiR6.java
@@ -18,129 +18,33 @@
  */
 package org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil;
 
-import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Enumeration;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-import org.osgi.framework.ServiceReference;
 import org.osgi.service.component.ComponentContext;
-import org.osgi.service.component.annotations.Activate;
-import org.osgi.service.component.annotations.Component;
-import org.osgi.service.component.annotations.Deactivate;
-import org.osgi.service.component.annotations.FieldOption;
-import org.osgi.service.component.annotations.Modified;
-import org.osgi.service.component.annotations.Reference;
-import org.osgi.service.component.annotations.ReferenceCardinality;
-import org.osgi.service.component.annotations.ReferencePolicy;
-import org.osgi.service.component.annotations.ReferencePolicyOption;
 
-@Component
-public class Service3OsgiR6 {
+public interface Service3OsgiR6 {
 
-    @Reference
-    private ServiceInterface1 reference1;
+    ServiceInterface1 getReference1();
 
-    @Reference(cardinality = ReferenceCardinality.OPTIONAL, policy = 
ReferencePolicy.DYNAMIC)
-    private volatile ServiceInterface1Optional reference1Optional;
+    ServiceInterface1Optional getReference1Optional();
 
-    @Reference(cardinality = ReferenceCardinality.AT_LEAST_ONE,
-            policy = ReferencePolicy.DYNAMIC, policyOption = 
ReferencePolicyOption.GREEDY)
-    private volatile List<ServiceReference<ServiceInterface2>> references2 = 
new ArrayList<>();
+    List<ServiceInterface2> getReferences2();
 
-    @Reference(service = ServiceInterface3.class, cardinality = 
ReferenceCardinality.MULTIPLE,
-            policy = ReferencePolicy.DYNAMIC, policyOption = 
ReferencePolicyOption.GREEDY)
-    private volatile List<ServiceSuperInterface3> references3;
+    List<ServiceSuperInterface3> getReferences3();
 
-    @Reference(service = ServiceInterface3.class, cardinality = 
ReferenceCardinality.MULTIPLE, target="(prop1=abc)",
-            policy = ReferencePolicy.DYNAMIC, policyOption = 
ReferencePolicyOption.GREEDY)
-    private volatile List<ServiceSuperInterface3> references3Filtered;
+    List<ServiceSuperInterface3> getReferences3Filtered();
 
-    @Reference(cardinality = ReferenceCardinality.OPTIONAL,
-            policy = ReferencePolicy.DYNAMIC, policyOption = 
ReferencePolicyOption.GREEDY,
-            name = "reference3DynamicFiltered")
-    private volatile ServiceSuperInterface3 reference3DynamicFiltered;
+    ServiceSuperInterface3 getReference3DynamicFiltered();
 
-    @Reference(service = ServiceInterface3.class, cardinality = 
ReferenceCardinality.MULTIPLE,
-            policy = ReferencePolicy.DYNAMIC, policyOption = 
ReferencePolicyOption.GREEDY,
-            fieldOption = FieldOption.UPDATE)
-    private volatile Set<ServiceSuperInterface3> references3Set;
+    Set<ServiceSuperInterface3> getReferences3Set();
 
-    @Reference(service = ServiceInterface3.class, cardinality = 
ReferenceCardinality.MULTIPLE,
-            policy = ReferencePolicy.DYNAMIC, policyOption = 
ReferencePolicyOption.GREEDY)
-    private volatile Collection<ServiceSuperInterface3> references3Collection;
+    Collection<ServiceSuperInterface3> getReferences3Collection();
 
-    private ComponentContext componentContext;
-    private Map<String, Object> config;
+    ComponentContext getComponentContext();
 
-    @Activate
-    private void activate(ComponentContext ctx) {
-        this.componentContext = ctx;
-
-        // copy properties dictionary to config map
-        this.config = new HashMap<>();
-        Enumeration<String> keys = ctx.getProperties().keys();
-        while (keys.hasMoreElements()) {
-            String key = keys.nextElement();
-            this.config.put(key, ctx.getProperties().get(key));
-        }
-    }
-
-    @Deactivate
-    private void deactivate(ComponentContext ctx) {
-        this.componentContext = null;
-    }
-
-    @Modified
-    private void modified(Map<String,Object> newConfig) {
-        this.config = newConfig;
-    }
-
-    public ServiceInterface1 getReference1() {
-        return this.reference1;
-    }
-
-    public ServiceInterface1Optional getReference1Optional() {
-        return this.reference1Optional;
-    }
-
-    public List<ServiceInterface2> getReferences2() {
-        List<ServiceInterface2> services = new ArrayList<ServiceInterface2>();
-        for (ServiceReference<?> serviceReference : references2) {
-            
services.add((ServiceInterface2)componentContext.getBundleContext().getService(serviceReference));
-        }
-        return services;
-    }
-
-    public List<ServiceSuperInterface3> getReferences3() {
-        return this.references3;
-    }
-
-    public List<ServiceSuperInterface3> getReferences3Filtered() {
-        return this.references3Filtered;
-    }
-
-    public ServiceSuperInterface3 getReference3DynamicFiltered() {
-        return this.reference3DynamicFiltered;
-    }
-
-    public Set<ServiceSuperInterface3> getReferences3Set() {
-        return this.references3Set;
-    }
-
-    public Collection<ServiceSuperInterface3> getReferences3Collection() {
-        return this.references3Collection;
-    }
-
-    public ComponentContext getComponentContext() {
-        return this.componentContext;
-    }
-
-    public Map<String, Object> getConfig() {
-        return config;
-    }
+    Map<String, Object> getConfig();
 
 }
diff --git 
a/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3OsgiR6.java
 
b/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3OsgiR6ComponentServiceObjectsImpl.java
similarity index 64%
copy from 
test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3OsgiR6.java
copy to 
test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3OsgiR6ComponentServiceObjectsImpl.java
index 17ad401..969227c 100644
--- 
a/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3OsgiR6.java
+++ 
b/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3OsgiR6ComponentServiceObjectsImpl.java
@@ -20,14 +20,14 @@ package 
org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil;
 
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Enumeration;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 import java.util.Set;
+import java.util.stream.Collectors;
 
-import org.osgi.framework.ServiceReference;
 import org.osgi.service.component.ComponentContext;
+import org.osgi.service.component.ComponentServiceObjects;
 import org.osgi.service.component.annotations.Activate;
 import org.osgi.service.component.annotations.Component;
 import org.osgi.service.component.annotations.Deactivate;
@@ -39,39 +39,39 @@ import 
org.osgi.service.component.annotations.ReferencePolicy;
 import org.osgi.service.component.annotations.ReferencePolicyOption;
 
 @Component
-public class Service3OsgiR6 {
+public class Service3OsgiR6ComponentServiceObjectsImpl implements 
Service3OsgiR6 {
 
     @Reference
-    private ServiceInterface1 reference1;
+    private ComponentServiceObjects<ServiceInterface1> reference1;
 
     @Reference(cardinality = ReferenceCardinality.OPTIONAL, policy = 
ReferencePolicy.DYNAMIC)
-    private volatile ServiceInterface1Optional reference1Optional;
+    private volatile ComponentServiceObjects<ServiceInterface1Optional> 
reference1Optional;
 
     @Reference(cardinality = ReferenceCardinality.AT_LEAST_ONE,
             policy = ReferencePolicy.DYNAMIC, policyOption = 
ReferencePolicyOption.GREEDY)
-    private volatile List<ServiceReference<ServiceInterface2>> references2 = 
new ArrayList<>();
+    private volatile List<ComponentServiceObjects<ServiceInterface2>> 
references2 = new ArrayList<>();
 
     @Reference(service = ServiceInterface3.class, cardinality = 
ReferenceCardinality.MULTIPLE,
             policy = ReferencePolicy.DYNAMIC, policyOption = 
ReferencePolicyOption.GREEDY)
-    private volatile List<ServiceSuperInterface3> references3;
+    private volatile List<ComponentServiceObjects<ServiceSuperInterface3>> 
references3;
 
     @Reference(service = ServiceInterface3.class, cardinality = 
ReferenceCardinality.MULTIPLE, target="(prop1=abc)",
             policy = ReferencePolicy.DYNAMIC, policyOption = 
ReferencePolicyOption.GREEDY)
-    private volatile List<ServiceSuperInterface3> references3Filtered;
+    private volatile List<ComponentServiceObjects<ServiceSuperInterface3>> 
references3Filtered;
 
     @Reference(cardinality = ReferenceCardinality.OPTIONAL,
             policy = ReferencePolicy.DYNAMIC, policyOption = 
ReferencePolicyOption.GREEDY,
             name = "reference3DynamicFiltered")
-    private volatile ServiceSuperInterface3 reference3DynamicFiltered;
+    private volatile ComponentServiceObjects<ServiceSuperInterface3> 
reference3DynamicFiltered;
 
     @Reference(service = ServiceInterface3.class, cardinality = 
ReferenceCardinality.MULTIPLE,
             policy = ReferencePolicy.DYNAMIC, policyOption = 
ReferencePolicyOption.GREEDY,
             fieldOption = FieldOption.UPDATE)
-    private volatile Set<ServiceSuperInterface3> references3Set;
+    private volatile Set<ComponentServiceObjects<ServiceSuperInterface3>> 
references3Set;
 
     @Reference(service = ServiceInterface3.class, cardinality = 
ReferenceCardinality.MULTIPLE,
             policy = ReferencePolicy.DYNAMIC, policyOption = 
ReferencePolicyOption.GREEDY)
-    private volatile Collection<ServiceSuperInterface3> references3Collection;
+    private volatile 
Collection<ComponentServiceObjects<ServiceSuperInterface3>> 
references3Collection;
 
     private ComponentContext componentContext;
     private Map<String, Object> config;
@@ -79,14 +79,7 @@ public class Service3OsgiR6 {
     @Activate
     private void activate(ComponentContext ctx) {
         this.componentContext = ctx;
-
-        // copy properties dictionary to config map
-        this.config = new HashMap<>();
-        Enumeration<String> keys = ctx.getProperties().keys();
-        while (keys.hasMoreElements()) {
-            String key = keys.nextElement();
-            this.config.put(key, ctx.getProperties().get(key));
-        }
+        this.config = DictionaryTo.map(ctx.getProperties());
     }
 
     @Deactivate
@@ -100,39 +93,51 @@ public class Service3OsgiR6 {
     }
 
     public ServiceInterface1 getReference1() {
-        return this.reference1;
+        return Optional.ofNullable(this.reference1)
+            .map(ComponentServiceObjects::getService)
+            .orElse(null);
     }
 
     public ServiceInterface1Optional getReference1Optional() {
-        return this.reference1Optional;
+        return Optional.ofNullable(this.reference1Optional)
+                .map(ComponentServiceObjects::getService)
+                .orElse(null);
     }
 
     public List<ServiceInterface2> getReferences2() {
-        List<ServiceInterface2> services = new ArrayList<ServiceInterface2>();
-        for (ServiceReference<?> serviceReference : references2) {
-            
services.add((ServiceInterface2)componentContext.getBundleContext().getService(serviceReference));
-        }
-        return services;
+        return references2.stream()
+                .map(ComponentServiceObjects::getService)
+                .collect(Collectors.toList());
     }
 
     public List<ServiceSuperInterface3> getReferences3() {
-        return this.references3;
+        return this.references3.stream()
+                .map(ComponentServiceObjects::getService)
+                .collect(Collectors.toList());
     }
 
     public List<ServiceSuperInterface3> getReferences3Filtered() {
-        return this.references3Filtered;
+        return this.references3Filtered.stream()
+                .map(ComponentServiceObjects::getService)
+                .collect(Collectors.toList());
     }
 
     public ServiceSuperInterface3 getReference3DynamicFiltered() {
-        return this.reference3DynamicFiltered;
+        return Optional.ofNullable(this.reference3DynamicFiltered)
+                .map(ComponentServiceObjects::getService)
+                .orElse(null);
     }
 
     public Set<ServiceSuperInterface3> getReferences3Set() {
-        return this.references3Set;
+        return this.references3Set.stream()
+                .map(ComponentServiceObjects::getService)
+                .collect(Collectors.toSet());
     }
 
     public Collection<ServiceSuperInterface3> getReferences3Collection() {
-        return this.references3Collection;
+        return this.references3Collection.stream()
+                .map(ComponentServiceObjects::getService)
+                .collect(Collectors.toList());
     }
 
     public ComponentContext getComponentContext() {
diff --git 
a/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3OsgiR6.java
 
b/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3OsgiR6Impl.java
similarity index 91%
copy from 
test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3OsgiR6.java
copy to 
test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3OsgiR6Impl.java
index 17ad401..64be79d 100644
--- 
a/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3OsgiR6.java
+++ 
b/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3OsgiR6Impl.java
@@ -20,8 +20,6 @@ package 
org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil;
 
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Enumeration;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -39,7 +37,7 @@ import org.osgi.service.component.annotations.ReferencePolicy;
 import org.osgi.service.component.annotations.ReferencePolicyOption;
 
 @Component
-public class Service3OsgiR6 {
+public class Service3OsgiR6Impl implements Service3OsgiR6 {
 
     @Reference
     private ServiceInterface1 reference1;
@@ -79,14 +77,7 @@ public class Service3OsgiR6 {
     @Activate
     private void activate(ComponentContext ctx) {
         this.componentContext = ctx;
-
-        // copy properties dictionary to config map
-        this.config = new HashMap<>();
-        Enumeration<String> keys = ctx.getProperties().keys();
-        while (keys.hasMoreElements()) {
-            String key = keys.nextElement();
-            this.config.put(key, ctx.getProperties().get(key));
-        }
+        this.config = DictionaryTo.map(ctx.getProperties());
     }
 
     @Deactivate
@@ -108,7 +99,7 @@ public class Service3OsgiR6 {
     }
 
     public List<ServiceInterface2> getReferences2() {
-        List<ServiceInterface2> services = new ArrayList<ServiceInterface2>();
+        List<ServiceInterface2> services = new ArrayList<>();
         for (ServiceReference<?> serviceReference : references2) {
             
services.add((ServiceInterface2)componentContext.getBundleContext().getService(serviceReference));
         }
diff --git 
a/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3StaticGreedyConstructorInjectionImpl.java
 
b/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3StaticGreedyConstructorInjectionComponentServiceObjectsImpl.java
similarity index 62%
copy from 
test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3StaticGreedyConstructorInjectionImpl.java
copy to 
test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3StaticGreedyConstructorInjectionComponentServiceObjectsImpl.java
index 8131912..53d5a23 100644
--- 
a/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3StaticGreedyConstructorInjectionImpl.java
+++ 
b/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3StaticGreedyConstructorInjectionComponentServiceObjectsImpl.java
@@ -18,12 +18,14 @@
  */
 package org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil;
 
-import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
+import java.util.stream.Collectors;
 
 import org.osgi.framework.ServiceReference;
 import org.osgi.service.component.ComponentContext;
+import org.osgi.service.component.ComponentServiceObjects;
 import org.osgi.service.component.annotations.Activate;
 import org.osgi.service.component.annotations.Component;
 import org.osgi.service.component.annotations.Reference;
@@ -32,22 +34,23 @@ import 
org.osgi.service.component.annotations.ReferencePolicy;
 import org.osgi.service.component.annotations.ReferencePolicyOption;
 
 @Component(service= Service3StaticGreedy.class)
-public class Service3StaticGreedyConstructorInjectionImpl implements 
Service3StaticGreedy {
+public class 
Service3StaticGreedyConstructorInjectionComponentServiceObjectsImpl implements 
Service3StaticGreedy {
 
-    private final ServiceInterface1 reference1;
-    private final ServiceInterface1Optional reference1Optional;
-    private final List<ServiceReference<ServiceInterface2>> references2;
-    private final List<ServiceSuperInterface3> references3;
+    private final ComponentServiceObjects<ServiceInterface1> reference1;
+    private final ComponentServiceObjects<ServiceInterface1Optional> 
reference1Optional;
+    private final List<ComponentServiceObjects<ServiceInterface2>> references2;
+    private final List<ComponentServiceObjects<ServiceSuperInterface3>> 
references3;
 
     private final ComponentContext componentContext;
     private final Map<String, Object> config;
 
     // this constructor should be ignored as it contains additional parameters 
not valid for injection
-    public Service3StaticGreedyConstructorInjectionImpl(
-            ServiceInterface1 reference1,
-            ServiceInterface1Optional reference1Optional,
-            List<ServiceReference<ServiceInterface2>> references2,
-            List<ServiceSuperInterface3> references3,
+    @SuppressWarnings("java:S1172") // unused parameter by intention
+    public Service3StaticGreedyConstructorInjectionComponentServiceObjectsImpl(
+            ComponentServiceObjects<ServiceInterface1> reference1,
+            ComponentServiceObjects<ServiceInterface1Optional> 
reference1Optional,
+            List<ComponentServiceObjects<ServiceInterface2>> references2,
+            List<ComponentServiceObjects<ServiceSuperInterface3>> references3,
             ComponentContext ctx,
             Map<String, Object> config,
             Object illegalParameter) {
@@ -63,22 +66,22 @@ public class Service3StaticGreedyConstructorInjectionImpl 
implements Service3Sta
     }
 
     @Activate
-    public Service3StaticGreedyConstructorInjectionImpl(
+    public Service3StaticGreedyConstructorInjectionComponentServiceObjectsImpl(
 
             @Reference(policy = ReferencePolicy.STATIC, policyOption = 
ReferencePolicyOption.GREEDY)
-            ServiceInterface1 reference1,
+            ComponentServiceObjects<ServiceInterface1> reference1,
 
             @Reference(cardinality = ReferenceCardinality.OPTIONAL,
                     policy = ReferencePolicy.STATIC, policyOption = 
ReferencePolicyOption.GREEDY)
-            ServiceInterface1Optional reference1Optional,
+            ComponentServiceObjects<ServiceInterface1Optional> 
reference1Optional,
 
             @Reference(cardinality = ReferenceCardinality.AT_LEAST_ONE,
                     policy = ReferencePolicy.STATIC, policyOption = 
ReferencePolicyOption.GREEDY)
-            List<ServiceReference<ServiceInterface2>> references2,
+            List<ComponentServiceObjects<ServiceInterface2>> references2,
 
             @Reference(name = "reference3", service = ServiceInterface3.class, 
cardinality = ReferenceCardinality.MULTIPLE,
                     policy = ReferencePolicy.STATIC, policyOption = 
ReferencePolicyOption.GREEDY)
-            List<ServiceSuperInterface3> references3,
+            List<ComponentServiceObjects<ServiceSuperInterface3>> references3,
 
             ComponentContext ctx,
             Map<String, Object> config) {
@@ -95,31 +98,39 @@ public class Service3StaticGreedyConstructorInjectionImpl 
implements Service3Sta
 
     @Override
     public ServiceInterface1 getReference1() {
-        return this.reference1;
+        return Optional.ofNullable(this.reference1)
+                .map(ComponentServiceObjects::getService)
+                .orElse(null);
     }
 
     @Override
     public ServiceInterface1Optional getReference1Optional() {
-        return this.reference1Optional;
+        return Optional.ofNullable(this.reference1Optional)
+                .map(ComponentServiceObjects::getService)
+                .orElse(null);
     }
 
     @Override
     public List<ServiceInterface2> getReferences2() {
-        List<ServiceInterface2> services = new ArrayList<>();
-        for (ServiceReference<?> serviceReference : references2) {
-            
services.add((ServiceInterface2)componentContext.getBundleContext().getService(serviceReference));
-        }
-        return services;
+        return references2.stream()
+                .map(ComponentServiceObjects::getService)
+                .collect(Collectors.toList());
     }
 
     @Override
     public List<ServiceSuperInterface3> getReferences3() {
-        return this.references3;
+        return this.references3.stream()
+                .map(ComponentServiceObjects::getService)
+                .collect(Collectors.toList());
     }
 
     @Override
     public List<Map<String, Object>> getReference3Configs() {
-        return null;
+        return this.references3.stream()
+                .map(ComponentServiceObjects::getServiceReference)
+                .map(ServiceReference::getProperties)
+                .map(DictionaryTo::map)
+                .collect(Collectors.toList());
     }
 
     @Override
diff --git 
a/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3StaticGreedyConstructorInjectionImpl.java
 
b/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3StaticGreedyConstructorInjectionImpl.java
index 8131912..6789c23 100644
--- 
a/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3StaticGreedyConstructorInjectionImpl.java
+++ 
b/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3StaticGreedyConstructorInjectionImpl.java
@@ -43,6 +43,7 @@ public class Service3StaticGreedyConstructorInjectionImpl 
implements Service3Sta
     private final Map<String, Object> config;
 
     // this constructor should be ignored as it contains additional parameters 
not valid for injection
+    @SuppressWarnings("java:S1172") // unused parameter by intention
     public Service3StaticGreedyConstructorInjectionImpl(
             ServiceInterface1 reference1,
             ServiceInterface1Optional reference1Optional,
diff --git 
a/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3StaticGreedyImpl.java
 
b/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3StaticGreedyImpl.java
index 6beb5d8..aadd261 100644
--- 
a/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3StaticGreedyImpl.java
+++ 
b/test-services/src/main/java/org/apache/sling/testing/mock/osgi/testsvc/osgiserviceutil/Service3StaticGreedyImpl.java
@@ -19,8 +19,6 @@
 package org.apache.sling.testing.mock.osgi.testsvc.osgiserviceutil;
 
 import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -67,14 +65,7 @@ public class Service3StaticGreedyImpl implements 
Service3StaticGreedy {
     @Activate
     private void activate(ComponentContext ctx) {
         this.componentContext = ctx;
-
-        // copy properties dictionary to config map
-        this.config = new HashMap<>();
-        Enumeration<String> keys = ctx.getProperties().keys();
-        while (keys.hasMoreElements()) {
-            String key = keys.nextElement();
-            this.config.put(key, ctx.getProperties().get(key));
-        }
+        this.config = DictionaryTo.map(ctx.getProperties());
     }
 
     @Deactivate

Reply via email to