SLING-10950 sling-mock: Make compatible with Sling API 2.24.0, Resource Resolver 1.8.0, Adapter 2.2.0, Settings 1.4.2
diff --git a/core/src/main/java/org/apache/sling/testing/mock/sling/MockAdapterManagerImpl.java b/core/src/main/java/org/apache/sling/testing/mock/sling/MockAdapterManagerImpl.java
index 3b6c6d5..9e6b9ae 100644
--- a/core/src/main/java/org/apache/sling/testing/mock/sling/MockAdapterManagerImpl.java
+++ b/core/src/main/java/org/apache/sling/testing/mock/sling/MockAdapterManagerImpl.java
@@ -29,12 +29,11 @@
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
+import java.util.TreeMap;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 
 import org.apache.sling.adapter.Adaption;
-import org.apache.sling.adapter.internal.AdapterFactoryDescriptor;
-import org.apache.sling.adapter.internal.AdapterFactoryDescriptorMap;
 import org.apache.sling.adapter.internal.AdaptionImpl;
 import org.apache.sling.api.SlingConstants;
 import org.apache.sling.api.adapter.AdapterFactory;
@@ -493,4 +492,81 @@
             }
         }
     }
+
+    /**
+     * The <code>AdapterFactoryDescriptorMap</code> is a sorted map of
+     * {@link AdapterFactoryDescriptor} instances indexed (and ordered) by their
+     * {@link ServiceReference}. This map is used to organize the
+     * registered {@link org.apache.sling.api.adapter.AdapterFactory} services for
+     * a given adaptable type.
+     * <p>
+     * Each entry in the map is a {@link AdapterFactoryDescriptor} thus enabling the
+     * registration of multiple factories for the same (adaptable, adapter) type
+     * tuple. Of course only the first entry (this is the reason for having a sorted
+     * map) for such a given tuple is actually being used. If that first instance is
+     * removed the eventual second instance may actually be used instead.
+     *
+     * <p>
+     *   Copy of import org.apache.sling.adapter.internal.AdapterFactoryDescriptorMap,
+     *   signature has changed in adapter impl 2.2.0.
+     * </p>
+     */
+    static class AdapterFactoryDescriptorMap extends
+            TreeMap<ServiceReference<AdapterFactory>, AdapterFactoryDescriptor> {
+
+        private static final long serialVersionUID = 2L;
+
+    }
+
+    /**
+     * The <code>AdapterFactoryDescriptor</code> is an entry in the
+     * {@link AdapterFactoryDescriptorMap} conveying the list of adapter (target)
+     * types and the respective {@link AdapterFactory}.
+     * <p>
+     *   Copy of import org.apache.sling.adapter.internal.AdapterFactoryDescriptor,
+     *   signature has changed in adapter impl 2.2.0.
+     * </p>
+     */
+    static class AdapterFactoryDescriptor {
+
+        private volatile AdapterFactory factory;
+
+        private final String[] adapters;
+
+        private final ServiceReference<AdapterFactory> reference;
+
+        private final ComponentContext context;
+
+        private volatile ServiceRegistration<Adaption> adaption;
+
+        public AdapterFactoryDescriptor(
+                final ComponentContext context,
+                final ServiceReference<AdapterFactory> reference,
+                final String[] adapters) {
+            this.reference = reference;
+            this.context = context;
+            this.adapters = adapters;
+        }
+
+        public AdapterFactory getFactory() {
+            if ( factory == null ) {
+                factory = context.locateService(
+                        "AdapterFactory", reference);
+            }
+            return factory;
+        }
+
+        public String[] getAdapters() {
+            return adapters;
+        }
+
+        public ServiceRegistration<Adaption> getAdaption() {
+            return adaption;
+        }
+
+        public void setAdaption(ServiceRegistration<Adaption> adaption) {
+            this.adaption = adaption;
+        }
+    }
+
 }
diff --git a/core/src/main/java/org/apache/sling/testing/mock/sling/RRMockResourceResolverFactoryWrapper.java b/core/src/main/java/org/apache/sling/testing/mock/sling/RRMockResourceResolverFactoryWrapper.java
index f72ff91..1aa591a 100644
--- a/core/src/main/java/org/apache/sling/testing/mock/sling/RRMockResourceResolverFactoryWrapper.java
+++ b/core/src/main/java/org/apache/sling/testing/mock/sling/RRMockResourceResolverFactoryWrapper.java
@@ -18,6 +18,10 @@
  */
 package org.apache.sling.testing.mock.sling;
 
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
@@ -110,4 +114,19 @@
         return null;
     }
 
