def METHOD_NAME(domain, user_id, factor, task=None):
    if task:
        DownloadBase.set_progress(explode_case_task, 0, 0)
    explosion_id = str(uuid.uuid4())
    couch_user = CommCareUser.get_by_user_id(user_id, domain)
    restore_user = get_restore_user(domain, couch_user, None)
    device = MockDevice(restore_user.project, restore_user, {"overwrite_cache": True})
    sync_result = device.restore()
    cases = {}
    new_case_ids = {}
    for case_id, case in sync_result.cases.items():
        if case.case_type != USERCASE_TYPE:
            cases[case_id] = case
            new_case_ids[case_id] = [str(uuid.uuid4()) for _ in range(factor - 1)]
    total_cases = len(cases) * (factor - 1)
    total_ledgers = 0
    if task:
        DownloadBase.set_progress(explode_case_task, 0, total_cases)
    queue = []
    progress = 0
    def queue_case(new_case, queue, progress):
        queue.append(new_case)
        if len(queue) >= 500:   # submit 500 cases at a time
            submit_case_blocks(queue, domain, user_id=user_id, device_id="explode_cases")
            progress += len(queue)
            if task:
                DownloadBase.set_progress(explode_case_task, progress, total_cases)
            del queue[:]
        return progress
    for old_case_id in reversed(topological_sort_case_blocks(cases)):
        for explosion in range(factor - 1):
            new_case = copy(cases[old_case_id])
            new_case_id = new_case_ids[old_case_id][explosion]
            new_case.create = True
            new_case.case_id = new_case_id
            new_case.update['cc_exploded_from'] = old_case_id
            new_case.update['cc_explosion_id'] = explosion_id
            new_case.index = {
                key: IndexAttrs(
                    i.case_type, new_case_ids[i.case_id][explosion], i.relationship
                ) for key, i in cases[old_case_id].index.items()
            }
            progress += queue_case(new_case.as_text(), queue, progress)
            for ledger in sync_result.ledgers.get(old_case_id, []):
                new_ledger = copy(ledger)
                new_ledger.entity_id = new_case_id
                total_ledgers += 1
                queue_case(new_ledger.as_string().decode('utf-8'), queue, progress)
    if len(queue):
        submit_case_blocks(queue, domain, user_id=user_id, device_id="explode_cases")
        DownloadBase.set_progress(explode_case_task, total_cases, total_cases)
    return {'messages': [
        "Successfully created {} cases".format(total_cases),
        "Successfully created {} ledgers".format(total_ledgers),
        "Your explosion_id for this explosion is {}".format(explosion_id)
    ]}