use crate::{
    archetype::Archetype,
    bundle::{
        Bundle, BundleFromComponents, BundleInserter, BundleRemover, DynamicBundle, InsertMode,
    },
    change_detection::{ComponentTicks, MaybeLocation, MutUntyped, Tick},
    component::{Component, ComponentId, Components, Mutable, StorageType},
    entity::{Entity, EntityCloner, EntityClonerBuilder, EntityLocation, OptIn, OptOut},
    event::{EntityComponentsTrigger, EntityEvent},
    lifecycle::{Despawn, Remove, Replace, DESPAWN, REMOVE, REPLACE},
    observer::Observer,
    query::{
        has_conflicts, Access, DebugCheckedUnwrap, QueryAccessError, ReadOnlyQueryData,
        ReleaseStateQueryData,
    },
    relationship::RelationshipHookMode,
    resource::Resource,
    storage::{SparseSets, Table},
    system::IntoObserverSystem,
    world::{
        error::EntityComponentError, unsafe_world_cell::UnsafeEntityCell, ComponentEntry,
        DynamicComponentFetch, EntityMut, EntityRef, FilteredEntityMut, FilteredEntityRef, Mut,
        OccupiedComponentEntry, Ref, VacantComponentEntry, World,
    },
};

use alloc::vec::Vec;
use bevy_ptr::{move_as_ptr, MovingPtr, OwningPtr};
use core::{any::TypeId, marker::PhantomData, mem::MaybeUninit};

/// A mutable reference to a particular [`Entity`], and the entire world.
///
/// This is essentially a performance-optimized `(Entity, &mut World)` tuple,
/// which caches the [`EntityLocation`] to reduce duplicate lookups.
///
/// Since this type provides mutable access to the entire world, only one
/// [`EntityWorldMut`] can exist at a time for a given world.
///
/// See also [`EntityMut`], which allows disjoint mutable access to multiple
/// entities at once.  Unlike `EntityMut`, this type allows adding and
/// removing components, and despawning the entity.
///
/// # Invariants and Risk
///
/// An [`EntityWorldMut`] may point to a despawned entity.
/// You can check this via [`is_despawned`](Self::is_despawned).
/// Using an [`EntityWorldMut`] of a despawned entity may panic in some contexts, so read method documentation carefully.
///
/// Unless you have strong reason to assume these invariants, you should generally avoid keeping an [`EntityWorldMut`] to an entity that is potentially not spawned.
/// For example, when inserting a component, that component insert may trigger an observer that despawns the entity.
/// So, when you don't have full knowledge of what commands may interact with this entity,
/// do not further use this value without first checking [`is_despawned`](Self::is_despawned).
pub struct EntityWorldMut<'w> {
    world: &'w mut World,
    entity: Entity,
    location: Option<EntityLocation>,
}

impl<'w> EntityWorldMut<'w> {
    #[track_caller]
    #[inline(never)]
    #[cold]
    fn panic_despawned(&self) -> ! {
        panic!(
            "Entity {} {}",
            self.entity,
            self.world.entities().get_spawned(self.entity).unwrap_err()
        );
    }

    #[inline(always)]
    #[track_caller]
    pub(crate) fn assert_not_despawned(&self) {
        if self.location.is_none() {
            self.panic_despawned()
        }
    }