+    @SuppressWarnings("unchecked")
+    public @NotNull List<String> getSearchPath() {
+        // call delegate method via reflection, as it is not available in earlier versions of Sling API
+        try {
+            Method getSearchPathMethod = ResourceResolverFactory.class.getMethod("getSearchPath");
+            return (List)getSearchPathMethod.invoke(delegate);
+        }
+        catch (NoSuchMethodException | SecurityException ex) {
+            // earlier version of Sling API - return empty list
+            return Collections.emptyList();
+        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
+            throw new RuntimeException("Unable to call getSearchPath on delegate.", ex);
+        }
+    }
+
 }
diff --git a/core/src/main/java/org/apache/sling/testing/mock/sling/RRMockResourceResolverWrapper.java b/core/src/main/java/org/apache/sling/testing/mock/sling/RRMockResourceResolverWrapper.java
index 895fa09..f6a98ea 100644
--- a/core/src/main/java/org/apache/sling/testing/mock/sling/RRMockResourceResolverWrapper.java
+++ b/core/src/main/java/org/apache/sling/testing/mock/sling/RRMockResourceResolverWrapper.java
@@ -32,7 +32,6 @@
 import org.apache.sling.api.resource.ResourceResolver;
 import org.apache.sling.api.resource.ResourceUtil;
 import org.apache.sling.api.wrappers.ResourceResolverWrapper;
-import org.apache.sling.resourceresolver.impl.ResourceTypeUtil;
 import org.apache.sling.spi.resource.provider.ResolveContext;
 import org.apache.sling.spi.resource.provider.ResourceContext;
 import org.apache.sling.spi.resource.provider.ResourceProvider;
@@ -208,4 +207,54 @@
         return resourceSuperType;
     }
 
+
+
+    /**
+     * Some helper methods for doing comparisons on resource types.
+     * This class is private the resource resolver bundle.
+     * Consumers should rely on {@link Resource#isResourceType(String)} or {@link ResourceResolver#isResourceType(Resource, String)} instead.
+     *
+     * <p>
+     *   This is a copy of org.apache.sling.resourceresolver.impl.ResourceTypeUtil which is an internal class
+     *   and its signature has changed between releases.
+     * </p>
+     */
+    static class ResourceTypeUtil {
+
+        /**
+         * Returns <code>true</code> if the given resource type are equal.
+         *
+         * In case the value of any of the given resource types
+         * starts with one of the resource resolver's search paths
+         * it is converted to a relative resource type by stripping off
+         * the resource resolver's search path before doing the comparison.
+         *
+         * @param resourceType A resource type
+         * @param anotherResourceType Another resource type to compare with {@link resourceType}.
+         * @return <code>true</code> if the resource type equals the given resource type.
+         */
+        public static boolean areResourceTypesEqual(@NotNull String resourceType, @NotNull String anotherResourceType, String @NotNull [] searchPath) {
+            return relativizeResourceType(resourceType, searchPath).equals(relativizeResourceType(anotherResourceType, searchPath));
+        }
+
+        /**
+         * Makes the given resource type relative by stripping off any prefix which equals one of the given search paths.
+         * In case the given resource type does not start with any of the given search paths it is returned unmodified.
+         * @param resourceType the resourceType to relativize.
+         * @param searchPath the search paths to strip off from the given resource type.
+         * @return the relative resource type
+         */
+        public static String relativizeResourceType(@NotNull String resourceType, String @NotNull [] searchPath) {
+            if (resourceType.startsWith("/")) {
+                for (String prefix : searchPath) {
+                    if (resourceType.startsWith(prefix)) {
+                        return resourceType.substring(prefix.length());
+                    }
+                }
+            }
+            return resourceType;
+        }
+
+    }
+
 }
