Improve concurrency by narrowing the RankedBindings subscription lock down to the publisher.
Also fix corner case where a publisher that has a maximum binding rank of Integer.MIN_VALUE
might never be called, despite that being a valid rank.
diff --git a/org.eclipse.sisu.inject/src/org/eclipse/sisu/inject/RankedBindings.java b/org.eclipse.sisu.inject/src/org/eclipse/sisu/inject/RankedBindings.java
index ecd06fc..23aee30 100644
--- a/org.eclipse.sisu.inject/src/org/eclipse/sisu/inject/RankedBindings.java
+++ b/org.eclipse.sisu.inject/src/org/eclipse/sisu/inject/RankedBindings.java
@@ -35,8 +35,6 @@
 
     final Collection<BeanCache<?, T>> cachedBeans = Weak.elements();
 
-    volatile int topRank = Integer.MAX_VALUE;
-
     // ----------------------------------------------------------------------
     // Constructors
     // ----------------------------------------------------------------------
@@ -105,10 +103,6 @@
          * No need to lock; ranked sequence is thread-safe.
          */
         pendingPublishers.insert( publisher, rank );
-        if ( rank > topRank )
-        {
-            topRank = rank;
-        }
     }
 
     void remove( final BindingPublisher publisher )
@@ -116,7 +110,7 @@
         /*
          * Lock just to prevent subscription race condition.
          */
-        synchronized ( pendingPublishers )
+        synchronized ( publisher )
         {
             if ( !pendingPublishers.removeThis( publisher ) )
             {
@@ -147,17 +141,21 @@
 
         public boolean hasNext()
         {
-            int rank = topRank;
-            if ( rank > Integer.MIN_VALUE && rank > itr.peekNextRank() )
+            // apply any publishers that could add bindings before the current position
+            BindingPublisher publisher = pendingPublishers.peek();
+            while ( null != publisher && !itr.hasNext( publisher.maxBindingRank() ) )
             {
-                synchronized ( pendingPublishers )
+                synchronized ( publisher )
                 {
-                    while ( ( rank = pendingPublishers.topRank() ) > Integer.MIN_VALUE && rank > itr.peekNextRank() )
+                    // check in case subscribed by another thread
+                    if ( publisher == pendingPublishers.peek() )
                     {
-                        pendingPublishers.poll().subscribe( RankedBindings.this );
+                        // only update list _after_ subscription
+                        publisher.subscribe( RankedBindings.this );
+                        pendingPublishers.removeThis( publisher );
                     }
-                    topRank = rank;
                 }
+                publisher = pendingPublishers.peek();
             }
             return itr.hasNext();
         }
diff --git a/org.eclipse.sisu.inject/src/org/eclipse/sisu/inject/RankedSequence.java b/org.eclipse.sisu.inject/src/org/eclipse/sisu/inject/RankedSequence.java
index 1e346c4..451e65d 100644
--- a/org.eclipse.sisu.inject/src/org/eclipse/sisu/inject/RankedSequence.java
+++ b/org.eclipse.sisu.inject/src/org/eclipse/sisu/inject/RankedSequence.java
@@ -70,17 +70,10 @@
     }
 
     @SuppressWarnings( "unchecked" )
-    public T poll()
+    public T peek()
     {
         final Content content = get();
-        set( content.remove( 0 ) );
-        return (T) content.objs[0];
-    }
-
-    public int topRank()
-    {
-        final Content content = get();
-        return null != content ? uid2rank( content.uids[0] ) : Integer.MIN_VALUE;
+        return null != content ? (T) content.objs[0] : null;
     }
 
     public boolean contains( final Object element )
@@ -391,13 +384,13 @@
         }
 
         /**
-         * @return Rank assigned to the next element; returns {@link Integer#MIN_VALUE} if there is no next element.
+         * @return {@code true} if the next element is ranked at or above the given rank; otherwise {@code false}
          */
-        public int peekNextRank()
+        public boolean hasNext( final int rank )
         {
             if ( null != nextObj )
             {
-                return uid2rank( nextUID );
+                return uid2rank( nextUID ) >= rank;
             }
             final Content newContent = get();
             if ( content != newContent )
@@ -407,9 +400,9 @@
             }
             if ( index >= 0 && index < content.uids.length )
             {
-                return uid2rank( content.uids[index] );
+                return uid2rank( content.uids[index] ) >= rank;
             }
-            return Integer.MIN_VALUE;
+            return false;
         }
 
         public T next()