'Get the root_usage from the db and do a depth first scan. Call the function on each. The
function should return a list of SON for any next tier items to process and should
add the SON for any items to delete to the to_be_deleted array.
At the end, it mass deletes the to_be_deleted items and refreshes the cached metadata inheritance
tree.
:param function: a function taking (item, to_be_deleted) and returning [SON] for next_tier invocation
:param root_usages: the usage keys for the root items (ensure they have the right revision set)'

def _breadth_first(self, function, root_usages):

    if (len(root_usages) == 0):
        return
    to_be_deleted = []
    def _internal(tier):
        next_tier = []
        tier_items = self.collection.find({'_id': {'$in': tier}})
        for current_entry in tier_items:
            next_tier.extend(function(current_entry, to_be_deleted))
        if (len(next_tier) > 0):
            _internal(next_tier)
    _internal([root_usage.to_deprecated_son() for root_usage in root_usages])
    if (len(to_be_deleted) > 0):
        bulk_record = self._get_bulk_ops_record(root_usages[0].course_key)
        bulk_record.dirty = True
        self.collection.remove({'_id': {'$in': to_be_deleted}}, safe=self.collection.safe)
