'Return a copy of this history using the given `name` and `target_user`.
If `activatable`, copy only non-deleted datasets. If `all_datasets`, copy
non-deleted, deleted, and purged datasets.'

def copy(self, name=None, target_user=None, activatable=False, all_datasets=False):

    name = (name or self.name)
    applies_to_quota = (target_user != self.user)
    new_history = History(name=name, user=target_user)
    db_session = object_session(self)
    db_session.add(new_history)
    db_session.flush()
    if target_user:
        self.copy_item_annotation(db_session, self.user, self, target_user, new_history)
        new_history.copy_tags_from(target_user=target_user, source_history=self)
    if activatable:
        hdas = self.activatable_datasets
    elif all_datasets:
        hdas = self.datasets
    else:
        hdas = self.active_datasets
    for hda in hdas:
        new_hda = hda.copy(copy_children=True)
        new_history.add_dataset(new_hda, set_hid=False, quota=applies_to_quota)
        db_session.add(new_hda)
        db_session.flush()
        if target_user:
            new_hda.copy_item_annotation(db_session, self.user, hda, target_user, new_hda)
            new_hda.copy_tags_from(target_user, hda)
    if all_datasets:
        hdcas = self.dataset_collections
    else:
        hdcas = self.active_dataset_collections
    for hdca in hdcas:
        new_hdca = hdca.copy()
        new_history.add_dataset_collection(new_hdca, set_hid=False)
        db_session.add(new_hdca)
        db_session.flush()
        if target_user:
            new_hdca.copy_item_annotation(db_session, self.user, hdca, target_user, new_hdca)
    new_history.hid_counter = self.hid_counter
    db_session.add(new_history)
    db_session.flush()
    return new_history
