SLING-7194 AdapterManager sorts AdapterFactory implementations lowest ranking first
diff --git a/src/main/java/org/apache/sling/adapter/internal/AdapterFactoryDescriptorMap.java b/src/main/java/org/apache/sling/adapter/internal/AdapterFactoryDescriptorMap.java
index 4de3d08..c36f7dc 100644
--- a/src/main/java/org/apache/sling/adapter/internal/AdapterFactoryDescriptorMap.java
+++ b/src/main/java/org/apache/sling/adapter/internal/AdapterFactoryDescriptorMap.java
@@ -18,6 +18,7 @@
  */
 package org.apache.sling.adapter.internal;
 
+import java.util.Comparator;
 import java.util.TreeMap;
 
 import org.apache.sling.api.adapter.AdapterFactory;
@@ -41,4 +42,16 @@
 
     private static final long serialVersionUID = 2L;
 
+    public AdapterFactoryDescriptorMap() {
+        super(new Comparator<ServiceReference<AdapterFactory>>() {
+            @Override
+            public int compare(ServiceReference<AdapterFactory> o1, ServiceReference<AdapterFactory> o2) {
+                // compareTo of ServiceReference implements service-ranking lowest-first/service id highest-first
+                // but we want service-ranking highest-first/service id lowest-first as it is done e.g. for BundleContext.getService
+                // so explicitly reverse the comparison (SLING-7194)
+                return o2.compareTo(o1);
+            }
+        });
+    }
+
 }
