'Given a source and destination selectable, create a
join between them.
This takes into account aliasing the join clause
to reference the appropriate corresponding columns
in the target objects, as well as the extra child
criterion, equivalent column sets, etc.'

def join_targets(self, source_selectable, dest_selectable, aliased, single_crit=None):

    dest_selectable = _shallow_annotate(dest_selectable, {'no_replacement_traverse': True})
    (primaryjoin, secondaryjoin, secondary) = (self.primaryjoin, self.secondaryjoin, self.secondary)
    if (single_crit is not None):
        if (secondaryjoin is not None):
            secondaryjoin = (secondaryjoin & single_crit)
        else:
            primaryjoin = (primaryjoin & single_crit)
    if aliased:
        if (secondary is not None):
            secondary = secondary.alias(flat=True)
            primary_aliasizer = ClauseAdapter(secondary)
            secondary_aliasizer = ClauseAdapter(dest_selectable, equivalents=self.child_equivalents).chain(primary_aliasizer)
            if (source_selectable is not None):
                primary_aliasizer = ClauseAdapter(secondary).chain(ClauseAdapter(source_selectable, equivalents=self.parent_equivalents))
            secondaryjoin = secondary_aliasizer.traverse(secondaryjoin)
        else:
            primary_aliasizer = ClauseAdapter(dest_selectable, exclude_fn=_ColInAnnotations('local'), equivalents=self.child_equivalents)
            if (source_selectable is not None):
                primary_aliasizer.chain(ClauseAdapter(source_selectable, exclude_fn=_ColInAnnotations('remote'), equivalents=self.parent_equivalents))
            secondary_aliasizer = None
        primaryjoin = primary_aliasizer.traverse(primaryjoin)
        target_adapter = (secondary_aliasizer or primary_aliasizer)
        target_adapter.exclude_fn = None
    else:
        target_adapter = None
    return (primaryjoin, secondaryjoin, secondary, target_adapter, dest_selectable)
