'Sends a join event to one of a list of homeservers.
Doing so will cause the remote server to add the event to the graph,
and send the event out to the rest of the federation.
Args:
destinations (str): Candidate homeservers which are probably
participating in the room.
pdu (BaseEvent): event to be sent
Return:
Deferred: resolves to a dict with members ``origin`` (a string
giving the serer the event was sent to, ``state`` (?) and
``auth_chain``.
Fails with a ``CodeMessageException`` if the chosen remote server
returns a 300/400 code.
Fails with a ``RuntimeError`` if no servers were reachable.'

@defer.inlineCallbacks
def send_join(self, destinations, pdu):

    for destination in destinations:
        if (destination == self.server_name):
            continue
        try:
            time_now = self._clock.time_msec()
            (_, content) = (yield self.transport_layer.send_join(destination=destination, room_id=pdu.room_id, event_id=pdu.event_id, content=pdu.get_pdu_json(time_now)))
            logger.debug('Got    content:    %s', content)
            state = [self.event_from_pdu_json(p, outlier=True) for p in content.get('state', [])]
            auth_chain = [self.event_from_pdu_json(p, outlier=True) for p in content.get('auth_chain', [])]
            pdus = {p.event_id: p for p in itertools.chain(state, auth_chain)}
            valid_pdus = (yield self._check_sigs_and_hash_and_fetch(destination, pdus.values(), outlier=True))
            valid_pdus_map = {p.event_id: p for p in valid_pdus}
            signed_state = [copy.copy(valid_pdus_map[p.event_id]) for p in state if (p.event_id in valid_pdus_map)]
            signed_auth = [valid_pdus_map[p.event_id] for p in auth_chain if (p.event_id in valid_pdus_map)]
            for s in signed_state:
                s.internal_metadata = copy.deepcopy(s.internal_metadata)
            auth_chain.sort(key=(lambda e: e.depth))
            defer.returnValue({'state': signed_state, 'auth_chain': signed_auth, 'origin': destination})
        except CodeMessageException as e:
            if (not (500 <= e.code < 600)):
                raise
            else:
                logger.exception('Failed    to    send_join    via    %s:    %s', destination, e.message)
        except Exception as e:
            logger.exception('Failed    to    send_join    via    %s:    %s', destination, e.message)
    raise RuntimeError('Failed    to    send    to    any    server.')