    #[inline(always)]
    fn as_unsafe_entity_cell_readonly(&self) -> UnsafeEntityCell<'_> {
        let location = self.location();
        let last_change_tick = self.world.last_change_tick;
        let change_tick = self.world.read_change_tick();
        UnsafeEntityCell::new(
            self.world.as_unsafe_world_cell_readonly(),
            self.entity,
            location,
            last_change_tick,
            change_tick,
        )
    }

    #[inline(always)]
    fn as_unsafe_entity_cell(&mut self) -> UnsafeEntityCell<'_> {
        let location = self.location();
        let last_change_tick = self.world.last_change_tick;
        let change_tick = self.world.change_tick();
        UnsafeEntityCell::new(
            self.world.as_unsafe_world_cell(),
            self.entity,
            location,
            last_change_tick,
            change_tick,
        )
    }

    #[inline(always)]
    fn into_unsafe_entity_cell(self) -> UnsafeEntityCell<'w> {
        let location = self.location();
        let last_change_tick = self.world.last_change_tick;
        let change_tick = self.world.change_tick();
        UnsafeEntityCell::new(
            self.world.as_unsafe_world_cell(),
            self.entity,
            location,
            last_change_tick,
            change_tick,
        )
    }

    /// # Safety
    ///
    ///  The `location` must be sourced from `world`'s `Entities` and must exactly match the location for `entity`.
    ///  If the `entity` is not spawned for any reason (See [`EntityNotSpawnedError`](crate::entity::EntityNotSpawnedError)), the location should be `None`.
    ///
    ///  The above is trivially satisfied if `location` was sourced from `world.entities().get_spawned(entity).ok()`.
    #[inline]
    pub(crate) unsafe fn new(
        world: &'w mut World,
        entity: Entity,
        location: Option<EntityLocation>,
    ) -> Self {
        debug_assert_eq!(world.entities().get_spawned(entity).ok(), location);

        EntityWorldMut {
            world,
            entity,
            location,
        }
    }

    /// Consumes `self` and returns read-only access to all of the entity's
    /// components, with the world `'w` lifetime.
    pub fn into_readonly(self) -> EntityRef<'w> {
        EntityRef::from(self)
    }

    /// Gets read-only access to all of the entity's components.
    #[inline]
    pub fn as_readonly(&self) -> EntityRef<'_> {
        EntityRef::from(self)
    }

    /// Consumes `self` and returns non-structural mutable access to all of the
    /// entity's components, with the world `'w` lifetime.
    pub fn into_mutable(self) -> EntityMut<'w> {
        EntityMut::from(self)
    }

    /// Gets non-structural mutable access to all of the entity's components.
    #[inline]
    pub fn as_mutable(&mut self) -> EntityMut<'_> {
        EntityMut::from(self)
    }

    /// Returns the [ID](Entity) of the current entity.
    #[inline]
    #[must_use = "Omit the .id() call if you do not need to store the `Entity` identifier."]
    pub fn id(&self) -> Entity {
        self.entity
    }

    /// Gets metadata indicating the location where the current entity is stored.
    #[inline]
    pub fn try_location(&self) -> Option<EntityLocation> {
        self.location
    }

    /// Returns if the entity is spawned or not.
    #[inline]
    pub fn is_spawned(&self) -> bool {
        self.try_location().is_some()
    }

    /// Returns the archetype that the current entity belongs to.
    #[inline]
    pub fn try_archetype(&self) -> Option<&Archetype> {
        self.try_location()
            .map(|location| &self.world.archetypes[location.archetype_id])
    }

    /// Gets metadata indicating the location where the current entity is stored.
    ///
    /// # Panics
    ///
    /// If the entity has been despawned while this `EntityWorldMut` is still alive.
    #[inline]
    pub fn location(&self) -> EntityLocation {
        match self.try_location() {
            Some(a) => a,
            None => self.panic_despawned(),
        }
    }

    /// Returns the archetype that the current entity belongs to.
    ///
    /// # Panics
    ///
    /// If the entity has been despawned while this `EntityWorldMut` is still alive.
    #[inline]
    pub fn archetype(&self) -> &Archetype {
        match self.try_archetype() {
            Some(a) => a,
            None => self.panic_despawned(),
        }
    }

    /// Returns `true` if the current entity has a component of type `T`.
    /// Otherwise, this returns `false`.
    ///
    /// ## Notes
    ///
    /// If you do not know the concrete type of a component, consider using
    /// [`Self::contains_id`] or [`Self::contains_type_id`].
    ///
    /// # Panics
    ///
    /// If the entity has been despawned while this `EntityWorldMut` is still alive.
    #[inline]
    pub fn contains<T: Component>(&self) -> bool {
        self.contains_type_id(TypeId::of::<T>())
    }

    /// Returns `true` if the current entity has a component identified by `component_id`.
    /// Otherwise, this returns false.
    ///
    /// ## Notes
    ///
    /// - If you know the concrete type of the component, you should prefer [`Self::contains`].
    /// - If you know the component's [`TypeId`] but not its [`ComponentId`], consider using
    ///   [`Self::contains_type_id`].
    ///
    /// # Panics
    ///
    /// If the entity has been despawned while this `EntityWorldMut` is still alive.
    #[inline]
    pub fn contains_id(&self, component_id: ComponentId) -> bool {
        self.as_unsafe_entity_cell_readonly()
            .contains_id(component_id)
    }

    /// Returns `true` if the current entity has a component with the type identified by `type_id`.
    /// Otherwise, this returns false.
    ///
    /// ## Notes
    ///
    /// - If you know the concrete type of the component, you should prefer [`Self::contains`].
    /// - If you have a [`ComponentId`] instead of a [`TypeId`], consider using [`Self::contains_id`].
    ///
    /// # Panics
    ///
    /// If the entity has been despawned while this `EntityWorldMut` is still alive.
    #[inline]
    pub fn contains_type_id(&self, type_id: TypeId) -> bool {
        self.as_unsafe_entity_cell_readonly()
            .contains_type_id(type_id)
    }

    /// Gets access to the component of type `T` for the current entity.
    /// Returns `None` if the entity does not have a component of type `T`.
    ///
    /// # Panics
    ///
    /// If the entity has been despawned while this `EntityWorldMut` is still alive.
    #[inline]
    pub fn get<T: Component>(&self) -> Option<&'_ T> {
        self.as_readonly().get()
    }

    /// Returns read-only components for the current entity that match the query `Q`.
    ///
    /// # Panics
    ///
    /// If the entity does not have the components required by the query `Q` or if the entity
    /// has been despawned while this `EntityWorldMut` is still alive.
    #[inline]
    pub fn components<Q: ReadOnlyQueryData + ReleaseStateQueryData>(&self) -> Q::Item<'_, 'static> {
        self.as_readonly().components::<Q>()
    }

    /// Returns read-only components for the current entity that match the query `Q`,
    /// or `None` if the entity does not have the components required by the query `Q`.
    ///
    /// # Panics
    ///
    /// If the entity has been despawned while this `EntityWorldMut` is still alive.
    #[inline]
    pub fn get_components<Q: ReadOnlyQueryData + ReleaseStateQueryData>(
        &self,
    ) -> Result<Q::Item<'_, 'static>, QueryAccessError> {
        self.as_readonly().get_components::<Q>()
    }

    /// Returns components for the current entity that match the query `Q`,
    /// or `None` if the entity does not have the components required by the query `Q`.
    ///
    /// # Example
    ///
    /// ```
    /// # use bevy_ecs::prelude::*;
    /// #
    /// #[derive(Component)]
    /// struct X(usize);
    /// #[derive(Component)]
    /// struct Y(usize);
    ///
    /// # let mut world = World::default();
    /// let mut entity = world.spawn((X(0), Y(0)));
    /// // Get mutable access to two components at once
    /// // SAFETY: X and Y are different components
    /// let (mut x, mut y) =
    ///     unsafe { entity.get_components_mut_unchecked::<(&mut X, &mut Y)>() }.unwrap();
    /// *x = X(1);
    /// *y = Y(1);
    /// // This would trigger undefined behavior, as the `&mut X`s would alias:
    /// // entity.get_components_mut_unchecked::<(&mut X, &mut X)>();
    /// ```
    ///
    /// # Safety
    /// It is the caller's responsibility to ensure that
    /// the `QueryData` does not provide aliasing mutable references to the same component.
    ///
    /// /// # See also
    ///
    /// - [`Self::get_components_mut`] for the safe version that performs aliasing checks
    pub unsafe fn get_components_mut_unchecked<Q: ReleaseStateQueryData>(
        &mut self,
    ) -> Result<Q::Item<'_, 'static>, QueryAccessError> {
        // SAFETY: Caller the `QueryData` does not provide aliasing mutable references to the same component
        unsafe { self.as_mutable().into_components_mut_unchecked::<Q>() }
    }

    /// Returns components for the current entity that match the query `Q`.
    /// In the case of conflicting [`QueryData`](crate::query::QueryData), unregistered components, or missing components,
    /// this will return a [`QueryAccessError`]
    ///
    /// # Example
    ///
    /// ```
    /// # use bevy_ecs::prelude::*;
    /// #
    /// #[derive(Component)]
    /// struct X(usize);
    /// #[derive(Component)]
    /// struct Y(usize);
    ///
    /// # let mut world = World::default();
    /// let mut entity = world.spawn((X(0), Y(0))).into_mutable();
    /// // Get mutable access to two components at once
    /// // SAFETY: X and Y are different components
    /// let (mut x, mut y) = entity.get_components_mut::<(&mut X, &mut Y)>().unwrap();
    /// ```
    ///
    /// Note that this does a O(n^2) check that the [`QueryData`](crate::query::QueryData) does not conflict. If performance is a
    /// consideration you should use [`Self::get_components_mut_unchecked`] instead.
    pub fn get_components_mut<Q: ReleaseStateQueryData>(
        &mut self,
    ) -> Result<Q::Item<'_, 'static>, QueryAccessError> {
        self.as_mutable().into_components_mut::<Q>()
    }

    /// Consumes self and returns components for the current entity that match the query `Q` for the world lifetime `'w`,
    /// or `None` if the entity does not have the components required by the query `Q`.
    ///
    /// # Example
    ///
    /// ```
    /// # use bevy_ecs::prelude::*;
    /// #
    /// #[derive(Component)]
    /// struct X(usize);
    /// #[derive(Component)]
    /// struct Y(usize);
    ///
    /// # let mut world = World::default();
    /// let mut entity = world.spawn((X(0), Y(0)));
    /// // Get mutable access to two components at once
    /// // SAFETY: X and Y are different components
    /// let (mut x, mut y) =
    ///     unsafe { entity.into_components_mut_unchecked::<(&mut X, &mut Y)>() }.unwrap();
    /// *x = X(1);
    /// *y = Y(1);
    /// // This would trigger undefined behavior, as the `&mut X`s would alias:
    /// // entity.into_components_mut_unchecked::<(&mut X, &mut X)>();
    /// ```
    ///
    /// # Safety
    /// It is the caller's responsibility to ensure that
    /// the `QueryData` does not provide aliasing mutable references to the same component.
    ///
    /// # See also
    ///
    /// - [`Self::into_components_mut`] for the safe version that performs aliasing checks
    pub unsafe fn into_components_mut_unchecked<Q: ReleaseStateQueryData>(
        self,
    ) -> Result<Q::Item<'w, 'static>, QueryAccessError> {
        // SAFETY: Caller the `QueryData` does not provide aliasing mutable references to the same component
        unsafe { self.into_mutable().into_components_mut_unchecked::<Q>() }
    }

    /// Consumes self and returns components for the current entity that match the query `Q` for the world lifetime `'w`,
    /// or `None` if the entity does not have the components required by the query `Q`.
    ///
    /// The checks for aliasing mutable references may be expensive.
    /// If performance is a concern, consider making multiple calls to [`Self::get_mut`].
    /// If that is not possible, consider using [`Self::into_components_mut_unchecked`] to skip the checks.
    ///
    /// # Panics
    ///
    /// - If the `QueryData` provides aliasing mutable references to the same component.
    /// - If the entity has been despawned while this `EntityWorldMut` is still alive.
    ///
    /// # Example
    ///
    /// ```
    /// # use bevy_ecs::prelude::*;
    /// #
    /// #[derive(Component)]
    /// struct X(usize);
    /// #[derive(Component)]
    /// struct Y(usize);
    ///
    /// # let mut world = World::default();
    /// let mut entity = world.spawn((X(0), Y(0)));
    /// // Get mutable access to two components at once
    /// let (mut x, mut y) = entity.into_components_mut::<(&mut X, &mut Y)>().unwrap();
    /// *x = X(1);
    /// *y = Y(1);
    /// ```
    ///
    /// ```should_panic
    /// # use bevy_ecs::prelude::*;
    /// #
    /// # #[derive(Component)]
    /// # struct X(usize);
    /// #
    /// # let mut world = World::default();
    /// let mut entity = world.spawn((X(0)));
    /// // This panics, as the `&mut X`s would alias:
    /// entity.into_components_mut::<(&mut X, &mut X)>();
    /// ```
    pub fn into_components_mut<Q: ReleaseStateQueryData>(
        self,
    ) -> Result<Q::Item<'w, 'static>, QueryAccessError> {
        has_conflicts::<Q>(self.world.components())?;
        // SAFETY: we checked that there were not conflicting components above
        unsafe { self.into_mutable().into_components_mut_unchecked::<Q>() }
    }

    /// Consumes `self` and gets access to the component of type `T` with
    /// the world `'w` lifetime for the current entity.
    /// Returns `None` if the entity does not have a component of type `T`.
    ///
    /// # Panics
    ///
    /// If the entity has been despawned while this `EntityWorldMut` is still alive.
    #[inline]
    pub fn into_borrow<T: Component>(self) -> Option<&'w T> {
        self.into_readonly().get()
    }

    /// Gets access to the component of type `T` for the current entity,
    /// including change detection information as a [`Ref`].
    ///
    /// Returns `None` if the entity does not have a component of type `T`.
    ///
    /// # Panics
    ///
    /// If the entity has been despawned while this `EntityWorldMut` is still alive.
    #[inline]
    pub fn get_ref<T: Component>(&self) -> Option<Ref<'_, T>> {
        self.as_readonly().get_ref()
    }

    /// Consumes `self` and gets access to the component of type `T`
    /// with the world `'w` lifetime for the current entity,
    /// including change detection information as a [`Ref`].
    ///
    /// Returns `None` if the entity does not have a component of type `T`.
    ///
    /// # Panics
    ///
    /// If the entity has been despawned while this `EntityWorldMut` is still alive.
    #[inline]
    pub fn into_ref<T: Component>(self) -> Option<Ref<'w, T>> {
        self.into_readonly().get_ref()
    }

    /// Gets mutable access to the component of type `T` for the current entity.
    /// Returns `None` if the entity does not have a component of type `T`.
    ///
    /// # Panics
    ///
    /// If the entity has been despawned while this `EntityWorldMut` is still alive.
    #[inline]
    pub fn get_mut<T: Component<Mutability = Mutable>>(&mut self) -> Option<Mut<'_, T>> {
        self.as_mutable().into_mut()
    }

    /// Temporarily removes a [`Component`] `T` from this [`Entity`] and runs the
    /// provided closure on it, returning the result if `T` was available.
    /// This will trigger the `Remove` and `Replace` component hooks without
    /// causing an archetype move.
    ///
    /// This is most useful with immutable components, where removal and reinsertion
    /// is the only way to modify a value.
    ///
    /// If you do not need to ensure the above hooks are triggered, and your component
    /// is mutable, prefer using [`get_mut`](EntityWorldMut::get_mut).
    ///
    /// # Examples
    ///
    /// ```rust
    /// # use bevy_ecs::prelude::*;
    /// #
    /// #[derive(Component, PartialEq, Eq, Debug)]
    /// #[component(immutable)]
    /// struct Foo(bool);
    ///
    /// # let mut world = World::default();
    /// # world.register_component::<Foo>();
    /// #
    /// # let entity = world.spawn(Foo(false)).id();
    /// #
    /// # let mut entity = world.entity_mut(entity);
    /// #
    /// # assert_eq!(entity.get::<Foo>(), Some(&Foo(false)));
    /// #
    /// entity.modify_component(|foo: &mut Foo| {
    ///     foo.0 = true;
    /// });
    /// #
    /// # assert_eq!(entity.get::<Foo>(), Some(&Foo(true)));
    /// ```
    ///
    /// # Panics
    ///
    /// If the entity has been despawned while this `EntityWorldMut` is still alive.
    #[inline]
    pub fn modify_component<T: Component, R>(&mut self, f: impl FnOnce(&mut T) -> R) -> Option<R> {
        self.assert_not_despawned();

        let result = self
            .world
            .modify_component(self.entity, f)
            .expect("entity access must be valid")?;

        self.update_location();

        Some(result)
    }

    /// Temporarily removes a [`Component`] `T` from this [`Entity`] and runs the
    /// provided closure on it, returning the result if `T` was available.
    /// This will trigger the `Remove` and `Replace` component hooks without
    /// causing an archetype move.
    ///
    /// This is most useful with immutable components, where removal and reinsertion
    /// is the only way to modify a value.
    ///
    /// If you do not need to ensure the above hooks are triggered, and your component
    /// is mutable, prefer using [`get_mut`](EntityWorldMut::get_mut).
    ///
    /// # Panics
    ///
    /// If the entity has been despawned while this `EntityWorldMut` is still alive.
    #[inline]
    pub fn modify_component_by_id<R>(
        &mut self,
        component_id: ComponentId,
        f: impl for<'a> FnOnce(MutUntyped<'a>) -> R,
    ) -> Option<R> {
        self.assert_not_despawned();

        let result = self
            .world
            .modify_component_by_id(self.entity, component_id, f)
            .expect("entity access must be valid")?;

        self.update_location();

        Some(result)
    }

    /// Gets mutable access to the component of type `T` for the current entity.
    /// Returns `None` if the entity does not have a component of type `T`.
    ///
    /// # Safety
    ///
    /// - `T` must be a mutable component
    #[inline]
    pub unsafe fn get_mut_assume_mutable<T: Component>(&mut self) -> Option<Mut<'_, T>> {
        self.as_mutable().into_mut_assume_mutable()
    }

    /// Consumes `self` and gets mutable access to the component of type `T`
    /// with the world `'w` lifetime for the current entity.
    /// Returns `None` if the entity does not have a component of type `T`.
    ///
    /// # Panics
    ///
    /// If the entity has been despawned while this `EntityWorldMut` is still alive.
    #[inline]
    pub fn into_mut<T: Component<Mutability = Mutable>>(self) -> Option<Mut<'w, T>> {
        // SAFETY: consuming `self` implies exclusive access
        unsafe { self.into_unsafe_entity_cell().get_mut() }
    }

    /// Consumes `self` and gets mutable access to the component of type `T`
    /// with the world `'w` lifetime for the current entity.
    /// Returns `None` if the entity does not have a component of type `T`.
    ///
    /// # Panics
    ///
    /// If the entity has been despawned while this `EntityWorldMut` is still alive.
    ///
    /// # Safety
    ///
    /// - `T` must be a mutable component
    #[inline]
    pub unsafe fn into_mut_assume_mutable<T: Component>(self) -> Option<Mut<'w, T>> {
        // SAFETY: consuming `self` implies exclusive access
        unsafe { self.into_unsafe_entity_cell().get_mut_assume_mutable() }
    }

    /// Gets a reference to the resource of the given type
    ///
    /// # Panics
    ///
    /// Panics if the resource does not exist.
    /// Use [`get_resource`](EntityWorldMut::get_resource) instead if you want to handle this case.
    #[inline]
    #[track_caller]
    pub fn resource<R: Resource>(&self) -> &R {
        self.world.resource::<R>()
    }

    /// Gets a mutable reference to the resource of the given type
    ///
    /// # Panics
    ///
    /// Panics if the resource does not exist.
    /// Use [`get_resource_mut`](World::get_resource_mut) instead if you want to handle this case.
    ///
    /// If you want to instead insert a value if the resource does not exist,
    /// use [`get_resource_or_insert_with`](World::get_resource_or_insert_with).
    #[inline]
    #[track_caller]
    pub fn resource_mut<R: Resource>(&mut self) -> Mut<'_, R> {
        self.world.resource_mut::<R>()
    }

    /// Gets a reference to the resource of the given type if it exists
    #[inline]
    pub fn get_resource<R: Resource>(&self) -> Option<&R> {
        self.world.get_resource()
    }

    /// Gets a mutable reference to the resource of the given type if it exists
    #[inline]
    pub fn get_resource_mut<R: Resource>(&mut self) -> Option<Mut<'_, R>> {
        self.world.get_resource_mut()
    }

    /// Temporarily removes the requested resource from the [`World`], runs custom user code,
    /// then re-adds the resource before returning.
    ///
    /// # Panics
    ///
    /// Panics if the resource does not exist.
    /// Use [`try_resource_scope`](Self::try_resource_scope) instead if you want to handle this case.
    ///
    /// See [`World::resource_scope`] for further details.
    #[track_caller]
    pub fn resource_scope<R: Resource, U>(
        &mut self,
        f: impl FnOnce(&mut EntityWorldMut, Mut<R>) -> U,
    ) -> U {
        let id = self.id();
        self.world_scope(|world| {
            world.resource_scope(|world, res| {
                // Acquiring a new EntityWorldMut here and using that instead of `self` is fine because
                // the outer `world_scope` will handle updating our location if it gets changed by the user code
                let mut this = world.entity_mut(id);
                f(&mut this, res)
            })
        })
    }

    /// Temporarily removes the requested resource from the [`World`] if it exists, runs custom user code,
    /// then re-adds the resource before returning. Returns `None` if the resource does not exist in the [`World`].
    ///
    /// See [`World::try_resource_scope`] for further details.
    pub fn try_resource_scope<R: Resource, U>(
        &mut self,
        f: impl FnOnce(&mut EntityWorldMut, Mut<R>) -> U,
    ) -> Option<U> {
        let id = self.id();
        self.world_scope(|world| {
            world.try_resource_scope(|world, res| {
                // Acquiring a new EntityWorldMut here and using that instead of `self` is fine because
                // the outer `world_scope` will handle updating our location if it gets changed by the user code
                let mut this = world.entity_mut(id);
                f(&mut this, res)
            })
        })
    }

    /// Retrieves the change ticks for the given component. This can be useful for implementing change
    /// detection in custom runtimes.
    ///
    /// # Panics
    ///
    /// If the entity has been despawned while this `EntityWorldMut` is still alive.
    #[inline]
    pub fn get_change_ticks<T: Component>(&self) -> Option<ComponentTicks> {
        self.as_readonly().get_change_ticks::<T>()
    }

    /// Retrieves the change ticks for the given [`ComponentId`]. This can be useful for implementing change
    /// detection in custom runtimes.
    ///
    /// **You should prefer to use the typed API [`EntityWorldMut::get_change_ticks`] where possible and only
    /// use this in cases where the actual component types are not known at
    /// compile time.**
    ///
    /// # Panics
    ///
    /// If the entity has been despawned while this `EntityWorldMut` is still alive.
    #[inline]
    pub fn get_change_ticks_by_id(&self, component_id: ComponentId) -> Option<ComponentTicks> {
        self.as_readonly().get_change_ticks_by_id(component_id)
    }

    /// Returns untyped read-only reference(s) to component(s) for the
    /// current entity, based on the given [`ComponentId`]s.
    ///
    /// **You should prefer to use the typed API [`EntityWorldMut::get`] where
    /// possible and only use this in cases where the actual component types
    /// are not known at compile time.**
    ///
    /// Unlike [`EntityWorldMut::get`], this returns untyped reference(s) to
    /// component(s), and it's the job of the caller to ensure the correct
    /// type(s) are dereferenced (if necessary).
    ///
    /// # Errors
    ///
    /// Returns [`EntityComponentError::MissingComponent`] if the entity does
    /// not have a component.
    ///
    /// # Examples
    ///
    /// For examples on how to use this method, see [`EntityRef::get_by_id`].
    ///
    /// # Panics
    ///
    /// If the entity has been despawned while this `EntityWorldMut` is still alive.
    #[inline]
    pub fn get_by_id<F: DynamicComponentFetch>(
        &self,
        component_ids: F,
    ) -> Result<F::Ref<'_>, EntityComponentError> {
        self.as_readonly().get_by_id(component_ids)
    }

    /// Consumes `self` and returns untyped read-only reference(s) to
    /// component(s) with lifetime `'w` for the current entity, based on the
    /// given [`ComponentId`]s.
    ///
    /// **You should prefer to use the typed API [`EntityWorldMut::into_borrow`]
    /// where possible and only use this in cases where the actual component
    /// types are not known at compile time.**
    ///
    /// Unlike [`EntityWorldMut::into_borrow`], this returns untyped reference(s) to
    /// component(s), and it's the job of the caller to ensure the correct
    /// type(s) are dereferenced (if necessary).
    ///
    /// # Errors
    ///
    /// Returns [`EntityComponentError::MissingComponent`] if the entity does
    /// not have a component.
    ///
    /// # Examples
    ///
    /// For examples on how to use this method, see [`EntityRef::get_by_id`].
    ///
    /// # Panics
    ///
    /// If the entity has been despawned while this `EntityWorldMut` is still alive.
    #[inline]
    pub fn into_borrow_by_id<F: DynamicComponentFetch>(
        self,
        component_ids: F,
    ) -> Result<F::Ref<'w>, EntityComponentError> {
        self.into_readonly().get_by_id(component_ids)
    }

    /// Returns [untyped mutable reference(s)](MutUntyped) to component(s) for
    /// the current entity, based on the given [`ComponentId`]s.
    ///
    /// **You should prefer to use the typed API [`EntityWorldMut::get_mut`] where
    /// possible and only use this in cases where the actual component types
    /// are not known at compile time.**
    ///
    /// Unlike [`EntityWorldMut::get_mut`], this returns untyped reference(s) to
    /// component(s), and it's the job of the caller to ensure the correct
    /// type(s) are dereferenced (if necessary).
    ///
    /// # Errors
    ///
    /// - Returns [`EntityComponentError::MissingComponent`] if the entity does
    ///   not have a component.
    /// - Returns [`EntityComponentError::AliasedMutability`] if a component
    ///   is requested multiple times.
    ///
    /// # Examples
    ///
    /// For examples on how to use this method, see [`EntityMut::get_mut_by_id`].
    ///
    /// # Panics
    ///
    /// If the entity has been despawned while this `EntityWorldMut` is still alive.
    #[inline]
    pub fn get_mut_by_id<F: DynamicComponentFetch>(
        &mut self,
        component_ids: F,
    ) -> Result<F::Mut<'_>, EntityComponentError> {
        self.as_mutable().into_mut_by_id(component_ids)
    }

    /// Returns [untyped mutable reference(s)](MutUntyped) to component(s) for
    /// the current entity, based on the given [`ComponentId`]s.
    /// Assumes the given [`ComponentId`]s refer to mutable components.
    ///
    /// **You should prefer to use the typed API [`EntityWorldMut::get_mut_assume_mutable`] where
    /// possible and only use this in cases where the actual component types
    /// are not known at compile time.**
    ///
    /// Unlike [`EntityWorldMut::get_mut_assume_mutable`], this returns untyped reference(s) to
    /// component(s), and it's the job of the caller to ensure the correct
    /// type(s) are dereferenced (if necessary).
    ///
    /// # Errors
    ///
    /// - Returns [`EntityComponentError::MissingComponent`] if the entity does
    ///   not have a component.
    /// - Returns [`EntityComponentError::AliasedMutability`] if a component
    ///   is requested multiple times.
    ///
    /// # Panics
    ///
    /// If the entity has been despawned while this `EntityWorldMut` is still alive.
    ///
    /// # Safety
    /// It is the callers responsibility to ensure that
    /// - the provided [`ComponentId`]s must refer to mutable components.
    #[inline]
    pub unsafe fn get_mut_assume_mutable_by_id<F: DynamicComponentFetch>(
        &mut self,
        component_ids: F,
    ) -> Result<F::Mut<'_>, EntityComponentError> {
        // SAFETY: Upheld by caller
        unsafe {
            self.as_mutable()
                .into_mut_assume_mutable_by_id(component_ids)
        }
    }

    /// Consumes `self` and returns [untyped mutable reference(s)](MutUntyped)
    /// to component(s) with lifetime `'w` for the current entity, based on the
    /// given [`ComponentId`]s.
    ///
    /// **You should prefer to use the typed API [`EntityWorldMut::into_mut`] where
    /// possible and only use this in cases where the actual component types
    /// are not known at compile time.**
    ///
    /// Unlike [`EntityWorldMut::into_mut`], this returns untyped reference(s) to
    /// component(s), and it's the job of the caller to ensure the correct
    /// type(s) are dereferenced (if necessary).
    ///
    /// # Errors
    ///
    /// - Returns [`EntityComponentError::MissingComponent`] if the entity does
    ///   not have a component.
    /// - Returns [`EntityComponentError::AliasedMutability`] if a component
    ///   is requested multiple times.
    ///
    /// # Examples
    ///
    /// For examples on how to use this method, see [`EntityMut::get_mut_by_id`].
    ///
    /// # Panics
    ///
    /// If the entity has been despawned while this `EntityWorldMut` is still alive.
    #[inline]
    pub fn into_mut_by_id<F: DynamicComponentFetch>(
        self,
        component_ids: F,
    ) -> Result<F::Mut<'w>, EntityComponentError> {
        self.into_mutable().into_mut_by_id(component_ids)
    }

    /// Consumes `self` and returns [untyped mutable reference(s)](MutUntyped)
    /// to component(s) with lifetime `'w` for the current entity, based on the
    /// given [`ComponentId`]s.
    /// Assumes the given [`ComponentId`]s refer to mutable components.
    ///
    /// **You should prefer to use the typed API [`EntityWorldMut::into_mut_assume_mutable`] where
    /// possible and only use this in cases where the actual component types
    /// are not known at compile time.**
    ///
    /// Unlike [`EntityWorldMut::into_mut_assume_mutable`], this returns untyped reference(s) to
    /// component(s), and it's the job of the caller to ensure the correct
    /// type(s) are dereferenced (if necessary).
    ///
    /// # Errors
    ///
    /// - Returns [`EntityComponentError::MissingComponent`] if the entity does
    ///   not have a component.
    /// - Returns [`EntityComponentError::AliasedMutability`] if a component
    ///   is requested multiple times.
    ///
    /// # Panics
    ///
    /// If the entity has been despawned while this `EntityWorldMut` is still alive.
    ///
    /// # Safety
    /// It is the callers responsibility to ensure that
    /// - the provided [`ComponentId`]s must refer to mutable components.
    #[inline]
    pub unsafe fn into_mut_assume_mutable_by_id<F: DynamicComponentFetch>(
        self,
        component_ids: F,
    ) -> Result<F::Mut<'w>, EntityComponentError> {
        // SAFETY: Upheld by caller
        unsafe {
            self.into_mutable()
                .into_mut_assume_mutable_by_id(component_ids)
        }
    }

    /// Adds a [`Bundle`] of components to the entity.
    ///
    /// This will overwrite any previous value(s) of the same component type.
    ///
    /// # Panics
    ///
    /// If the entity has been despawned while this `EntityWorldMut` is still alive.
    #[track_caller]
    pub fn insert<T: Bundle>(&mut self, bundle: T) -> &mut Self {
        move_as_ptr!(bundle);
        self.insert_with_caller(
            bundle,
            InsertMode::Replace,
            MaybeLocation::caller(),
            RelationshipHookMode::Run,
        )
    }

    /// Adds a [`Bundle`] of components to the entity.
    /// [`Relationship`](crate::relationship::Relationship) components in the bundle will follow the configuration
    /// in `relationship_hook_mode`.
    ///
    /// This will overwrite any previous value(s) of the same component type.
    ///
    /// # Warning
    ///
    /// This can easily break the integrity of relationships. This is intended to be used for cloning and spawning code internals,
    /// not most user-facing scenarios.
    ///
    /// # Panics
    ///
    /// If the entity has been despawned while this `EntityWorldMut` is still alive.
    #[track_caller]
    pub fn insert_with_relationship_hook_mode<T: Bundle>(
        &mut self,
        bundle: T,
        relationship_hook_mode: RelationshipHookMode,
    ) -> &mut Self {
        move_as_ptr!(bundle);
        self.insert_with_caller(
            bundle,
            InsertMode::Replace,
            MaybeLocation::caller(),
            relationship_hook_mode,
        )
    }

    /// Adds a [`Bundle`] of components to the entity without overwriting.
    ///
    /// This will leave any previous value(s) of the same component type
    /// unchanged.
    ///
    /// # Panics
    ///
    /// If the entity has been despawned while this `EntityWorldMut` is still alive.
    #[track_caller]
    pub fn insert_if_new<T: Bundle>(&mut self, bundle: T) -> &mut Self {
        move_as_ptr!(bundle);
        self.insert_with_caller(
            bundle,
            InsertMode::Keep,
            MaybeLocation::caller(),
            RelationshipHookMode::Run,
        )
    }

    /// Adds a [`Bundle`] of components to the entity.
    #[inline]
    pub(crate) fn insert_with_caller<T: Bundle>(
        &mut self,
        bundle: MovingPtr<'_, T>,
        mode: InsertMode,
        caller: MaybeLocation,
        relationship_hook_mode: RelationshipHookMode,
    ) -> &mut Self {
        let location = self.location();
        let change_tick = self.world.change_tick();
        let mut bundle_inserter =
            BundleInserter::new::<T>(self.world, location.archetype_id, change_tick);
        // SAFETY:
        // - `location` matches current entity and thus must currently exist in the source
        //   archetype for this inserter and its location within the archetype.
        // - `T` matches the type used to create the `BundleInserter`.
        // - `apply_effect` is called exactly once after this function.
        // - The value pointed at by `bundle` is not accessed for anything other than `apply_effect`
        //   and the caller ensures that the value is not accessed or dropped after this function
        //   returns.
        let (bundle, location) = bundle.partial_move(|bundle| unsafe {
            bundle_inserter.insert(
                self.entity,
                location,
                bundle,
                mode,
                caller,
                relationship_hook_mode,
            )
        });
        self.location = Some(location);
        self.world.flush();
        self.update_location();
        // SAFETY:
        // - This is called exactly once after the `BundleInsert::insert` call before returning to safe code.
        // - `bundle` points to the same `B` that `BundleInsert::insert` was called on.
        unsafe { T::apply_effect(bundle, self) };
        self
    }

    /// Inserts a dynamic [`Component`] into the entity.
    ///
    /// This will overwrite any previous value(s) of the same component type.
    ///
    /// You should prefer to use the typed API [`EntityWorldMut::insert`] where possible.
    ///
    /// # Safety
    ///
    /// - [`ComponentId`] must be from the same world as [`EntityWorldMut`]
    /// - [`OwningPtr`] must be a valid reference to the type represented by [`ComponentId`]
    ///
    /// # Panics
    ///
    /// If the entity has been despawned while this `EntityWorldMut` is still alive.
    #[track_caller]
    pub unsafe fn insert_by_id(
        &mut self,
        component_id: ComponentId,
        component: OwningPtr<'_>,
    ) -> &mut Self {
        // SAFETY: Upheld by caller
        unsafe {
            self.insert_by_id_with_caller(
                component_id,
                component,
                InsertMode::Replace,
                MaybeLocation::caller(),
                RelationshipHookMode::Run,
            )
        }
    }

    /// # Safety
    ///
    /// - [`ComponentId`] must be from the same world as [`EntityWorldMut`]
    /// - [`OwningPtr`] must be a valid reference to the type represented by [`ComponentId`]
    #[inline]
    pub(crate) unsafe fn insert_by_id_with_caller(
        &mut self,
        component_id: ComponentId,
        component: OwningPtr<'_>,
        mode: InsertMode,
        caller: MaybeLocation,
        relationship_hook_insert_mode: RelationshipHookMode,
    ) -> &mut Self {
        let location = self.location();
        let change_tick = self.world.change_tick();
        let bundle_id = self.world.bundles.init_component_info(
            &mut self.world.storages,
            &self.world.components,
            component_id,
        );
        let storage_type = self.world.bundles.get_storage_unchecked(bundle_id);

        let bundle_inserter =
            BundleInserter::new_with_id(self.world, location.archetype_id, bundle_id, change_tick);

        self.location = Some(insert_dynamic_bundle(
            bundle_inserter,
            self.entity,
            location,
            Some(component).into_iter(),
            Some(storage_type).iter().cloned(),
            mode,
            caller,
            relationship_hook_insert_mode,
        ));
        self.world.flush();
        self.update_location();
        self
    }

    /// Inserts a dynamic [`Bundle`] into the entity.
    ///
    /// This will overwrite any previous value(s) of the same component type.
    ///
    /// You should prefer to use the typed API [`EntityWorldMut::insert`] where possible.
    /// If your [`Bundle`] only has one component, use the cached API [`EntityWorldMut::insert_by_id`].
    ///
    /// If possible, pass a sorted slice of `ComponentId` to maximize caching potential.
    ///
    /// # Safety
    /// - Each [`ComponentId`] must be from the same world as [`EntityWorldMut`]
    /// - Each [`OwningPtr`] must be a valid reference to the type represented by [`ComponentId`]
    ///
    /// # Panics
    ///
    /// If the entity has been despawned while this `EntityWorldMut` is still alive.
    #[track_caller]
    pub unsafe fn insert_by_ids<'a, I: Iterator<Item = OwningPtr<'a>>>(
        &mut self,
        component_ids: &[ComponentId],
        iter_components: I,
    ) -> &mut Self {
        self.insert_by_ids_internal(component_ids, iter_components, RelationshipHookMode::Run)
    }

    #[track_caller]
    pub(crate) unsafe fn insert_by_ids_internal<'a, I: Iterator<Item = OwningPtr<'a>>>(
        &mut self,
        component_ids: &[ComponentId],
        iter_components: I,
        relationship_hook_insert_mode: RelationshipHookMode,
    ) -> &mut Self {
        let location = self.location();
        let change_tick = self.world.change_tick();
        let bundle_id = self.world.bundles.init_dynamic_info(
            &mut self.world.storages,
            &self.world.components,
            component_ids,
        );
        let mut storage_types =
            core::mem::take(self.world.bundles.get_storages_unchecked(bundle_id));
        let bundle_inserter =
            BundleInserter::new_with_id(self.world, location.archetype_id, bundle_id, change_tick);

        self.location = Some(insert_dynamic_bundle(
            bundle_inserter,
            self.entity,
            location,
            iter_components,
            (*storage_types).iter().cloned(),
            InsertMode::Replace,
            MaybeLocation::caller(),
            relationship_hook_insert_mode,
        ));
        *self.world.bundles.get_storages_unchecked(bundle_id) = core::mem::take(&mut storage_types);
        self.world.flush();
        self.update_location();
        self
    }

    /// Removes all components in the [`Bundle`] from the entity and returns their previous values.
    ///
    /// **Note:** If the entity does not have every component in the bundle, this method will not
    /// remove any of them.
    ///
    /// # Panics
    ///
    /// If the entity has been despawned while this `EntityWorldMut` is still alive.
    #[must_use]
    #[track_caller]
    pub fn take<T: Bundle + BundleFromComponents>(&mut self) -> Option<T> {
        let location = self.location();
        let entity = self.entity;

        let mut remover =
            // SAFETY: The archetype id must be valid since this entity is in it.
            unsafe { BundleRemover::new::<T>(self.world, location.archetype_id, true) }?;
        // SAFETY: The passed location has the sane archetype as the remover, since they came from the same location.
        let (new_location, result) = unsafe {
            remover.remove(
                entity,
                location,
                MaybeLocation::caller(),
                |sets, table, components, bundle_components| {
                    let mut bundle_components = bundle_components.iter().copied();
                    (
                        false,
                        T::from_components(&mut (sets, table), &mut |(sets, table)| {
                            let component_id = bundle_components.next().unwrap();
                            // SAFETY: the component existed to be removed, so its id must be valid.
                            let component_info = components.get_info_unchecked(component_id);
                            match component_info.storage_type() {
                                StorageType::Table => {
                                    table
                                        .as_mut()
                                        // SAFETY: The table must be valid if the component is in it.
                                        .debug_checked_unwrap()
                                        // SAFETY: The remover is cleaning this up.
                                        .take_component(component_id, location.table_row)
                                }
                                StorageType::SparseSet => sets
                                    .get_mut(component_id)
                                    .unwrap()
                                    .remove_and_forget(entity)
                                    .unwrap(),
                            }
                        }),
                    )
                },
            )
        };
        self.location = Some(new_location);

        self.world.flush();
        self.update_location();
        Some(result)
    }

    /// Removes any components in the [`Bundle`] from the entity.
    ///
    /// See [`EntityCommands::remove`](crate::system::EntityCommands::remove) for more details.
    ///
    /// # Panics
    ///
    /// If the entity has been despawned while this `EntityWorldMut` is still alive.
    #[track_caller]
    pub fn remove<T: Bundle>(&mut self) -> &mut Self {
        self.remove_with_caller::<T>(MaybeLocation::caller())
    }

    #[inline]
    pub(crate) fn remove_with_caller<T: Bundle>(&mut self, caller: MaybeLocation) -> &mut Self {
        let location = self.location();

        let Some(mut remover) =
            // SAFETY: The archetype id must be valid since this entity is in it.
            (unsafe { BundleRemover::new::<T>(self.world, location.archetype_id, false) })
        else {
            return self;
        };
        // SAFETY: The remover archetype came from the passed location and the removal can not fail.
        let new_location = unsafe {
            remover.remove(
                self.entity,
                location,
                caller,
                BundleRemover::empty_pre_remove,
            )
        }
        .0;

        self.location = Some(new_location);
        self.world.flush();
        self.update_location();
        self
    }

    /// Removes all components in the [`Bundle`] and remove all required components for each component in the bundle
    ///
    /// # Panics
    ///
    /// If the entity has been despawned while this `EntityWorldMut` is still alive.
    #[track_caller]
    pub fn remove_with_requires<T: Bundle>(&mut self) -> &mut Self {
        self.remove_with_requires_with_caller::<T>(MaybeLocation::caller())
    }

    pub(crate) fn remove_with_requires_with_caller<T: Bundle>(
        &mut self,
        caller: MaybeLocation,
    ) -> &mut Self {
        let location = self.location();
        let bundle_id = self.world.register_contributed_bundle_info::<T>();

        // SAFETY: We just created the bundle, and the archetype is valid, since we are in it.
        let Some(mut remover) = (unsafe {
            BundleRemover::new_with_id(self.world, location.archetype_id, bundle_id, false)
        }) else {
            return self;
        };
        // SAFETY: The remover archetype came from the passed location and the removal can not fail.
        let new_location = unsafe {
            remover.remove(
                self.entity,
                location,
                caller,
                BundleRemover::empty_pre_remove,
            )
        }
        .0;

        self.location = Some(new_location);
        self.world.flush();
        self.update_location();
        self
    }

    /// Removes any components except those in the [`Bundle`] (and its Required Components) from the entity.
    ///
    /// See [`EntityCommands::retain`](crate::system::EntityCommands::retain) for more details.
    ///
    /// # Panics
    ///
    /// If the entity has been despawned while this `EntityWorldMut` is still alive.
    #[track_caller]
    pub fn retain<T: Bundle>(&mut self) -> &mut Self {
        self.retain_with_caller::<T>(MaybeLocation::caller())
    }

    #[inline]
    pub(crate) fn retain_with_caller<T: Bundle>(&mut self, caller: MaybeLocation) -> &mut Self {
        let old_location = self.location();
        let retained_bundle = self.world.register_bundle_info::<T>();
        let archetypes = &mut self.world.archetypes;

        // SAFETY: `retained_bundle` exists as we just registered it.
        let retained_bundle_info = unsafe { self.world.bundles.get_unchecked(retained_bundle) };
        let old_archetype = &mut archetypes[old_location.archetype_id];

        // PERF: this could be stored in an Archetype Edge
        let to_remove = &old_archetype
            .iter_components()
            .filter(|c| !retained_bundle_info.contributed_components().contains(c))
            .collect::<Vec<_>>();
        let remove_bundle = self.world.bundles.init_dynamic_info(
            &mut self.world.storages,
            &self.world.components,
            to_remove,
        );

        // SAFETY: We just created the bundle, and the archetype is valid, since we are in it.
        let Some(mut remover) = (unsafe {
            BundleRemover::new_with_id(self.world, old_location.archetype_id, remove_bundle, false)
        }) else {
            return self;
        };
        // SAFETY: The remover archetype came from the passed location and the removal can not fail.
        let new_location = unsafe {
            remover.remove(
                self.entity,
                old_location,
                caller,
                BundleRemover::empty_pre_remove,
            )
        }
        .0;

        self.location = Some(new_location);
        self.world.flush();
        self.update_location();
        self
    }

    /// Removes a dynamic [`Component`] from the entity if it exists.
    ///
    /// You should prefer to use the typed API [`EntityWorldMut::remove`] where possible.
    ///
    /// # Panics
    ///
    /// Panics if the provided [`ComponentId`] does not exist in the [`World`] or if the
    /// entity has been despawned while this `EntityWorldMut` is still alive.
    #[track_caller]
    pub fn remove_by_id(&mut self, component_id: ComponentId) -> &mut Self {
        self.remove_by_id_with_caller(component_id, MaybeLocation::caller())
    }

    #[inline]
    pub(crate) fn remove_by_id_with_caller(
        &mut self,
        component_id: ComponentId,
        caller: MaybeLocation,
    ) -> &mut Self {
        let location = self.location();
        let components = &mut self.world.components;

        let bundle_id = self.world.bundles.init_component_info(
            &mut self.world.storages,
            components,
            component_id,
        );

        // SAFETY: We just created the bundle, and the archetype is valid, since we are in it.
        let Some(mut remover) = (unsafe {
            BundleRemover::new_with_id(self.world, location.archetype_id, bundle_id, false)
        }) else {
            return self;
        };
        // SAFETY: The remover archetype came from the passed location and the removal can not fail.
        let new_location = unsafe {
            remover.remove(
                self.entity,
                location,
                caller,
                BundleRemover::empty_pre_remove,
            )
        }
        .0;

        self.location = Some(new_location);
        self.world.flush();
        self.update_location();
        self
    }

    /// Removes a dynamic bundle from the entity if it exists.
    ///
    /// You should prefer to use the typed API [`EntityWorldMut::remove`] where possible.
    ///
    /// # Panics
    ///
    /// Panics if any of the provided [`ComponentId`]s do not exist in the [`World`] or if the
    /// entity has been despawned while this `EntityWorldMut` is still alive.
    #[track_caller]
    pub fn remove_by_ids(&mut self, component_ids: &[ComponentId]) -> &mut Self {
        self.remove_by_ids_with_caller(
            component_ids,
            MaybeLocation::caller(),
            RelationshipHookMode::Run,
            BundleRemover::empty_pre_remove,
        )
    }

    #[inline]
    pub(crate) fn remove_by_ids_with_caller<T: 'static>(
        &mut self,
        component_ids: &[ComponentId],
        caller: MaybeLocation,
        relationship_hook_mode: RelationshipHookMode,
        pre_remove: impl FnOnce(
            &mut SparseSets,
            Option<&mut Table>,
            &Components,
            &[ComponentId],
        ) -> (bool, T),
    ) -> &mut Self {
        let location = self.location();
        let components = &mut self.world.components;

        let bundle_id = self.world.bundles.init_dynamic_info(
            &mut self.world.storages,
            components,
            component_ids,
        );

        // SAFETY: We just created the bundle, and the archetype is valid, since we are in it.
        let Some(mut remover) = (unsafe {
            BundleRemover::new_with_id(self.world, location.archetype_id, bundle_id, false)
        }) else {
            return self;
        };
        remover.relationship_hook_mode = relationship_hook_mode;
        // SAFETY: The remover archetype came from the passed location and the removal can not fail.
        let new_location = unsafe { remover.remove(self.entity, location, caller, pre_remove) }.0;

        self.location = Some(new_location);
        self.world.flush();
        self.update_location();
        self
    }

    /// Removes all components associated with the entity.
    ///
    /// # Panics
    ///
    /// If the entity has been despawned while this `EntityWorldMut` is still alive.
    #[track_caller]
    pub fn clear(&mut self) -> &mut Self {
        self.clear_with_caller(MaybeLocation::caller())
    }

    #[inline]
    pub(crate) fn clear_with_caller(&mut self, caller: MaybeLocation) -> &mut Self {
        let location = self.location();
        // PERF: this should not be necessary
        let component_ids: Vec<ComponentId> = self.archetype().components().to_vec();
        let components = &mut self.world.components;

        let bundle_id = self.world.bundles.init_dynamic_info(
            &mut self.world.storages,
            components,
            component_ids.as_slice(),
        );

        // SAFETY: We just created the bundle, and the archetype is valid, since we are in it.
        let Some(mut remover) = (unsafe {
            BundleRemover::new_with_id(self.world, location.archetype_id, bundle_id, false)
        }) else {
            return self;
        };
        // SAFETY: The remover archetype came from the passed location and the removal can not fail.
        let new_location = unsafe {
            remover.remove(
                self.entity,
                location,
                caller,
                BundleRemover::empty_pre_remove,
            )
        }
        .0;

        self.location = Some(new_location);
        self.world.flush();
        self.update_location();
        self
    }

    /// Despawns the entity without freeing it to the allocator.
    /// This returns the new [`Entity`], which you must manage.
    /// Note that this still increases the generation to differentiate different spawns of the same row.
    ///
    /// Additionally, keep in mind the limitations documented in the type-level docs.
    /// Unless you have full knowledge of this [`EntityWorldMut`]'s lifetime,
    /// you may not assume that nothing else has taken responsibility of this [`Entity`].
    /// If you are not careful, this could cause a double free.
    ///
    /// This may be later [`spawn_at`](World::spawn_at).
    /// See [`World::despawn_no_free`] for details and usage examples.
    #[track_caller]
    pub fn despawn_no_free(mut self) -> Entity {
        self.despawn_no_free_with_caller(MaybeLocation::caller());
        self.entity
    }

    /// This despawns this entity if it is currently spawned, storing the new [`EntityGeneration`](crate::entity::EntityGeneration) in [`Self::entity`] but not freeing it.
    pub(crate) fn despawn_no_free_with_caller(&mut self, caller: MaybeLocation) {
        // setup
        let Some(location) = self.location else {
            // If there is no location, we are already despawned
            return;
        };
        let archetype = &self.world.archetypes[location.archetype_id];

        // SAFETY: Archetype cannot be mutably aliased by DeferredWorld
        let (archetype, mut deferred_world) = unsafe {
            let archetype: *const Archetype = archetype;
            let world = self.world.as_unsafe_world_cell();
            (&*archetype, world.into_deferred())
        };

        // SAFETY: All components in the archetype exist in world
        unsafe {
            if archetype.has_despawn_observer() {
                // SAFETY: the DESPAWN event_key corresponds to the Despawn event's type
                deferred_world.trigger_raw(
                    DESPAWN,
                    &mut Despawn {
                        entity: self.entity,
                    },
                    &mut EntityComponentsTrigger {
                        components: archetype.components(),
                    },
                    caller,
                );
            }
            deferred_world.trigger_on_despawn(
                archetype,
                self.entity,
                archetype.iter_components(),
                caller,
            );
            if archetype.has_replace_observer() {
                // SAFETY: the REPLACE event_key corresponds to the Replace event's type
                deferred_world.trigger_raw(
                    REPLACE,
                    &mut Replace {
                        entity: self.entity,
                    },
                    &mut EntityComponentsTrigger {
                        components: archetype.components(),
                    },
                    caller,
                );
            }
            deferred_world.trigger_on_replace(
                archetype,
                self.entity,
                archetype.iter_components(),
                caller,
                RelationshipHookMode::Run,
            );
            if archetype.has_remove_observer() {
                // SAFETY: the REMOVE event_key corresponds to the Remove event's type
                deferred_world.trigger_raw(
                    REMOVE,
                    &mut Remove {
                        entity: self.entity,
                    },
                    &mut EntityComponentsTrigger {
                        components: archetype.components(),
                    },
                    caller,
                );
            }
            deferred_world.trigger_on_remove(
                archetype,
                self.entity,
                archetype.iter_components(),
                caller,
            );
        }

        // do the despawn
        let change_tick = self.world.change_tick();
        for component_id in archetype.components() {
            self.world
                .removed_components
                .write(*component_id, self.entity);
        }
        // SAFETY: Since we had a location, and it was valid, this is safe.
        unsafe {
            let was_at = self
                .world
                .entities
                .update_existing_location(self.entity.index(), None);
            debug_assert_eq!(was_at, Some(location));
            self.world
                .entities
                .mark_spawned_or_despawned(self.entity.index(), caller, change_tick);
        }

        let table_row;
        let moved_entity;
        {
            let archetype = &mut self.world.archetypes[location.archetype_id];
            let remove_result = archetype.swap_remove(location.archetype_row);
            if let Some(swapped_entity) = remove_result.swapped_entity {
                let swapped_location = self.world.entities.get_spawned(swapped_entity).unwrap();
                // SAFETY: swapped_entity is valid and the swapped entity's components are
                // moved to the new location immediately after.
                unsafe {
                    self.world.entities.update_existing_location(
                        swapped_entity.index(),
                        Some(EntityLocation {
                            archetype_id: swapped_location.archetype_id,
                            archetype_row: location.archetype_row,
                            table_id: swapped_location.table_id,
                            table_row: swapped_location.table_row,
                        }),
                    );
                }
            }
            table_row = remove_result.table_row;

            for component_id in archetype.sparse_set_components() {
                // set must have existed for the component to be added.
                let sparse_set = self
                    .world
                    .storages
                    .sparse_sets
                    .get_mut(component_id)
                    .unwrap();
                sparse_set.remove(self.entity);
            }
            // SAFETY: table rows stored in archetypes always exist
            moved_entity = unsafe {
                self.world.storages.tables[archetype.table_id()].swap_remove_unchecked(table_row)
            };
        };

        // Handle displaced entity
        if let Some(moved_entity) = moved_entity {
            let moved_location = self.world.entities.get_spawned(moved_entity).unwrap();
            // SAFETY: `moved_entity` is valid and the provided `EntityLocation` accurately reflects
            //         the current location of the entity and its component data.
            unsafe {
                self.world.entities.update_existing_location(
                    moved_entity.index(),
                    Some(EntityLocation {
                        archetype_id: moved_location.archetype_id,
                        archetype_row: moved_location.archetype_row,
                        table_id: moved_location.table_id,
                        table_row,
                    }),
                );
            }
            self.world.archetypes[moved_location.archetype_id]
                .set_entity_table_row(moved_location.archetype_row, table_row);
        }

        // finish
        // SAFETY: We just despawned it.
        self.entity = unsafe { self.world.entities.mark_free(self.entity.index(), 1) };
        self.world.flush();
    }

    /// Despawns the current entity.
    ///
    /// See [`World::despawn`] for more details.
    ///
    /// # Note
    ///
    /// This will also despawn any [`Children`](crate::hierarchy::Children) entities, and any other [`RelationshipTarget`](crate::relationship::RelationshipTarget) that is configured
    /// to despawn descendants. This results in "recursive despawn" behavior.
    #[track_caller]
    pub fn despawn(self) {
        self.despawn_with_caller(MaybeLocation::caller());
    }

    pub(crate) fn despawn_with_caller(mut self, caller: MaybeLocation) {
        self.despawn_no_free_with_caller(caller);
        if let Ok(None) = self.world.entities.get(self.entity) {
            self.world.allocator.free(self.entity);
        }

        // Otherwise:
        // A command must have reconstructed it (had a location); don't free
        // A command must have already despawned it (err) or otherwise made the free unneeded (ex by spawning and despawning in commands); don't free
    }

    /// Ensures any commands triggered by the actions of Self are applied, equivalent to [`World::flush`]
    pub fn flush(self) -> Entity {
        self.world.flush();
        self.entity
    }

    /// Gets read-only access to the world that the current entity belongs to.
    #[inline]
    pub fn world(&self) -> &World {
        self.world
    }

    /// Returns this entity's world.
    ///
    /// See [`EntityWorldMut::world_scope`] or [`EntityWorldMut::into_world_mut`] for a safe alternative.
    ///
    /// # Safety
    /// Caller must not modify the world in a way that changes the current entity's location
    /// If the caller _does_ do something that could change the location, `self.update_location()`
    /// must be called before using any other methods on this [`EntityWorldMut`].
    #[inline]
    pub unsafe fn world_mut(&mut self) -> &mut World {
        self.world
    }

    /// Returns this entity's [`World`], consuming itself.
    #[inline]
    pub fn into_world_mut(self) -> &'w mut World {
        self.world
    }

    /// Gives mutable access to this entity's [`World`] in a temporary scope.
    /// This is a safe alternative to using [`EntityWorldMut::world_mut`].
    ///
    /// # Examples
    ///
    /// ```
    /// # use bevy_ecs::prelude::*;
    /// #[derive(Resource, Default, Clone, Copy)]
    /// struct R(u32);
    ///
    /// # let mut world = World::new();
    /// # world.init_resource::<R>();
    /// # let mut entity = world.spawn_empty();
    /// // This closure gives us temporary access to the world.
    /// let new_r = entity.world_scope(|world: &mut World| {
    ///     // Mutate the world while we have access to it.
    ///     let mut r = world.resource_mut::<R>();
    ///     r.0 += 1;
    ///
    ///     // Return a value from the world before giving it back to the `EntityWorldMut`.
    ///     *r
    /// });
    /// # assert_eq!(new_r.0, 1);
    /// ```
    pub fn world_scope<U>(&mut self, f: impl FnOnce(&mut World) -> U) -> U {
        struct Guard<'w, 'a> {
            entity_mut: &'a mut EntityWorldMut<'w>,
        }

        impl Drop for Guard<'_, '_> {
            #[inline]
            fn drop(&mut self) {
                self.entity_mut.update_location();
            }
        }

        // When `guard` is dropped at the end of this scope,
        // it will update the cached `EntityLocation` for this instance.
        // This will run even in case the closure `f` unwinds.
        let guard = Guard { entity_mut: self };
        f(guard.entity_mut.world)
    }

    /// Updates the internal entity location to match the current location in the internal
    /// [`World`].
    ///
    /// This is *only* required when using the unsafe function [`EntityWorldMut::world_mut`],
    /// which enables the location to change.
    ///
    /// Note that if the entity is not spawned for any reason,
    /// this will have a location of `None`, leading some methods to panic.
    pub fn update_location(&mut self) {
        self.location = self.world.entities().get_spawned(self.entity).ok();
    }

    /// Returns if the entity has been despawned.
    ///
    /// Normally it shouldn't be needed to explicitly check if the entity has been despawned
    /// between commands as this shouldn't happen. However, for some special cases where it
    /// is known that a hook or an observer might despawn the entity while a [`EntityWorldMut`]
    /// reference is still held, this method can be used to check if the entity is still alive
    /// to avoid panicking when calling further methods.
    #[inline]
    pub fn is_despawned(&self) -> bool {
        self.location.is_none()
    }

    /// Gets an Entry into the world for this entity and component for in-place manipulation.
    ///
    /// The type parameter specifies which component to get.
    ///
    /// # Examples
    ///
    /// ```
    /// # use bevy_ecs::prelude::*;
    /// #[derive(Component, Default, Clone, Copy, Debug, PartialEq)]
    /// struct Comp(u32);
    ///
    /// # let mut world = World::new();
    /// let mut entity = world.spawn_empty();
    /// entity.entry().or_insert_with(|| Comp(4));
    /// # let entity_id = entity.id();
    /// assert_eq!(world.query::<&Comp>().single(&world).unwrap().0, 4);
    ///
    /// # let mut entity = world.get_entity_mut(entity_id).unwrap();
    /// entity.entry::<Comp>().and_modify(|mut c| c.0 += 1);
    /// assert_eq!(world.query::<&Comp>().single(&world).unwrap().0, 5);
    /// ```
    ///
    /// # Panics
    ///
    /// If the entity has been despawned while this `EntityWorldMut` is still alive.
    pub fn entry<'a, T: Component>(&'a mut self) -> ComponentEntry<'w, 'a, T> {
        if self.contains::<T>() {
            ComponentEntry::Occupied(OccupiedComponentEntry {
                entity_world: self,
                _marker: PhantomData,
            })
        } else {
            ComponentEntry::Vacant(VacantComponentEntry {
                entity_world: self,
                _marker: PhantomData,
            })
        }
    }

    /// Creates an [`Observer`] watching for an [`EntityEvent`] of type `E` whose [`EntityEvent::event_target`]
    /// targets this entity.
    ///
    /// # Panics
    ///
    /// If the entity has been despawned while this `EntityWorldMut` is still alive.
    ///
    /// Panics if the given system is an exclusive system.
    #[track_caller]
    pub fn observe<E: EntityEvent, B: Bundle, M>(
        &mut self,
        observer: impl IntoObserverSystem<E, B, M>,
    ) -> &mut Self {
        self.observe_with_caller(observer, MaybeLocation::caller())
    }

    pub(crate) fn observe_with_caller<E: EntityEvent, B: Bundle, M>(
        &mut self,
        observer: impl IntoObserverSystem<E, B, M>,
        caller: MaybeLocation,
    ) -> &mut Self {
        self.assert_not_despawned();
        let bundle = Observer::new(observer).with_entity(self.entity);
        move_as_ptr!(bundle);
        self.world.spawn_with_caller(bundle, caller);
        self.world.flush();
        self.update_location();
        self
    }

    /// Clones parts of an entity (components, observers, etc.) onto another entity,
    /// configured through [`EntityClonerBuilder`].
    ///
    /// The other entity will receive all the components of the original that implement
    /// [`Clone`] or [`Reflect`](bevy_reflect::Reflect) except those that are
    /// [denied](EntityClonerBuilder::deny) in the `config`.
    ///
    /// # Example
    ///
    /// ```
    /// # use bevy_ecs::prelude::*;
    /// # #[derive(Component, Clone, PartialEq, Debug)]
    /// # struct ComponentA;
    /// # #[derive(Component, Clone, PartialEq, Debug)]
    /// # struct ComponentB;
    /// # let mut world = World::new();
    /// # let entity = world.spawn((ComponentA, ComponentB)).id();
    /// # let target = world.spawn_empty().id();
    /// // Clone all components except ComponentA onto the target.
    /// world.entity_mut(entity).clone_with_opt_out(target, |builder| {
    ///     builder.deny::<ComponentA>();
    /// });
    /// # assert_eq!(world.get::<ComponentA>(target), None);
    /// # assert_eq!(world.get::<ComponentB>(target), Some(&ComponentB));
    /// ```
    ///
    /// See [`EntityClonerBuilder<OptOut>`] for more options.
    ///
    /// # Panics
    ///
    /// - If this entity has been despawned while this `EntityWorldMut` is still alive.
    /// - If the target entity does not exist.
    pub fn clone_with_opt_out(
        &mut self,
        target: Entity,
        config: impl FnOnce(&mut EntityClonerBuilder<OptOut>) + Send + Sync + 'static,
    ) -> &mut Self {
        self.assert_not_despawned();

        let mut builder = EntityCloner::build_opt_out(self.world);
        config(&mut builder);
        builder.clone_entity(self.entity, target);

        self.world.flush();
        self.update_location();
        self
    }

    /// Clones parts of an entity (components, observers, etc.) onto another entity,
    /// configured through [`EntityClonerBuilder`].
    ///
    /// The other entity will receive only the components of the original that implement
    /// [`Clone`] or [`Reflect`](bevy_reflect::Reflect) and are
    /// [allowed](EntityClonerBuilder::allow) in the `config`.
    ///
    /// # Example
    ///
    /// ```
    /// # use bevy_ecs::prelude::*;
    /// # #[derive(Component, Clone, PartialEq, Debug)]
    /// # struct ComponentA;
    /// # #[derive(Component, Clone, PartialEq, Debug)]
    /// # struct ComponentB;
    /// # let mut world = World::new();
    /// # let entity = world.spawn((ComponentA, ComponentB)).id();
    /// # let target = world.spawn_empty().id();
    /// // Clone only ComponentA onto the target.
    /// world.entity_mut(entity).clone_with_opt_in(target, |builder| {
    ///     builder.allow::<ComponentA>();
    /// });
    /// # assert_eq!(world.get::<ComponentA>(target), Some(&ComponentA));
    /// # assert_eq!(world.get::<ComponentB>(target), None);
    /// ```
    ///
    /// See [`EntityClonerBuilder<OptIn>`] for more options.
    ///
    /// # Panics
    ///
    /// - If this entity has been despawned while this `EntityWorldMut` is still alive.
    /// - If the target entity does not exist.
    pub fn clone_with_opt_in(
        &mut self,
        target: Entity,
        config: impl FnOnce(&mut EntityClonerBuilder<OptIn>) + Send + Sync + 'static,
    ) -> &mut Self {
        self.assert_not_despawned();

        let mut builder = EntityCloner::build_opt_in(self.world);
        config(&mut builder);
        builder.clone_entity(self.entity, target);

        self.world.flush();
        self.update_location();
        self
    }

    /// Spawns a clone of this entity and returns the [`Entity`] of the clone.
    ///
    /// The clone will receive all the components of the original that implement
    /// [`Clone`] or [`Reflect`](bevy_reflect::Reflect).
    ///
    /// To configure cloning behavior (such as only cloning certain components),
    /// use [`EntityWorldMut::clone_and_spawn_with_opt_out`]/
    /// [`opt_in`](`EntityWorldMut::clone_and_spawn_with_opt_in`).
    ///
    /// # Panics
    ///
    /// If this entity has been despawned while this `EntityWorldMut` is still alive.
    pub fn clone_and_spawn(&mut self) -> Entity {
        self.clone_and_spawn_with_opt_out(|_| {})
    }

    /// Spawns a clone of this entity and allows configuring cloning behavior
    /// using [`EntityClonerBuilder`], returning the [`Entity`] of the clone.
    ///
    /// The clone will receive all the components of the original that implement
    /// [`Clone`] or [`Reflect`](bevy_reflect::Reflect) except those that are
    /// [denied](EntityClonerBuilder::deny) in the `config`.
    ///
    /// # Example
    ///
    /// ```
    /// # use bevy_ecs::prelude::*;
    /// # let mut world = World::new();
    /// # let entity = world.spawn((ComponentA, ComponentB)).id();
    /// # #[derive(Component, Clone, PartialEq, Debug)]
    /// # struct ComponentA;
    /// # #[derive(Component, Clone, PartialEq, Debug)]
    /// # struct ComponentB;
    /// // Create a clone of an entity but without ComponentA.
    /// let entity_clone = world.entity_mut(entity).clone_and_spawn_with_opt_out(|builder| {
    ///     builder.deny::<ComponentA>();
    /// });
    /// # assert_eq!(world.get::<ComponentA>(entity_clone), None);
    /// # assert_eq!(world.get::<ComponentB>(entity_clone), Some(&ComponentB));
    /// ```
    ///
    /// See [`EntityClonerBuilder<OptOut>`] for more options.
    ///
    /// # Panics
    ///
    /// If this entity has been despawned while this `EntityWorldMut` is still alive.
    pub fn clone_and_spawn_with_opt_out(
        &mut self,
        config: impl FnOnce(&mut EntityClonerBuilder<OptOut>) + Send + Sync + 'static,
    ) -> Entity {
        self.assert_not_despawned();
        let entity_clone = self.world.spawn_empty().id();

        let mut builder = EntityCloner::build_opt_out(self.world);
        config(&mut builder);
        builder.clone_entity(self.entity, entity_clone);

        self.world.flush();
        self.update_location();
        entity_clone
    }

    /// Spawns a clone of this entity and allows configuring cloning behavior
    /// using [`EntityClonerBuilder`], returning the [`Entity`] of the clone.
    ///
    /// The clone will receive only the components of the original that implement
    /// [`Clone`] or [`Reflect`](bevy_reflect::Reflect) and are
    /// [allowed](EntityClonerBuilder::allow) in the `config`.
    ///
    /// # Example
    ///
    /// ```
    /// # use bevy_ecs::prelude::*;
    /// # let mut world = World::new();
    /// # let entity = world.spawn((ComponentA, ComponentB)).id();
    /// # #[derive(Component, Clone, PartialEq, Debug)]
    /// # struct ComponentA;
    /// # #[derive(Component, Clone, PartialEq, Debug)]
    /// # struct ComponentB;
    /// // Create a clone of an entity but only with ComponentA.
    /// let entity_clone = world.entity_mut(entity).clone_and_spawn_with_opt_in(|builder| {
    ///     builder.allow::<ComponentA>();
    /// });
    /// # assert_eq!(world.get::<ComponentA>(entity_clone), Some(&ComponentA));
    /// # assert_eq!(world.get::<ComponentB>(entity_clone), None);
    /// ```
    ///
    /// See [`EntityClonerBuilder<OptIn>`] for more options.
    ///
    /// # Panics
    ///
    /// If this entity has been despawned while this `EntityWorldMut` is still alive.
    pub fn clone_and_spawn_with_opt_in(
        &mut self,
        config: impl FnOnce(&mut EntityClonerBuilder<OptIn>) + Send + Sync + 'static,
    ) -> Entity {
        self.assert_not_despawned();
        let entity_clone = self.world.spawn_empty().id();

        let mut builder = EntityCloner::build_opt_in(self.world);
        config(&mut builder);
        builder.clone_entity(self.entity, entity_clone);

        self.world.flush();
        self.update_location();
        entity_clone
    }

    /// Clones the specified components of this entity and inserts them into another entity.
    ///
    /// Components can only be cloned if they implement
    /// [`Clone`] or [`Reflect`](bevy_reflect::Reflect).
    ///
    /// # Panics
    ///
    /// - If this entity has been despawned while this `EntityWorldMut` is still alive.
    /// - If the target entity does not exist.
    pub fn clone_components<B: Bundle>(&mut self, target: Entity) -> &mut Self {
        self.assert_not_despawned();

        EntityCloner::build_opt_in(self.world)
            .allow::<B>()
            .clone_entity(self.entity, target);

        self.world.flush();
        self.update_location();
        self
    }

    /// Clones the specified components of this entity and inserts them into another entity,
    /// then removes the components from this entity.
    ///
    /// Components can only be cloned if they implement
    /// [`Clone`] or [`Reflect`](bevy_reflect::Reflect).
    ///
    /// # Panics
    ///
    /// - If this entity has been despawned while this `EntityWorldMut` is still alive.
    /// - If the target entity does not exist.
    pub fn move_components<B: Bundle>(&mut self, target: Entity) -> &mut Self {
        self.assert_not_despawned();

        EntityCloner::build_opt_in(self.world)
            .allow::<B>()
            .move_components(true)
            .clone_entity(self.entity, target);

        self.world.flush();
        self.update_location();
        self
    }

    /// Returns the source code location from which this entity has last been spawned.
    pub fn spawned_by(&self) -> MaybeLocation {
        self.world()
            .entities()
            .entity_get_spawned_or_despawned_by(self.entity)
            .map(|location| location.unwrap())
    }

    /// Returns the [`Tick`] at which this entity has last been spawned.
    pub fn spawn_tick(&self) -> Tick {
        self.assert_not_despawned();

        // SAFETY: entity being alive was asserted
        unsafe {
            self.world()
                .entities()
                .entity_get_spawned_or_despawned_unchecked(self.entity)
                .1
        }
    }

    /// Reborrows this entity in a temporary scope.
    /// This is useful for executing a function that requires a `EntityWorldMut`
    /// but you do not want to move out the entity ownership.
    pub fn reborrow_scope<U>(&mut self, f: impl FnOnce(EntityWorldMut) -> U) -> U {
        let Self {
            entity, location, ..
        } = *self;
        self.world_scope(move |world| {
            f(EntityWorldMut {
                world,
                entity,
                location,
            })
        })
    }

    /// Passes the current entity into the given function, and triggers the [`EntityEvent`] returned by that function.
    /// See [`EntityCommands::trigger`] for usage examples
    ///
    /// [`EntityCommands::trigger`]: crate::system::EntityCommands::trigger
    #[track_caller]
    pub fn trigger<'t, E: EntityEvent<Trigger<'t>: Default>>(
        &mut self,
        event_fn: impl FnOnce(Entity) -> E,
    ) -> &mut Self {
        let mut event = (event_fn)(self.entity);
        let caller = MaybeLocation::caller();
        self.world_scope(|world| {
            world.trigger_ref_with_caller(
                &mut event,
                &mut <E::Trigger<'_> as Default>::default(),
                caller,
            );
        });
        self
    }
}

