def move_part_instance(part_instance, target_parent, part_model, name=None, include_children=True):
    if not name:
        name = part_instance.name
    moved_model = get_mapping_dictionary()[part_model.id]
    if moved_model.multiplicity == Multiplicity.ONE:
        moved_instance = moved_model.instances(parent_id=target_parent.id)[0]
        map_property_instances(part_instance, moved_instance)
        moved_instance = update_part_with_properties(part_instance, moved_instance, name=str(name))
    elif moved_model.multiplicity == Multiplicity.ONE_MANY:
        if target_parent.id not in get_edited_one_many():
            moved_instance = moved_model.instances(parent_id=target_parent.id)[0]
            map_property_instances(part_instance, moved_instance)
            moved_instance = update_part_with_properties(part_instance, moved_instance, name=str(name))
            get_edited_one_many().append(target_parent.id)
        else:
            moved_instance = target_parent.add(name=part_instance.name, model=moved_model, suppress_kevents=True)
            map_property_instances(part_instance, moved_instance)
            moved_instance = update_part_with_properties(part_instance, moved_instance, name=str(name))
    else:
        moved_instance = target_parent.add(name=name, model=moved_model, suppress_kevents=True)
        map_property_instances(part_instance, moved_instance)
        moved_instance = update_part_with_properties(part_instance, moved_instance, name=str(name))
    if include_children:
        for sub_instance in part_instance._cached_children:
            move_part_instance(part_instance=sub_instance, target_parent=moved_instance,
                               part_model=sub_instance.model(),
                               name=sub_instance.name, include_children=True)
    return moved_instance