@_generative(_no_statement_condition, _no_limit_offset)
def _join(self, keys, outerjoin, create_aliases, from_joinpoint):
    'consumes arguments from join() or outerjoin(), places them into a\n        consistent format with which to form the actual JOIN constructs.\n\n        '
    if (not from_joinpoint):
        self._reset_joinpoint()
    if ((len(keys) == 2) and isinstance(keys[0], (expression.FromClause, type, AliasedClass)) and isinstance(keys[1], (str, expression.ClauseElement, interfaces.PropComparator))):
        keys = (keys,)
    for arg1 in util.to_list(keys):
        if isinstance(arg1, tuple):
            (arg1, arg2) = arg1
        else:
            arg2 = None
        if isinstance(arg1, (interfaces.PropComparator, util.string_types)):
            (right_entity, onclause) = (arg2, arg1)
        else:
            (right_entity, onclause) = (arg1, arg2)
        left_entity = prop = None
        if isinstance(onclause, interfaces.PropComparator):
            of_type = getattr(onclause, '_of_type', None)
        else:
            of_type = None
        if isinstance(onclause, util.string_types):
            left_entity = self._joinpoint_zero()
            descriptor = _entity_descriptor(left_entity, onclause)
            onclause = descriptor
        elif (from_joinpoint and isinstance(onclause, interfaces.PropComparator)):
            left_entity = onclause._parententity
            info = inspect(self._joinpoint_zero())
            (left_mapper, left_selectable, left_is_aliased) = (getattr(info, 'mapper', None), info.selectable, getattr(info, 'is_aliased_class', None))
            if (left_mapper is left_entity):
                left_entity = self._joinpoint_zero()
                descriptor = _entity_descriptor(left_entity, onclause.key)
                onclause = descriptor
        if isinstance(onclause, interfaces.PropComparator):
            if (right_entity is None):
                if of_type:
                    right_entity = of_type
                else:
                    right_entity = onclause.property.mapper
            left_entity = onclause._parententity
            prop = onclause.property
            if (not isinstance(onclause, attributes.QueryableAttribute)):
                onclause = prop
            if (not create_aliases):
                edge = (left_entity, right_entity, prop.key)
                if (edge in self._joinpoint):
                    jp = self._joinpoint[edge].copy()
                    jp['prev'] = (edge, self._joinpoint)
                    self._update_joinpoint(jp)
                    continue
        elif ((onclause is not None) and (right_entity is None)):
            raise NotImplementedError('query.join(a==b) not supported.')
        self._join_left_to_right(left_entity, right_entity, onclause, outerjoin, create_aliases, prop)
consumes arguments from join() or outerjoin(), places them into a
consistent format with which to form the actual JOIN constructs.
@_generative(_no_statement_condition, _no_limit_offset)
def _join(self, keys, outerjoin, create_aliases, from_joinpoint):
    'consumes arguments from join() or outerjoin(), places them into a\n        consistent format with which to form the actual JOIN constructs.\n\n        '
    if (not from_joinpoint):
        self._reset_joinpoint()
    if ((len(keys) == 2) and isinstance(keys[0], (expression.FromClause, type, AliasedClass)) and isinstance(keys[1], (str, expression.ClauseElement, interfaces.PropComparator))):
        keys = (keys,)
    for arg1 in util.to_list(keys):
        if isinstance(arg1, tuple):
            (arg1, arg2) = arg1
        else:
            arg2 = None
        if isinstance(arg1, (interfaces.PropComparator, util.string_types)):
            (right_entity, onclause) = (arg2, arg1)
        else:
            (right_entity, onclause) = (arg1, arg2)
        left_entity = prop = None
        if isinstance(onclause, interfaces.PropComparator):
            of_type = getattr(onclause, '_of_type', None)
        else:
            of_type = None
        if isinstance(onclause, util.string_types):
            left_entity = self._joinpoint_zero()
            descriptor = _entity_descriptor(left_entity, onclause)
            onclause = descriptor
        elif (from_joinpoint and isinstance(onclause, interfaces.PropComparator)):
            left_entity = onclause._parententity
            info = inspect(self._joinpoint_zero())
            (left_mapper, left_selectable, left_is_aliased) = (getattr(info, 'mapper', None), info.selectable, getattr(info, 'is_aliased_class', None))
            if (left_mapper is left_entity):
                left_entity = self._joinpoint_zero()
                descriptor = _entity_descriptor(left_entity, onclause.key)
                onclause = descriptor
        if isinstance(onclause, interfaces.PropComparator):
            if (right_entity is None):
                if of_type:
                    right_entity = of_type
                else:
                    right_entity = onclause.property.mapper
            left_entity = onclause._parententity
            prop = onclause.property
            if (not isinstance(onclause, attributes.QueryableAttribute)):
                onclause = prop
            if (not create_aliases):
                edge = (left_entity, right_entity, prop.key)
                if (edge in self._joinpoint):
                    jp = self._joinpoint[edge].copy()
                    jp['prev'] = (edge, self._joinpoint)
                    self._update_joinpoint(jp)
                    continue
        elif ((onclause is not None) and (right_entity is None)):
            raise NotImplementedError('query.join(a==b) not supported.')
        self._join_left_to_right(left_entity, right_entity, onclause, outerjoin, create_aliases, prop)