diff --git a/src/test/java/org/apache/sling/adapter/internal/AdapterManagerTest.java b/src/test/java/org/apache/sling/adapter/internal/AdapterManagerTest.java
index 1208c85..635ab83 100644
--- a/src/test/java/org/apache/sling/adapter/internal/AdapterManagerTest.java
+++ b/src/test/java/org/apache/sling/adapter/internal/AdapterManagerTest.java
@@ -395,34 +395,6 @@
     }
 
     @org.junit.Test public void testAdaptMultipleAdapterFactoriesServiceRanking() throws Exception {
-        final ServiceReference firstAdaptable = new ServiceReferenceImpl(1, new String[]{AdapterObject.class.getName()},  new String[]{ ParentInterface.class.getName(), FirstImplementation.class.getName()});
-        final ServiceReference secondAdaptable = new ServiceReferenceImpl(2, new String[]{ AdapterObject.class.getName() }, new String[]{ParentInterface.class.getName(), SecondImplementation.class.getName()});
-
-        am.activate(this.createMultipleAdaptersComponentContext(firstAdaptable, secondAdaptable));
-
-        AdapterObject first = new AdapterObject(Want.INDIFFERENT);
-        assertNull("Expect no adapter", am.getAdapter(first, ParentInterface.class));
-
-        AdapterObject second = new AdapterObject(Want.INDIFFERENT);
-        assertNull("Expect no adapter", am.getAdapter(second, ParentInterface.class));
-
-        am.bindAdapterFactory(firstAdaptable);
-        am.bindAdapterFactory(secondAdaptable);
-
-        Object adapter = am.getAdapter(first, ParentInterface.class);
-        assertNotNull("Did not get an adapter back for first implementation (from ParentInterface), service ranking 1", adapter);
-        assertTrue("Did not get the correct adaptable back for first implementation, service ranking 1, ", adapter instanceof FirstImplementation);
-
-        adapter = am.getAdapter(first, FirstImplementation.class);
-        assertNotNull("Did not get an adapter back for first implementation, service ranking 1", adapter);
-        assertTrue("Did not get the correct adaptable back for first implementation, service ranking 1, ", adapter instanceof FirstImplementation);
-
-        adapter = am.getAdapter(second, SecondImplementation.class);
-        assertNotNull("Did not get an adapter back for second implementation, service ranking 2", adapter);
-        assertTrue("Did not get the correct adaptable back for second implementation, service ranking 2, ", adapter instanceof SecondImplementation);
-    }
-
-    @org.junit.Test public void testAdaptMultipleAdapterFactoriesServiceRankingSecondHigherOrder() throws Exception {
         final ServiceReference firstAdaptable = new ServiceReferenceImpl(2, new String[]{AdapterObject.class.getName()},  new String[]{ ParentInterface.class.getName(), FirstImplementation.class.getName()});
         final ServiceReference secondAdaptable = new ServiceReferenceImpl(1, new String[]{ AdapterObject.class.getName() }, new String[]{ParentInterface.class.getName(), SecondImplementation.class.getName()});
 
@@ -438,21 +410,49 @@
         am.bindAdapterFactory(secondAdaptable);
 
         Object adapter = am.getAdapter(first, ParentInterface.class);
-        assertNotNull("Did not get an adapter back for second implementation (from ParentInterface), service ranking 1", adapter);
-        assertTrue("Did not get the correct adaptable back for second implementation, service ranking 1, ", adapter instanceof SecondImplementation);
+        assertNotNull("Did not get an adapter back for first implementation (from ParentInterface), service ranking 2", adapter);
+        assertTrue("Did not get the correct adaptable back for first implementation, service ranking 2, ", adapter instanceof FirstImplementation);
 
         adapter = am.getAdapter(first, FirstImplementation.class);
-        assertNotNull("Did not get an adapter back for first implementation, service ranking 1", adapter);
-        assertTrue("Did not get the correct adaptable back for first implementation, service ranking 1, ", adapter instanceof FirstImplementation);
+        assertNotNull("Did not get an adapter back for first implementation, service ranking 2", adapter);
+        assertTrue("Did not get the correct adaptable back for first implementation, service ranking 2, ", adapter instanceof FirstImplementation);
 
         adapter = am.getAdapter(second, SecondImplementation.class);
-        assertNotNull("Did not get an adapter back for second implementation, service ranking 2", adapter);
+        assertNotNull("Did not get an adapter back for second implementation, service ranking 1", adapter);
+        assertTrue("Did not get the correct adaptable back for second implementation, service ranking 1, ", adapter instanceof SecondImplementation);
+    }
+
+    @org.junit.Test public void testAdaptMultipleAdapterFactoriesServiceRankingSecondHigherOrder() throws Exception {
+        final ServiceReference firstAdaptable = new ServiceReferenceImpl(1, new String[]{AdapterObject.class.getName()},  new String[]{ ParentInterface.class.getName(), FirstImplementation.class.getName()});
+        final ServiceReference secondAdaptable = new ServiceReferenceImpl(2, new String[]{ AdapterObject.class.getName() }, new String[]{ParentInterface.class.getName(), SecondImplementation.class.getName()});
+
+        am.activate(this.createMultipleAdaptersComponentContext(firstAdaptable, secondAdaptable));
+
+        AdapterObject first = new AdapterObject(Want.INDIFFERENT);
+        assertNull("Expect no adapter", am.getAdapter(first, ParentInterface.class));
+
+        AdapterObject second = new AdapterObject(Want.INDIFFERENT);
+        assertNull("Expect no adapter", am.getAdapter(second, ParentInterface.class));
+
+        am.bindAdapterFactory(firstAdaptable);
+        am.bindAdapterFactory(secondAdaptable);
+
+        Object adapter = am.getAdapter(first, ParentInterface.class);
+        assertNotNull("Did not get an adapter back for second implementation (from ParentInterface), service ranking 2", adapter);
         assertTrue("Did not get the correct adaptable back for second implementation, service ranking 2, ", adapter instanceof SecondImplementation);
+
+        adapter = am.getAdapter(first, FirstImplementation.class);
+        assertNotNull("Did not get an adapter back for first implementation, service ranking 2", adapter);
+        assertTrue("Did not get the correct adaptable back for first implementation, service ranking 2, ", adapter instanceof FirstImplementation);
+
+        adapter = am.getAdapter(second, SecondImplementation.class);
+        assertNotNull("Did not get an adapter back for second implementation, service ranking 1", adapter);
+        assertTrue("Did not get the correct adaptable back for second implementation, service ranking 1, ", adapter instanceof SecondImplementation);
     }
 
     @org.junit.Test public void testAdaptMultipleAdapterFactoriesServiceRankingReverse() throws Exception {
-        final ServiceReference firstAdaptable = new ServiceReferenceImpl(1, new String[]{AdapterObject.class.getName()},  new String[]{ ParentInterface.class.getName(), FirstImplementation.class.getName()});
-        final ServiceReference secondAdaptable = new ServiceReferenceImpl(2, new String[]{ AdapterObject.class.getName() }, new String[]{ParentInterface.class.getName(), SecondImplementation.class.getName()});
+        final ServiceReference firstAdaptable = new ServiceReferenceImpl(2, new String[]{AdapterObject.class.getName()},  new String[]{ ParentInterface.class.getName(), FirstImplementation.class.getName()});
+        final ServiceReference secondAdaptable = new ServiceReferenceImpl(1, new String[]{ AdapterObject.class.getName() }, new String[]{ParentInterface.class.getName(), SecondImplementation.class.getName()});
 
         am.activate(this.createMultipleAdaptersComponentContext(firstAdaptable, secondAdaptable));
 
@@ -467,16 +467,16 @@
         am.bindAdapterFactory(firstAdaptable);
 
         Object adapter = am.getAdapter(first, ParentInterface.class);
-        assertNotNull("Did not get an adapter back for first implementation (from ParentInterface), service ranking 1", adapter);
-        assertTrue("Did not get the correct adaptable back for first implementation, service ranking 1, ", adapter instanceof FirstImplementation);
+        assertNotNull("Did not get an adapter back for first implementation (from ParentInterface), service ranking 2", adapter);
+        assertTrue("Did not get the correct adaptable back for first implementation, service ranking 2, ", adapter instanceof FirstImplementation);
 
         adapter = am.getAdapter(first, FirstImplementation.class);
-        assertNotNull("Did not get an adapter back for first implementation, service ranking 1", adapter);
-        assertTrue("Did not get the correct adaptable back for first implementation, service ranking 1, ", adapter instanceof FirstImplementation);
+        assertNotNull("Did not get an adapter back for first implementation, service ranking 2", adapter);
+        assertTrue("Did not get the correct adaptable back for first implementation, service ranking 2, ", adapter instanceof FirstImplementation);
 
         adapter = am.getAdapter(second, SecondImplementation.class);
-        assertNotNull("Did not get an adapter back for second implementation, service ranking 2", adapter);
-        assertTrue("Did not get the correct adaptable back for second implementation, service ranking 2, ", adapter instanceof SecondImplementation);
+        assertNotNull("Did not get an adapter back for second implementation, service ranking 1", adapter);
+        assertTrue("Did not get the correct adaptable back for second implementation, service ranking 1, ", adapter instanceof SecondImplementation);
     }