diff --git a/yum/depsolve.py b/yum/depsolve.py
index d1b2272..8a707bd 100644
--- a/yum/depsolve.py
+++ b/yum/depsolve.py
@@ -25,7 +25,7 @@ import logging
 import rpmUtils.transaction
 import rpmUtils.miscutils
 import rpmUtils.arch
-from rpmUtils.arch import archDifference, isMultiLibArch
+from rpmUtils.arch import archDifference, isMultiLibArch, getCanonArch
 import misc
 from misc import unique, version_tuple_to_string
 import rpm
@@ -38,6 +38,7 @@ import Errors
 from i18n import _
 import warnings
 warnings.simplefilter("ignore", Errors.YumFutureDeprecationWarning)
+from operator import itemgetter
 
 try:
     assert max(2, 4) == 4
@@ -502,19 +503,9 @@ class Depsolve(object):
         newest = provSack.returnNewestByNameArch()
         if len(newest) > 1: # there's no way this can be zero
                             
-            best = newest[0]
-            old_best = None
-            loop_run = 0
-            while best != old_best:
-                if loop_run >= len(newest)*2:
-                    msg = _('Failure finding best provider of %s for %s, exceeded maximum loop length' % (needname, requiringPo))
-                    errorlist.append(msg)
-                    self.verbose_logger.debug(msg)
-                    break
-                loop_run += 1
-                old_best = best
-                best = self._compare_providers(newest, best, requiringPo)
-                    
+            pkgresults = self._compare_providers(newest, requiringPo)
+            # take the first one...
+            best = pkgresults[0][0]                   
                 
         elif len(newest) == 1:
             best = newest[0]
@@ -913,14 +904,20 @@ class Depsolve(object):
         return installed
     _isPackageInstalled = isPackageInstalled
 
-    def _compare_providers(self, pkgs, bestpkg, reqpo):
+    def _compare_providers(self, pkgs, reqpo):
+        """take the list of pkgs and score them based on the requesting package
+           return a dictionary of po=score"""
+        self.verbose_logger.log(logginglevels.DEBUG_4,
+              _("Running compare_providers() for %s") %(str(pkgs)))
 
+        
         def _common_prefix_len(x, y, minlen=2):
             num = min(len(x), len(y))
             for off in range(num):
                 if x[off] != y[off]:
                     return max(off, minlen)
             return max(num, minlen)
+
         def _common_sourcerpm(x, y):
             if not hasattr(x, 'sourcerpm'):
                 return False
@@ -928,116 +925,99 @@ class Depsolve(object):
                 return False
             return x.sourcerpm == y.sourcerpm
 
-        for po in pkgs:
-            self.verbose_logger.log(logginglevels.DEBUG_4,
-                _("Comparing best: %s to po: %s") %(bestpkg, po))
+        def _compare_arch_distance(x, y, req_compare_arch):
+            # take X and Y package objects
+            # determine which has a closer archdistance to compare_arch
+            # if they are equal to compare_arch, compare which is closer to the 
+            # running arch
+            # return the package which is closer or None for equal, or equally useless
+            
+            x_dist = archDifference(req_compare_arch, x.arch)
+            if isMultiLibArch(): # only go to the next one if we're multilib - 
+                if x_dist == 0: # can't really use best's arch anyway...
+                    self.verbose_logger.log(logginglevels.DEBUG_4,
+                        _("better arch in po %s") %(y))
+                    return y # just try the next one - can't be much worse
 
-            if po == bestpkg: # if we're comparing the same one, skip it
+            y_dist = archDifference(req_compare_arch, y.arch)
+            if y_dist > 0 and x_dist > y_dist:
                 self.verbose_logger.log(logginglevels.DEBUG_4,
-                    _("Same: best %s == po: %s") %(bestpkg, po))
+                    _("better arch in po %s") %(y))
 
-                continue
-            # if best is obsoleted by any of the packages, then the obsoleter
-            # is the new best    
-            for obs in po.obsoletes:
-                if bestpkg.inPrcoRange('provides', obs):
-                    # make sure the best doesn't obsolete this po - if it does we're done
-                    # we do this b/c it is possible for two entries to oscillate in this
-                    # test - obsolete should trump no matter what
-                    # NOTE: mutually obsoleting providers is completely and utterly doom
-                    # but this should 'break the loop'
-                    for obs in bestpkg.obsoletes:
-                        if po.inPrcoRange('provides', obs):
-                            self.verbose_logger.log(logginglevels.DEBUG_4,
-                                _("best %s obsoletes po: %s") %(bestpkg, po))
-                            return bestpkg
-                    self.verbose_logger.log(logginglevels.DEBUG_4,
-                        _("po %s obsoletes best: %s") %(po, bestpkg))
-                           
-                    return po
+                return y
+            if y_dist == x_dist:
+                return None
+            return x
+            
+        pkgresults = {}
 
-            # just check if best obsoletes po
-            for obs in bestpkg.obsoletes:
-                if po.inPrcoRange('provides', obs):
-                    self.verbose_logger.log(logginglevels.DEBUG_4,
-                        _("best %s obsoletes po: %s") %(bestpkg, po))
-                    return bestpkg
+        for pkg in pkgs:
+            pkgresults[pkg] = 0
+            
+        # go through each pkg and compare to others
+        # if it is same skip it
+        # if the pkg is obsoleted by any other of the packages
+        # then add  -1024 to its score
+        # don't need to look for mutual obsoletes b/c each package
+        # is evaluated against all the others, so mutually obsoleting
+        # packages will have their scores diminished equally
+        
+        # compare the arch vs each other pkg
+        #   give each time it returns with a better arch a +5
 