impl<'w> From<EntityWorldMut<'w>> for EntityRef<'w> {
    fn from(entity: EntityWorldMut<'w>) -> EntityRef<'w> {
        // SAFETY:
        // - `EntityWorldMut` guarantees exclusive access to the entire world.
        unsafe { EntityRef::new(entity.into_unsafe_entity_cell()) }
    }
}

impl<'a> From<&'a EntityWorldMut<'_>> for EntityRef<'a> {
    fn from(entity: &'a EntityWorldMut<'_>) -> Self {
        // SAFETY:
        // - `EntityWorldMut` guarantees exclusive access to the entire world.
        // - `&entity` ensures no mutable accesses are active.
        unsafe { EntityRef::new(entity.as_unsafe_entity_cell_readonly()) }
    }
}

impl<'w> From<EntityWorldMut<'w>> for EntityMut<'w> {
    fn from(entity: EntityWorldMut<'w>) -> Self {
        // SAFETY: `EntityWorldMut` guarantees exclusive access to the entire world.
        unsafe { EntityMut::new(entity.into_unsafe_entity_cell()) }
    }
}

impl<'a> From<&'a mut EntityWorldMut<'_>> for EntityMut<'a> {
    #[inline]
    fn from(entity: &'a mut EntityWorldMut<'_>) -> Self {
        // SAFETY: `EntityWorldMut` guarantees exclusive access to the entire world.
        unsafe { EntityMut::new(entity.as_unsafe_entity_cell()) }
    }
}

