'Drop all the information about given objects.
DANGEROUS! This recursively deletes all objects contained within the
specified URN.
Args:
urns: Urns of objects to remove.
token: The Security Token to use for opening this item.
Raises:
RuntimeError: If one of the urns is too short. This is a safety check to
ensure the root is not removed.'

def MultiDelete(self, urns, token=None):

    urns = [rdfvalue.RDFURN(urn) for urn in urns]
    if (token is None):
        token = data_store.default_token
    for urn in urns:
        if (urn.Path() == '/'):
            raise RuntimeError("Can't    delete    root    URN.    Please    enter    a    valid    URN")
    deletion_pool = DeletionPool(token=token)
    deletion_pool.MultiMarkForDeletion(urns)
    marked_root_urns = deletion_pool.root_urns_for_deletion
    marked_urns = deletion_pool.urns_for_deletion
    logging.debug(u'Found    %d    objects    to    remove    when    removing    %s', len(marked_urns), utils.SmartUnicode(urns))
    logging.debug(u'Removing    %d    root    objects    when    removing    %s:    %s', len(marked_root_urns), utils.SmartUnicode(urns), utils.SmartUnicode(marked_root_urns))
    pool = data_store.DB.GetMutationPool(token=token)
    for root in marked_root_urns:
        self._DeleteChildFromIndex(root, token, mutation_pool=pool)
    for urn_to_delete in marked_urns:
        try:
            self.intermediate_cache.ExpireObject(urn_to_delete.Path())
        except KeyError:
            pass
    pool.DeleteSubjects(marked_urns)
    pool.Flush()
    self.Flush()
    logging.debug('Removed    %d    objects', len(marked_urns))
