+ if debug:
+ print "---"
+ print "Looking for %d things in %d extensions"%(len(things), len(things_by_ext))
+
+ extensions = []
+ keep_exts = 0
+ base_version = None
+ recheck_base_version = True
+ missing = set(things)
+ while 1:
+ if recheck_base_version:
+ max_version = Version(1, 0)
+ for t in missing:
+ supp = t.api_support.get(host_api.name)
+ if supp and supp.core_version and max_version:
+ max_version = max(max_version, supp.core_version)
+ else:
+ max_version = None
+
+ if max_version:
+ if not base_version or max_version<base_version:
+ base_version = max_version
+ keep_exts = len(extensions)
+ elif not base_version:
+ keep_exts = len(extensions)
+
+ recheck_base_version = False
+
+ if not missing or not things_by_ext:
+ break
+
+ largest_ext = None
+ largest_count = 0
+ for e, t in things_by_ext.iteritems():
+ count = len(t)
+ if count>largest_count:
+ largest_ext = e
+ largest_count = count
+ elif count==largest_count and e.preference>largest_ext.preference:
+ largest_ext = e
+
+ if debug:
+ print "Found %d things in %s"%(largest_count, largest_ext.name)
+
+ extensions.append(largest_ext)
+ for t in things_by_ext[largest_ext]:
+ missing.remove(t)
+
+ supp = t.api_support.get(host_api.name)
+ if supp and supp.core_version==base_version:
+ recheck_base_version = True
+
+ del things_by_ext[largest_ext]
+ for e in things_by_ext.keys():
+ unseen = filter((lambda t: t in missing), things_by_ext[e])
+ if unseen:
+ things_by_ext[e] = unseen
+ else:
+ del things_by_ext[e]
+
+ if not missing:
+ return None, extensions
+ elif base_version:
+ if debug:
+ print "Found remaining things in version %s"%base_version
+ if keep_exts<len(extensions):
+ print "Discarding %d extensions that do not improve base version"%(len(extensions)-keep_exts)
+ del extensions[keep_exts:]
+ return base_version, extensions
+ else:
+ if debug:
+ print "%d things still missing:"%len(missing)
+ for t in missing:
+ print " "+t.name
+ return None, None