Sort parameter converters
diff --git a/tomee/apache-tomee/src/patch/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java b/tomee/apache-tomee/src/patch/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java
index 27f575a..65c417c 100644
--- a/tomee/apache-tomee/src/patch/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java
+++ b/tomee/apache-tomee/src/patch/java/org/apache/cxf/jaxrs/provider/ProviderFactory.java
@@ -39,6 +39,7 @@
 import java.util.TreeMap;
 import java.util.logging.Logger;
 
+import javax.annotation.Priority;
 import javax.ws.rs.Produces;
 import javax.ws.rs.core.Application;
 import javax.ws.rs.core.Configuration;
@@ -77,6 +78,8 @@
 import org.apache.cxf.message.Message;
 import org.apache.cxf.message.MessageUtils;
 
+import static javax.ws.rs.Priorities.USER;
+
 public abstract class ProviderFactory {
     public static final String DEFAULT_FILTER_NAME_BINDING = "org.apache.cxf.filter.binding";
     public static final String PROVIDER_SELECTION_PROPERTY_CHANGED = "provider.selection.property.changed";
@@ -662,6 +665,7 @@
         sortReaders();
         sortWriters();
         sortContextResolvers();
+        sortParamConverters();
 
         mapInterceptorFilters(readerInterceptors, readInts, ReaderInterceptor.class, true);
         mapInterceptorFilters(writerInterceptors, writeInts, WriterInterceptor.class, true);
@@ -783,7 +787,9 @@
         contextResolvers.sort(new ContextResolverComparator());
     }
 
-
+    private void sortParamConverters() {
+        paramConverters.sort(new ParamConverterComparator());
+    }
 
 
 
@@ -1517,4 +1523,56 @@
         writerInterceptors = sortedWriterInterceptors;
     }
 
+    protected static class ParamConverterComparator implements Comparator<ProviderInfo<ParamConverterProvider>> {
+
+        @Override
+        public int compare(final ProviderInfo<ParamConverterProvider> a,
+                           final ProviderInfo<ParamConverterProvider> b) {
+
+            /*
+             * Primary sort.  Also takes care of sorting custom
+             * converters from system converters due to priority
+             * defaults
+             */
+            int result = sortByPriority(a, b);
+
+            /*
+             * Secondary sort as this list *will* change order
+             * once in a while between jvm restarts, which can
+             * have frustrating consequences for users who are
+             * expecting no change in behavior as they aren't
+             * changing their code.
+             */
+            if (result == 0) {
+                result = sortByClassName(a, b);
+            }
+
+            return result;
+        }
+
+        public int sortByPriority(final ProviderInfo<ParamConverterProvider> a,
+                           final ProviderInfo<ParamConverterProvider> b) {
+            final int aPriority = getPriority(a);
+            final int bPriority = getPriority(b);
+
+            // Sort ascending as the priority with the lowest number wins
+            return Integer.compare(aPriority, bPriority);
+        }
+
+        public int sortByClassName(final ProviderInfo<ParamConverterProvider> a,
+                           final ProviderInfo<ParamConverterProvider> b) {
+
+            // Sort ascending as the priority with the lowest number wins
+            return a.getProvider().getClass().getName().compareTo(b.getProvider().getClass().getName());
+        }
+
+        private int getPriority(final ProviderInfo<ParamConverterProvider> providerInfo) {
+            final Priority priority = providerInfo.getProvider().getClass().getAnnotation(Priority.class);
+            if (priority!=null) {
+                return priority.value();
+            }
+            return providerInfo.isCustom() ? USER : USER + 1000;
+        }
+    }
+
 }