impl<'a> From<EntityWorldMut<'a>> for FilteredEntityRef<'a, 'static> {
    fn from(entity: EntityWorldMut<'a>) -> Self {
        // SAFETY:
        // - `EntityWorldMut` guarantees exclusive access to the entire world.
        unsafe {
            FilteredEntityRef::new(
                entity.into_unsafe_entity_cell(),
                const { &Access::new_read_all() },
            )
        }
    }
}

impl<'a> From<&'a EntityWorldMut<'_>> for FilteredEntityRef<'a, 'static> {
    fn from(entity: &'a EntityWorldMut<'_>) -> Self {
        // SAFETY:
        // - `EntityWorldMut` guarantees exclusive access to the entire world.
        unsafe {
            FilteredEntityRef::new(
                entity.as_unsafe_entity_cell_readonly(),
                const { &Access::new_read_all() },
            )
        }
    }
}

impl<'a> From<EntityWorldMut<'a>> for FilteredEntityMut<'a, 'static> {
    fn from(entity: EntityWorldMut<'a>) -> Self {
        // SAFETY:
        // - `EntityWorldMut` guarantees exclusive access to the entire world.
        unsafe {
            FilteredEntityMut::new(
                entity.into_unsafe_entity_cell(),
                const { &Access::new_write_all() },
            )
        }
    }
}

