'Please upate me
:param force: if True, delete existing followers before creating new one
using the subtypes given in the parameters'

@api.model
def _add_follower_command(self, res_model, res_ids, partner_data, channel_data, force=True):

    force_mode = (force or (all((data for data in partner_data.values())) and all((data for data in channel_data.values()))))
    generic = []
    specific = {}
    existing = {}
    p_exist = {}
    c_exist = {}
    followers = self.sudo().search(['&', '&', ('res_model', '=', res_model), ('res_id', 'in', res_ids), '|', ('partner_id', 'in', partner_data.keys()), ('channel_id', 'in', channel_data.keys())])
    if force_mode:
        followers.unlink()
    else:
        for follower in followers:
            existing.setdefault(follower.res_id, list()).append(follower)
            if follower.partner_id:
                p_exist.setdefault(follower.partner_id.id, list()).append(follower.res_id)
            if follower.channel_id:
                c_exist.setdefault(follower.channel_id.id, list()).append(follower.res_id)
    default_subtypes = self.env['mail.message.subtype'].search([('default', '=', True), '|', ('res_model', '=', res_model), ('res_model', '=', False)])
    external_default_subtypes = default_subtypes.filtered((lambda subtype: (not subtype.internal)))
    if force_mode:
        employee_pids = self.env['res.users'].sudo().search([('partner_id', 'in', partner_data.keys()), ('share', '=', False)]).mapped('partner_id').ids
        for (pid, data) in partner_data.iteritems():
            if (not data):
                if (pid not in employee_pids):
                    partner_data[pid] = external_default_subtypes.ids
                else:
                    partner_data[pid] = default_subtypes.ids
        for (cid, data) in channel_data.iteritems():
            if (not data):
                channel_data[cid] = default_subtypes.ids
    gen_new_pids = [pid for pid in partner_data.keys() if (pid not in p_exist)]
    gen_new_cids = [cid for cid in channel_data.keys() if (cid not in c_exist)]
    for pid in gen_new_pids:
        generic.append([0, 0, {'res_model': res_model, 'partner_id': pid, 'subtype_ids': [(6, 0, (partner_data.get(pid) or default_subtypes.ids))]}])
    for cid in gen_new_cids:
        generic.append([0, 0, {'res_model': res_model, 'channel_id': cid, 'subtype_ids': [(6, 0, (channel_data.get(cid) or default_subtypes.ids))]}])
    if (not force_mode):
        for res_id in res_ids:
            command = []
            doc_followers = existing.get(res_id, list())
            new_pids = ((set(partner_data.keys()) - set([sub.partner_id.id for sub in doc_followers if sub.partner_id])) - set(gen_new_pids))
            new_cids = ((set(channel_data.keys()) - set([sub.channel_id.id for sub in doc_followers if sub.channel_id])) - set(gen_new_cids))
            for new_pid in new_pids:
                command.append((0, 0, {'res_model': res_model, 'partner_id': new_pid, 'subtype_ids': [(6, 0, (partner_data.get(new_pid) or default_subtypes.ids))]}))
            for new_cid in new_cids:
                command.append((0, 0, {'res_model': res_model, 'channel_id': new_cid, 'subtype_ids': [(6, 0, (channel_data.get(new_cid) or default_subtypes.ids))]}))
            if command:
                specific[res_id] = command
    return (generic, specific)
