Add support for dynamic reference properties
diff --git a/src/main/java/org/apache/sling/testing/mock/osgi/MockOsgi.java b/src/main/java/org/apache/sling/testing/mock/osgi/MockOsgi.java
index 7c07578..4d22717 100644
--- a/src/main/java/org/apache/sling/testing/mock/osgi/MockOsgi.java
+++ b/src/main/java/org/apache/sling/testing/mock/osgi/MockOsgi.java
@@ -145,7 +145,20 @@
      * @return true if all dependencies could be injected, false if the service has no dependencies.
      */
     public static boolean injectServices(Object target, BundleContext bundleContext) {
-        return OsgiServiceUtil.injectServices(target, bundleContext);
+        return MockOsgi.injectServices(target, bundleContext, (Map<String, Object>)null);
+    }
+
+    /**
+     * Simulate OSGi service dependency injection. Injects direct references and
+     * multiple references. If a some references could not be injected no error
+     * is thrown.
+     * @param target Service instance
+     * @param bundleContext Bundle context from which services are fetched to inject.
+     * @param properties Service properties (used to resolve dynamic reference properties)
+     * @return true if all dependencies could be injected, false if the service has no dependencies.
+     */
+    public static boolean injectServices(Object target, BundleContext bundleContext, Map<String, Object> properties) {
+        return OsgiServiceUtil.injectServices(target, bundleContext, properties);
     }
 
     /**
diff --git a/src/main/java/org/apache/sling/testing/mock/osgi/OsgiMetadataUtil.java b/src/main/java/org/apache/sling/testing/mock/osgi/OsgiMetadataUtil.java
index 1fca7a5..1e0b8d3 100644
--- a/src/main/java/org/apache/sling/testing/mock/osgi/OsgiMetadataUtil.java
+++ b/src/main/java/org/apache/sling/testing/mock/osgi/OsgiMetadataUtil.java
@@ -470,20 +470,20 @@
 
     static class Reference {
 
-        private final Class<?> clazz;
-        private final String name;
-        private final String interfaceType;
-        private final ReferenceCardinality cardinality;
-        private final ReferencePolicy policy;
-        private final ReferencePolicyOption policyOption;
-        private final String bind;
-        private final String unbind;
-        private final String field;
-        private final FieldCollectionType fieldCollectionType;
-        private final String target;
-        private final Filter targetFilter;
+        protected final Class<?> clazz;
+        protected final String name;
+        protected final String interfaceType;
+        protected final ReferenceCardinality cardinality;
+        protected final ReferencePolicy policy;
+        protected final ReferencePolicyOption policyOption;
+        protected final String bind;
+        protected final String unbind;
+        protected final String field;
+        protected final FieldCollectionType fieldCollectionType;
+        protected String target;
+        protected Filter targetFilter;
 
-        private Reference(Class<?> clazz, Node node) {
+        protected Reference(Class<?> clazz, Node node) {
             this.clazz = clazz;
             this.name = getAttributeValue(node, "name");
             this.interfaceType = getAttributeValue(node, "interface");
@@ -507,6 +507,21 @@
             }
         }
 
+        protected Reference(Reference reference) {
+            this.clazz = reference.clazz;
+            this.name = reference.name;
+            this.interfaceType = reference.interfaceType;
+            this.cardinality = reference.cardinality;
+            this.policy = reference.policy;
+            this.policyOption = reference.policyOption;
+            this.bind = reference.bind;
+            this.unbind = reference.unbind;
+            this.field = reference.field;
+            this.fieldCollectionType = reference.fieldCollectionType;
+            this.target = reference.target;
+            this.targetFilter = reference.targetFilter;
+        }
+
         public Class<?> getServiceClass() {
             return clazz;
         }
@@ -614,6 +629,22 @@
 
     }
 
+    static class DynamicReference extends Reference {
+        public DynamicReference(Reference reference, String target) {
+            super(reference);
+            this.target = target;
+            if (StringUtils.isNotEmpty(this.target)) {
+                try {
+                    this.targetFilter = new FilterImpl(this.target);
+                } catch (InvalidSyntaxException ex) {
+                    throw new RuntimeException("Invalid target filter in reference '" + this.name + "' of class " + clazz.getName(), ex);
+                }
+            }
+            else {
+                this.targetFilter = null;
+            }
+        }
+    }
 
     /**
      * Options for {@link Reference#cardinality()} property.
diff --git a/src/main/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtil.java b/src/main/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtil.java
index b3fd20c..488b4fe 100644
--- a/src/main/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtil.java
+++ b/src/main/java/org/apache/sling/testing/mock/osgi/OsgiServiceUtil.java
@@ -31,6 +31,7 @@
 
 import org.apache.commons.lang3.StringUtils;
 import org.apache.felix.scr.impl.inject.Annotations;
+import org.apache.sling.testing.mock.osgi.OsgiMetadataUtil.DynamicReference;
 import org.apache.sling.testing.mock.osgi.OsgiMetadataUtil.FieldCollectionType;
 import org.apache.sling.testing.mock.osgi.OsgiMetadataUtil.OsgiMetadata;
 import org.apache.sling.testing.mock.osgi.OsgiMetadataUtil.Reference;
@@ -369,9 +370,10 @@
      * multiple references.
      * @param target Service instance
      * @param bundleContext Bundle context from which services are fetched to inject.
+     * @param properties Services properties (used to resolve dynamic reference properties)
      * @return true if all dependencies could be injected, false if the service has no dependencies.
      */
-    public static boolean injectServices(Object target, BundleContext bundleContext) {
+    public static boolean injectServices(Object target, BundleContext bundleContext, Map<String, Object> properties) {
 
         // collect all declared reference annotations on class and field level
         Class<?> targetClass = target.getClass();
@@ -387,6 +389,13 @@
 
         // try to inject services
         for (Reference reference : references) {
+            if (properties != null) {
+                // Look for a target override
+                Object o = properties.get(reference.getName() + ".target");
+                if (o != null && o instanceof String) {
+                    reference = new DynamicReference(reference,(String)o);
+                }
+            }
             injectServiceReference(reference, target, bundleContext);
         }
         return true;
diff --git a/src/main/java/org/apache/sling/testing/mock/osgi/context/OsgiContextImpl.java b/src/main/java/org/apache/sling/testing/mock/osgi/context/OsgiContextImpl.java
index acb96e7..ae9d0b2 100644
--- a/src/main/java/org/apache/sling/testing/mock/osgi/context/OsgiContextImpl.java
+++ b/src/main/java/org/apache/sling/testing/mock/osgi/context/OsgiContextImpl.java
@@ -150,7 +150,7 @@
      * @return Registered service instance
      */
     public final <T> T registerInjectActivateService(final T service, final Map<String, Object> properties) {
-        MockOsgi.injectServices(service, bundleContext());
+        MockOsgi.injectServices(service, bundleContext(), properties);
         MockOsgi.activate(service, bundleContext(), properties);
         registerService(null, service, properties);
         return service;
diff --git a/src/main/java/org/apache/sling/testing/mock/osgi/package-info.java b/src/main/java/org/apache/sling/testing/mock/osgi/package-info.java
index d1f57fc..db6c8d4 100644
--- a/src/main/java/org/apache/sling/testing/mock/osgi/package-info.java
+++ b/src/main/java/org/apache/sling/testing/mock/osgi/package-info.java
@@ -19,5 +19,5 @@
 /**
  * Mock implementation of selected OSGi APIs.
  */
-@org.osgi.annotation.versioning.Version("3.3")
+@org.osgi.annotation.versioning.Version("3.4")
 package org.apache.sling.testing.mock.osgi;