'Change the membership status of a user in a room.
Args:
requester (Requester): The local user who requested the membership
event. If None, certain checks, like whether this homeserver can
act as the sender, will be skipped.
event (SynapseEvent): The membership event.
context: The context of the event.
is_guest (bool): Whether the sender is a guest.
room_hosts ([str]): Homeservers which are likely to already be in
the room, and could be danced with in order to join this
homeserver for the first time.
ratelimit (bool): Whether to rate limit this request.
Raises:
SynapseError if there was a problem changing the membership.'

@defer.inlineCallbacks
def send_membership_event(self, requester, event, context, remote_room_hosts=None, ratelimit=True):

    remote_room_hosts = (remote_room_hosts or [])
    target_user = UserID.from_string(event.state_key)
    room_id = event.room_id
    if (requester is not None):
        sender = UserID.from_string(event.sender)
        assert (sender == requester.user), ('Sender    (%s)    must    be    same    as    requester    (%s)' % (sender, requester.user))
        assert self.hs.is_mine(sender), ('Sender    must    be    our    own:    %s' % (sender,))
    else:
        requester = synapse.types.create_requester(target_user)
    message_handler = self.hs.get_handlers().message_handler
    prev_event = (yield message_handler.deduplicate_state_event(event, context))
    if (prev_event is not None):
        return
    if (event.membership == Membership.JOIN):
        if requester.is_guest:
            guest_can_join = (yield self._can_guest_join(context.prev_state_ids))
            if (not guest_can_join):
                raise AuthError(403, 'Guest    access    not    allowed')
    if (event.membership not in (Membership.LEAVE, Membership.BAN)):
        is_blocked = (yield self.store.is_room_blocked(room_id))
        if is_blocked:
            raise SynapseError(403, 'This    room    has    been    blocked    on    this    server')
    (yield message_handler.handle_new_client_event(requester, event, context, extra_users=[target_user], ratelimit=ratelimit))
    prev_member_event_id = context.prev_state_ids.get((EventTypes.Member, event.state_key), None)
    if (event.membership == Membership.JOIN):
        newly_joined = True
        if prev_member_event_id:
            prev_member_event = (yield self.store.get_event(prev_member_event_id))
            newly_joined = (prev_member_event.membership != Membership.JOIN)
        if newly_joined:
            (yield user_joined_room(self.distributor, target_user, room_id))
    elif (event.membership == Membership.LEAVE):
        if prev_member_event_id:
            prev_member_event = (yield self.store.get_event(prev_member_event_id))
            if (prev_member_event.membership == Membership.JOIN):
                user_left_room(self.distributor, target_user, room_id)