impl<'a> From<&'a mut EntityWorldMut<'_>> for FilteredEntityMut<'a, 'static> {
    fn from(entity: &'a mut EntityWorldMut<'_>) -> Self {
        // SAFETY:
        // - `EntityWorldMut` guarantees exclusive access to the entire world.
        unsafe {
            FilteredEntityMut::new(
                entity.as_unsafe_entity_cell(),
                const { &Access::new_write_all() },
            )
        }
    }
}

/// Inserts a dynamic [`Bundle`] into the entity.
///
/// # Safety
///
/// - [`OwningPtr`] and [`StorageType`] iterators must correspond to the
///   [`BundleInfo`](crate::bundle::BundleInfo) used to construct [`BundleInserter`]
/// - [`Entity`] must correspond to [`EntityLocation`]
unsafe fn insert_dynamic_bundle<
    'a,
    I: Iterator<Item = OwningPtr<'a>>,
    S: Iterator<Item = StorageType>,
>(
    mut bundle_inserter: BundleInserter<'_>,
    entity: Entity,
    location: EntityLocation,
    components: I,
    storage_types: S,
    mode: InsertMode,
    caller: MaybeLocation,
    relationship_hook_insert_mode: RelationshipHookMode,
) -> EntityLocation {
    struct DynamicInsertBundle<'a, I: Iterator<Item = (StorageType, OwningPtr<'a>)>> {
        components: I,
    }

    impl<'a, I: Iterator<Item = (StorageType, OwningPtr<'a>)>> DynamicBundle
        for DynamicInsertBundle<'a, I>
    {
        type Effect = ();
        unsafe fn get_components(
            mut ptr: MovingPtr<'_, Self>,
            func: &mut impl FnMut(StorageType, OwningPtr<'_>),
        ) {
            (&mut ptr.components).for_each(|(t, ptr)| func(t, ptr));
        }

        unsafe fn apply_effect(
            _ptr: MovingPtr<'_, MaybeUninit<Self>>,
            _entity: &mut EntityWorldMut,
        ) {
        }
    }

    let bundle = DynamicInsertBundle {
        components: storage_types.zip(components),
    };

    move_as_ptr!(bundle);

    // SAFETY:
    // - `location` matches `entity`.  and thus must currently exist in the source
    //   archetype for this inserter and its location within the archetype.
    // - The caller must ensure that the iterators and storage types match up with the `BundleInserter`
    // - `apply_effect` is never called on this bundle.
    // - `bundle` is not used or dropped after this point.
    unsafe {
        bundle_inserter.insert(
            entity,
            location,
            bundle,
            mode,
            caller,
            relationship_hook_insert_mode,
        )
    }
}

Graph