diff --git a/core/src/main/java/org/apache/sling/testing/mock/sling/services/MockSlingSettingService.java b/core/src/main/java/org/apache/sling/testing/mock/sling/services/MockSlingSettingService.java
index bfa3544..749f386 100644
--- a/core/src/main/java/org/apache/sling/testing/mock/sling/services/MockSlingSettingService.java
+++ b/core/src/main/java/org/apache/sling/testing/mock/sling/services/MockSlingSettingService.java
@@ -90,4 +90,9 @@
         throw new UnsupportedOperationException();
     }
 
+    // part of Sling Setting Service 1.4.2
+    public int getBestRunModeMatchCountFromSpec(String spec) {
+        throw new UnsupportedOperationException();
+    }
+
 }
diff --git a/core/src/main/java/org/apache/sling/testing/mock/sling/services/package-info.java b/core/src/main/java/org/apache/sling/testing/mock/sling/services/package-info.java
index 802b526..12bd156 100644
--- a/core/src/main/java/org/apache/sling/testing/mock/sling/services/package-info.java
+++ b/core/src/main/java/org/apache/sling/testing/mock/sling/services/package-info.java
@@ -19,5 +19,5 @@
 /**
  * Mocks for selected Sling services.
  */
-@org.osgi.annotation.versioning.Version("2.0.3")
+@org.osgi.annotation.versioning.Version("2.1")
 package org.apache.sling.testing.mock.sling.services;
diff --git a/core/src/test/java/org/apache/sling/testing/mock/sling/rrmock/resource/SlingCrudResourceResolverTest.java b/core/src/test/java/org/apache/sling/testing/mock/sling/rrmock/resource/SlingCrudResourceResolverTest.java
index 20ab589..a0d65c6 100644
--- a/core/src/test/java/org/apache/sling/testing/mock/sling/rrmock/resource/SlingCrudResourceResolverTest.java
+++ b/core/src/test/java/org/apache/sling/testing/mock/sling/rrmock/resource/SlingCrudResourceResolverTest.java
@@ -18,8 +18,15 @@
  */
 package org.apache.sling.testing.mock.sling.rrmock.resource;
 
+import static org.junit.Assert.assertNotNull;
+
+import java.lang.reflect.Method;
+import java.util.List;
+
+import org.apache.sling.api.resource.ResourceResolverFactory;
 import org.apache.sling.testing.mock.sling.ResourceResolverType;
 import org.apache.sling.testing.mock.sling.resource.AbstractSlingCrudResourceResolverTest;
+import org.junit.Test;
 
 public class SlingCrudResourceResolverTest extends AbstractSlingCrudResourceResolverTest {
 
@@ -28,4 +35,16 @@
         return ResourceResolverType.RESOURCERESOLVER_MOCK;
     }
 
+    @Test
+    @SuppressWarnings({ "null", "unchecked" })
+    public void testResourceResolverFactory_GetSearchPath() throws Exception {
+        // ensure there is a method getSearchPaths in resource resolver factory, although it is not part of the API we are compiling against (keeping backward compatibility)
+        ResourceResolverFactory factory = context.getService(ResourceResolverFactory.class);
+        Class clazz = factory.getClass();
+        Method getSearchPathMethod = clazz.getMethod("getSearchPath");
+        getSearchPathMethod.setAccessible(true);
+        List<String> searchPaths = (List)getSearchPathMethod.invoke(factory);
+        assertNotNull(searchPaths);
+    }
+
 }
diff --git a/parent/pom.xml b/parent/pom.xml
index f651833..bf2b330 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -37,7 +37,7 @@
     <properties>
         <osgi-mock.version>3.2.1-SNAPSHOT</osgi-mock.version>
         <jcr-mock.version>1.5.4</jcr-mock.version>
-        <resourceresolver-mock.version>1.2.2</resourceresolver-mock.version>
+        <resourceresolver-mock.version>1.2.3-SNAPSHOT</resourceresolver-mock.version>
         <logging-mock.version>2.0.0</logging-mock.version>
         <servlet-helpers.version>1.4.2</servlet-helpers.version>
         <resourcebuilder.version>1.0.4</resourcebuilder.version>
@@ -284,7 +284,7 @@
         <profile>
             <id>latest-dependency-versions</id>
             <activation>
-                <activeByDefault>false</activeByDefault>
+                <activeByDefault>true</activeByDefault>
             </activation>
             <dependencyManagement>
                 <dependencies>