-                    
-            if reqpo.arch != 'noarch':
-                best_dist = archDifference(reqpo.arch, bestpkg.arch)
-                if isMultiLibArch(): # only go to the next one if we're multilib - i686 can satisfy i386 deps
-                    if best_dist == 0: # can't really use best's arch anyway...
-                        self.verbose_logger.log(logginglevels.DEBUG_4,
-                            _("better arch in po %s") %(po))
-                        return po # just try the next one - can't be much worse
+        # look for common source vs the reqpo - give a +10 if it has it
 
-            
-                po_dist = archDifference(reqpo.arch, po.arch)
-                if po_dist > 0 and best_dist > po_dist:
-                    self.verbose_logger.log(logginglevels.DEBUG_4,
-                        _("better arch in po %s") %(po))
-                    
-                    return po
-                    
-                if best_dist == po_dist:
-                    csp = _common_sourcerpm(reqpo, po)
-                    csb = _common_sourcerpm(reqpo, bestpkg)
-                    if not csb and csp:
-                        self.verbose_logger.log(logginglevels.DEBUG_4,
-                            _("po %s shares a sourcerpm with %s") %(po, reqpo))
-                        return po
-                    if csb and not csp:
-                        self.verbose_logger.log(logginglevels.DEBUG_4,
-                            _("best %s shares a sourcerpm with %s") %(bestpkg, reqpo))
-                        return bestpkg
-                        
-                    cplp = _common_prefix_len(reqpo.name, po.name)
-                    cplb = _common_prefix_len(reqpo.name, bestpkg.name)
-                    if cplp > cplb:
-                        self.verbose_logger.log(logginglevels.DEBUG_4,
-                            _("po %s shares more of the name prefix with %s") %(po, reqpo))                    
-                        return po
-                    if cplp == cplb and len(po.name) < len(bestpkg.name):
+        # look for common_prefix_len - add the length*2 to the score
+        
+        # add the negative of the length of the name to the score
+        
+        for po in pkgs:
+            for nextpo in pkgs:
+                if po == nextpo:
+                    continue
+                obsoleted = False
+                for obs in nextpo.obsoletes:
+                    if po.inPrcoRange('provides', obs):
+                        obsoleted = True
+                                
                         self.verbose_logger.log(logginglevels.DEBUG_4,
-                            _("po %s has a shorter name than best %s") %(po, bestpkg))                    
-                        return po
+                            _("%s obsoletes %s") % (po, nextpo))
 
-            # reqpo.arch == "noarch"
-            elif (not _common_sourcerpm(reqpo, bestpkg) and
-                  _common_sourcerpm(reqpo, po)):
-                self.verbose_logger.log(logginglevels.DEBUG_4,
-                    _("po %s shares a sourcerpm with %s") %(po, reqpo))
-                return po
-            elif (_common_sourcerpm(reqpo, bestpkg) and
-                  not _common_sourcerpm(reqpo, po)):
-                self.verbose_logger.log(logginglevels.DEBUG_4,
-                    _("best %s shares a sourcerpm with %s") %(bestpkg,reqpo))
-                return bestpkg
-            elif (_common_prefix_len(reqpo.name, po.name) >
-                  _common_prefix_len(reqpo.name, bestpkg.name)):
-                self.verbose_logger.log(logginglevels.DEBUG_4,
-                    _("po %s shares more of the name prefix with %s") %(po, reqpo))                    
-                return po
-            elif (_common_prefix_len(reqpo.name, po.name) <
-                  _common_prefix_len(reqpo.name, bestpkg.name)):
+                    if obsoleted:
+                        pkgresults[po] -= 1024
+                        break
+
+                for thisarch in (reqpo.arch, getCanonArch()):
+                    res = _compare_arch_distance(po, nextpo, thisarch)
+                    if not res:
+                        continue
+                    self.verbose_logger.log(logginglevels.DEBUG_4,                   
+                       _('archdist compared %s to %s on %s\n  Winner: %s' % (po, nextpo, thisarch, res)))
+
+                    if res == po:
+                        pkgresults[po] += 5
+
+            if _common_sourcerpm(po, reqpo):
                 self.verbose_logger.log(logginglevels.DEBUG_4,
-                    _("bestpkg %s shares more of the name prefix with %s") %(bestpkg, reqpo))
-                return bestpkg
-            elif len(po.name) < len(bestpkg.name):
+                    _('common sourcerpm %s and %s' % (po, reqpo)))
+                pkgresults[po] += 20
+            
+            cpl = _common_prefix_len(po.name, reqpo.name)
+            if cpl > 2:
                 self.verbose_logger.log(logginglevels.DEBUG_4,
-                    _("po %s has a shorter name than best %s") %(po, bestpkg))                    
-                return po
-            elif len(po.name) == len(bestpkg.name):
-                # compare arch
-                arch = rpmUtils.arch.getBestArchFromList([po.arch, bestpkg.arch])
-                if arch == po.arch and arch != bestpkg.arch:
-                    self.verbose_logger.log(logginglevels.DEBUG_4,
-                        _("better arch in po %s") %(po))
-                    return po
+                    _('common prefix of %s between %s and %s' % (cpl, po, reqpo)))
+            
+                pkgresults[po] += cpl*2
+            
+            pkgresults[po] += (len(po.name)*-1)
+
+        bestorder = sorted(pkgresults.items(), key=itemgetter(1), reverse=True)
+        self.verbose_logger.log(logginglevels.DEBUG_4,
+                _('Best Order: %s' % str(bestorder)))
 
-        # Nothing else was better, so this is it
-        return bestpkg
+        return bestorder
+                                    
+       
 
 
 class DepCheck(object):
