'Removes many activities from the feed
:param activities: the list of activities to remove'

def remove_many(self, activities, batch_interface=None, trim=True, *args, **kwargs):

    self.trim()
    current_activities = kwargs.pop('current_activities', None)
    if (current_activities is None):
        current_activities = self.get_activity_slice(stop=self.max_length, rehydrate=False)
    (new, deleted, changed) = ([], [], [])
    getid = (lambda a: getattr(a, 'serialization_id', a))
    activities_to_remove = set((getid(a) for a in activities))
    activity_dict = dict(((getid(a), a) for a in activities))
    activity_remove_dict = defaultdict(list)
    for aggregated in current_activities:
        for activity_id in aggregated.activity_ids:
            if (activity_id in activities_to_remove):
                activity_remove_dict[aggregated].append(activity_id)
                activities_to_remove.discard(activity_id)
        if (not activities_to_remove):
            break
    hydrated_aggregated = activity_remove_dict.keys()
    if self.needs_hydration(hydrated_aggregated):
        hydrated_aggregated = self.hydrate_activities(hydrated_aggregated)
    hydrate_dict = dict(((a.group, a) for a in hydrated_aggregated))
    for (aggregated, activity_ids_to_remove) in activity_remove_dict.items():
        aggregated = hydrate_dict.get(aggregated.group)
        if (len(aggregated) == len(activity_ids_to_remove)):
            deleted.append(aggregated)
        else:
            original = copy.deepcopy(aggregated)
            activities_to_remove = map(activity_dict.get, activity_ids_to_remove)
            aggregated.remove_many(activities_to_remove)
            changed.append((original, aggregated))
    new_aggregated = self._update_from_diff(new, changed, deleted)
    return new_aggregated
