def promote_joins(self, aliases, unconditional=False):
        """
        Promotes recursively the join type of given aliases and its children to
        an outer join. If 'unconditional' is False, the join is only promoted if
        it is nullable or the parent join is an outer join.

        Note about join promotion: When promoting any alias, we make sure all
        joins which start from that alias are promoted, too. When adding a join
        in join(), we make sure any join added to already existing LOUTER join
        is generated as LOUTER. This ensures we don't ever have broken join
        chains which contain first a LOUTER join, then an INNER JOIN, that is
        this kind of join should never be generated: a LOUTER b INNER c. The
        reason for avoiding this type of join chain is that the INNER after
        the LOUTER will effectively remove any effect the LOUTER had.
        """
        aliases = list(aliases)
        while aliases:
            alias = aliases.pop(0)
            if self.alias_map[alias].rhs_join_col is None:
                # This is the base table (first FROM entry) - this table
                # isn't really joined at all in the query, so we should not
                # alter its join type.
                continue
            parent_alias = self.alias_map[alias].lhs_alias
            parent_louter = (parent_alias
                and self.alias_map[parent_alias].join_type == self.LOUTER)
            already_louter = self.alias_map[alias].join_type == self.LOUTER
            if ((unconditional or self.alias_map[alias].nullable
                 or parent_louter) and not already_louter):
                data = self.alias_map[alias]._replace(join_type=self.LOUTER)
                self.alias_map[alias] = data
                # Join type of 'alias' changed, so re-examine all aliases that
                # refer to this one.
                aliases.extend(
                    join for join in self.alias_map.keys()
                    if (self.alias_map[join].lhs_alias == alias
                        and aliases not in join))
dataset/ETHPy150Open AppScale/appscale/AppServer/lib/django-1.5/django/db/models/sql/query.py/Query.promote_joins/swapped operands of `not in`