Returns the best viable alternative for this property_set
            See the documentation for selection rules.
            # TODO: shouldn't this be 'alternative' (singular)?

def __select_alternatives (self, property_set_, debug):
        """ Returns the best viable alternative for this property_set
            See the documentation for selection rules.
            # TODO: shouldn't this be 'alternative' (singular)?
        """
        # When selecting alternatives we have to consider defaults,
        # for example:
        #    lib l : l.cpp : <variant>debug ;
        #    lib l : l_opt.cpp : <variant>release ;
        # won't work unless we add default value <variant>debug.
        assert isinstance(property_set_, property_set.PropertySet)
        assert isinstance(debug, int)  # also matches bools

        property_set_ = property_set_.add_defaults ()

        # The algorithm: we keep the current best viable alternative.
        # When we've got new best viable alternative, we compare it
        # with the current one.
        best = None
        best_properties = None

        if len (self.alternatives_) == 0:
            return None

        if len (self.alternatives_) == 1:
            return self.alternatives_ [0]

        if debug:
            print "Property set for selection:", property_set_

        for v in self.alternatives_:
            properties = v.match (property_set_, debug)

            if properties is not None:
                if not best:
                    best = v
                    best_properties = properties

                else:
                    if b2.util.set.equal (properties, best_properties):
                        return None

                    elif b2.util.set.contains (properties, best_properties):
                        # Do nothing, this alternative is worse
                        pass

                    elif b2.util.set.contains (best_properties, properties):
                        best = v
                        best_properties = properties

                    else:
                        return None

        return best