From 29a25df60e7a02fdf8c72bcf3744409448f14ca8 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Sun, 29 Sep 2024 16:48:34 -0700
Subject: [PATCH] Finish converting all events to jspecify annotations

---
 .../api/Add-BlockFailedDispenseEvent.patch    |   1 -
 patches/api/Add-BlockPreDispenseEvent.patch   |   1 +
 patches/api/Add-CartographyItemEvent.patch    |  15 +-
 .../Add-ElderGuardianAppearanceEvent.patch    |   1 +
 patches/api/Add-Mob-Goal-API.patch            |  88 +++---
 patches/api/Add-More-Creeper-API.patch        |   2 +
 .../api/Add-Player-Client-Options-API.patch   |  31 +-
 ...PlayerAdvancementCriterionGrantEvent.patch |  18 +-
 patches/api/Add-PlayerArmorChangeEvent.patch  |  31 +-
 ...PlayerAttackEntityCooldownResetEvent.patch |  14 +-
 patches/api/Add-PlayerFailMoveEvent.patch     |  15 +-
 .../Add-PlayerFlowerPotManipulateEvent.patch  |  13 +-
 .../Add-PlayerInventorySlotChangeEvent.patch  |  11 +-
 patches/api/Add-PlayerItemCooldownEvent.patch |  13 +-
 .../api/Add-PlayerItemFrameChangeEvent.patch  |  17 +-
 patches/api/Add-PlayerJumpEvent.patch         |  19 +-
 patches/api/Add-PlayerPickItemEvent.patch     |  19 +-
 patches/api/Add-PlayerPostRespawnEvent.patch  |  10 +-
 patches/api/Add-PlayerSetSpawnEvent.patch     |  31 +-
 .../api/Add-PlayerShieldDisableEvent.patch    |  10 +-
 ...Add-PlayerSignCommandPreprocessEvent.patch |  12 +-
 .../api/Add-PlayerStopUsingItemEvent.patch    |  10 +-
 .../api/Add-PlayerUseUnknownEntityEvent.patch |  13 +-
 .../api/Add-PrePlayerAttackEntityEvent.patch  |  11 +-
 ...reResultEvent-PrepareGrindstoneEvent.patch |   2 +
 patches/api/Add-StructuresLocateEvent.patch   |  31 +-
 ...implement-PlayerRecipeBookClickEvent.patch |  16 +-
 .../Add-event-for-player-editing-sign.patch   |  13 +-
 .../api/Add-exception-reporting-event.patch   |  12 +-
 ...-support-to-PaperServerListPingEvent.patch |   2 +-
 .../api/Add-paper-dumplisteners-command.patch |  22 +-
 patches/api/Add-spectator-target-events.patch |  27 +-
 patches/api/Add-villager-reputation-API.patch |  11 +-
 ...or-plugins-modifying-the-parent-of-t.patch |  20 +-
 patches/api/Add-worldborder-events.patch      |  40 ++-
 .../api/Added-PlayerBedFailEnterEvent.patch   |  22 +-
 .../Added-PlayerChangeBeaconEffectEvent.patch |  27 +-
 patches/api/Added-PlayerDeepSleepEvent.patch  |   9 +-
 .../Added-PlayerLecternPageChangeEvent.patch  |  14 +-
 .../Added-PlayerLoomPatternSelectEvent.patch  |  13 +-
 ...d-PlayerStonecutterRecipeSelectEvent.patch |  13 +-
 patches/api/Added-PlayerTradeEvent.patch      |  27 +-
 .../api/Added-WorldGameRuleChangeEvent.patch  |  20 +-
 patches/api/Adds-PlayerArmSwingEvent.patch    |   6 +-
 patches/api/Adventure.patch                   |  69 ++---
 patches/api/AnvilDamageEvent.patch            |   1 +
 patches/api/AsyncTabCompleteEvent.patch       |   1 +
 patches/api/Basic-PlayerProfile-API.patch     |   2 +-
 patches/api/Brigadier-based-command-API.patch |  14 +-
 patches/api/Build-system-changes.patch        |   1 +
 patches/api/EnderDragon-Events.patch          |   1 +
 patches/api/EndermanAttackPlayerEvent.patch   |   1 +
 ...Entity-AddTo-RemoveFrom-World-Events.patch |   2 +
 patches/api/Entity-Jump-API.patch             |   2 +
 patches/api/EntityPathfindEvent.patch         |   1 +
 ...ld.spawnParticle-API-and-add-Builder.patch | 279 ++++++++----------
 ...nt-protocol-version-and-virtual-host.patch |  10 +-
 .../api/Expose-server-build-information.patch |  12 +-
 .../api/Fill-Profile-Property-Events.patch    |  35 +--
 patches/api/LootTable-API.patch               |  64 ++--
 patches/api/Mob-Pathfinding-API.patch         |  69 ++---
 patches/api/Paper-Utils.patch                 |  13 +-
 .../api/Player-Chunk-Load-Unload-Events.patch |  16 +-
 .../api/Player-Entity-Tracking-Events.patch   |  18 +-
 patches/api/PlayerElytraBoostEvent.patch      |  19 +-
 patches/api/PlayerLaunchProjectileEvent.patch |  17 +-
 patches/api/PlayerPickupExperienceEvent.patch |  12 +-
 patches/api/PlayerReadyArrowEvent.patch       |  18 +-
 .../api/PlayerTeleportEndGatewayEvent.patch   |   8 +-
 patches/api/ProfileWhitelistVerifyEvent.patch |  31 +-
 patches/api/RangedEntity-API.patch            |   7 +-
 patches/api/Server-Tick-Events.patch          |   2 +
 patches/api/Slime-Pathfinder-Events.patch     |   2 +
 patches/api/Turtle-API.patch                  |   6 +
 patches/api/Use-ASM-for-event-executors.patch | 128 ++++----
 patches/api/WitchConsumePotionEvent.patch     |   1 +
 patches/api/added-PlayerNameEntityEvent.patch |  23 +-
 patches/server/Implement-Mob-Goal-API.patch   |   2 +
 78 files changed, 757 insertions(+), 883 deletions(-)

diff --git a/patches/api/Add-BlockFailedDispenseEvent.patch b/patches/api/Add-BlockFailedDispenseEvent.patch
index 6d9bfcf264..1be59e949f 100644
--- a/patches/api/Add-BlockFailedDispenseEvent.patch
+++ b/patches/api/Add-BlockFailedDispenseEvent.patch
@@ -15,7 +15,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.block.Block;
 +import org.bukkit.event.HandlerList;
 +import org.bukkit.event.block.BlockEvent;
-+import org.checkerframework.checker.nullness.qual.NonNull;
 +import org.jetbrains.annotations.ApiStatus;
 +import org.jspecify.annotations.NullMarked;
 +
diff --git a/patches/api/Add-BlockPreDispenseEvent.patch b/patches/api/Add-BlockPreDispenseEvent.patch
index 8f9677c2fe..cfef2a3585 100644
--- a/patches/api/Add-BlockPreDispenseEvent.patch
+++ b/patches/api/Add-BlockPreDispenseEvent.patch
@@ -65,6 +65,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        this.cancelled = cancel;
 +    }
 +
++    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
diff --git a/patches/api/Add-CartographyItemEvent.patch b/patches/api/Add-CartographyItemEvent.patch
index 45015d3af7..50602a7d2c 100644
--- a/patches/api/Add-CartographyItemEvent.patch
+++ b/patches/api/Add-CartographyItemEvent.patch
@@ -13,30 +13,31 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 @@ -0,0 +0,0 @@
 +package io.papermc.paper.event.player;
 +
-+import org.bukkit.inventory.InventoryView;
-+import org.bukkit.inventory.CartographyInventory;
 +import org.bukkit.event.inventory.ClickType;
-+import org.bukkit.event.inventory.InventoryType;
 +import org.bukkit.event.inventory.InventoryAction;
 +import org.bukkit.event.inventory.InventoryClickEvent;
-+import org.jetbrains.annotations.NotNull;
++import org.bukkit.event.inventory.InventoryType;
++import org.bukkit.inventory.CartographyInventory;
++import org.bukkit.inventory.InventoryView;
 +import org.jetbrains.annotations.ApiStatus;
++import org.jspecify.annotations.NullMarked;
 +
 +/**
 + * Called when the recipe of an Item is completed inside a cartography table.
 + */
++@NullMarked
 +public class CartographyItemEvent extends InventoryClickEvent {
++
 +    @ApiStatus.Internal
-+    public CartographyItemEvent(@NotNull InventoryView view, @NotNull InventoryType.SlotType type, int slot, @NotNull ClickType click, @NotNull InventoryAction action) {
++    public CartographyItemEvent(final InventoryView view, final InventoryType.SlotType type, final int slot, final ClickType click, final InventoryAction action) {
 +        super(view, type, slot, click, action);
 +    }
 +
 +    @ApiStatus.Internal
-+    public CartographyItemEvent(@NotNull InventoryView view, @NotNull InventoryType.SlotType type, int slot, @NotNull ClickType click, @NotNull InventoryAction action, int key) {
++    public CartographyItemEvent(final InventoryView view, final InventoryType.SlotType type, final int slot, final ClickType click, final InventoryAction action, final int key) {
 +        super(view, type, slot, click, action, key);
 +    }
 +
-+    @NotNull
 +    @Override
 +    public CartographyInventory getInventory() {
 +        return (CartographyInventory) super.getInventory();
diff --git a/patches/api/Add-ElderGuardianAppearanceEvent.patch b/patches/api/Add-ElderGuardianAppearanceEvent.patch
index e6c5445e28..73c4b1f7c0 100644
--- a/patches/api/Add-ElderGuardianAppearanceEvent.patch
+++ b/patches/api/Add-ElderGuardianAppearanceEvent.patch
@@ -51,6 +51,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return The elder guardian
 +     */
++    @Override
 +    public ElderGuardian getEntity() {
 +        return (ElderGuardian) super.getEntity();
 +    }
diff --git a/patches/api/Add-Mob-Goal-API.patch b/patches/api/Add-Mob-Goal-API.patch
index a858e42e4c..c0e8a59612 100644
--- a/patches/api/Add-Mob-Goal-API.patch
+++ b/patches/api/Add-Mob-Goal-API.patch
@@ -12,15 +12,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 @@ -0,0 +0,0 @@
 +package com.destroystokyo.paper.entity.ai;
 +
-+import org.jetbrains.annotations.NotNull;
-+
 +import java.util.EnumSet;
-+
 +import org.bukkit.entity.Mob;
++import org.jspecify.annotations.NullMarked;
 +
 +/**
 + * Represents an AI goal of an entity
 + */
++@NullMarked
 +public interface Goal<T extends Mob> {
 +
 +    /**
@@ -36,7 +35,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * @return if this goal should stay active
 +     */
 +    default boolean shouldStayActive() {
-+        return shouldActivate();
++        return this.shouldActivate();
 +    }
 +
 +    /**
@@ -63,17 +62,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return the goal key
 +     */
-+    @NotNull
 +    GoalKey<T> getKey();
 +
 +    /**
 +     * Returns a list of all applicable flags for this goal.<br>
-+     *
++     * <p>
 +     * This method is only called on construction.
 +     *
 +     * @return the subtypes.
 +     */
-+    @NotNull
 +    EnumSet<GoalType> getTypes();
 +}
 diff --git a/src/main/java/com/destroystokyo/paper/entity/ai/GoalKey.java b/src/main/java/com/destroystokyo/paper/entity/ai/GoalKey.java
@@ -85,64 +82,59 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +package com.destroystokyo.paper.entity.ai;
 +
 +import com.google.common.base.Objects;
-+
-+import org.jetbrains.annotations.NotNull;
-+
 +import java.util.StringJoiner;
-+
 +import org.bukkit.NamespacedKey;
 +import org.bukkit.entity.Mob;
++import org.jspecify.annotations.NullMarked;
++import org.jspecify.annotations.Nullable;
 +
 +/**
-+ *
 + * Used to identify a Goal. Consists of a {@link NamespacedKey} and the type of mob the goal can be applied to
 + *
 + * @param <T> the type of mob the goal can be applied to
 + */
-+public class GoalKey<T extends Mob> {
++@NullMarked
++public final class GoalKey<T extends Mob> {
 +
 +    private final Class<T> entityClass;
 +    private final NamespacedKey namespacedKey;
 +
-+    private GoalKey(@NotNull Class<T> entityClass, @NotNull NamespacedKey namespacedKey) {
++    private GoalKey(Class<T> entityClass, NamespacedKey namespacedKey) {
 +        this.entityClass = entityClass;
 +        this.namespacedKey = namespacedKey;
 +    }
 +
-+    @NotNull
 +    public Class<T> getEntityClass() {
-+        return entityClass;
++        return this.entityClass;
 +    }
 +
-+    @NotNull
 +    public NamespacedKey getNamespacedKey() {
-+        return namespacedKey;
++        return this.namespacedKey;
 +    }
 +
 +    @Override
-+    public boolean equals(Object o) {
++    public boolean equals(@Nullable Object o) {
 +        if (this == o) return true;
-+        if (o == null || getClass() != o.getClass()) return false;
++        if (o == null || this.getClass() != o.getClass()) return false;
 +        GoalKey<?> goalKey = (GoalKey<?>) o;
-+        return Objects.equal(entityClass, goalKey.entityClass) &&
-+               Objects.equal(namespacedKey, goalKey.namespacedKey);
++        return Objects.equal(this.entityClass, goalKey.entityClass) &&
++            Objects.equal(this.namespacedKey, goalKey.namespacedKey);
 +    }
 +
 +    @Override
 +    public int hashCode() {
-+        return Objects.hashCode(entityClass, namespacedKey);
++        return Objects.hashCode(this.entityClass, this.namespacedKey);
 +    }
 +
 +    @Override
 +    public String toString() {
 +        return new StringJoiner(", ", GoalKey.class.getSimpleName() + "[", "]")
-+            .add("entityClass=" + entityClass)
-+            .add("namespacedKey=" + namespacedKey)
++            .add("entityClass=" + this.entityClass)
++            .add("namespacedKey=" + this.namespacedKey)
 +            .toString();
 +    }
 +
-+    @NotNull
-+    public static <A extends Mob> GoalKey<A> of(@NotNull Class<A> entityClass, @NotNull NamespacedKey namespacedKey) {
++    public static <A extends Mob> GoalKey<A> of(Class<A> entityClass, NamespacedKey namespacedKey) {
 +        return new GoalKey<>(entityClass, namespacedKey);
 +    }
 +}
@@ -177,53 +169,45 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 @@ -0,0 +0,0 @@
 +package com.destroystokyo.paper.entity.ai;
 +
-+import org.jetbrains.annotations.NotNull;
-+import org.jetbrains.annotations.Nullable;
 +
 +import java.util.Collection;
-+
 +import org.bukkit.entity.Mob;
++import org.jspecify.annotations.NullMarked;
++import org.jspecify.annotations.Nullable;
 +
 +/**
 + * Represents a part of the "brain" of a mob. It tracks all tasks (running or not), allows adding and removing goals
 + */
++@NullMarked
 +public interface MobGoals {
 +
-+    <T extends Mob> void addGoal(@NotNull T mob, int priority, @NotNull Goal<T> goal);
++    <T extends Mob> void addGoal(T mob, int priority, Goal<T> goal);
 +
-+    <T extends Mob> void removeGoal(@NotNull T mob, @NotNull Goal<T> goal);
++    <T extends Mob> void removeGoal(T mob, Goal<T> goal);
 +
-+    <T extends Mob> void removeAllGoals(@NotNull T mob);
++    <T extends Mob> void removeAllGoals(T mob);
 +
-+    <T extends Mob> void removeAllGoals(@NotNull T mob, @NotNull GoalType type);
++    <T extends Mob> void removeAllGoals(T mob, GoalType type);
 +
-+    <T extends Mob> void removeGoal(@NotNull T mob, @NotNull GoalKey<T> key);
++    <T extends Mob> void removeGoal(T mob, GoalKey<T> key);
 +
-+    <T extends Mob> boolean hasGoal(@NotNull T mob, @NotNull GoalKey<T> key);
++    <T extends Mob> boolean hasGoal(T mob, GoalKey<T> key);
 +
-+    @Nullable
-+    <T extends Mob> Goal<T> getGoal(@NotNull T mob, @NotNull GoalKey<T> key);
++    <T extends Mob> @Nullable Goal<T> getGoal(T mob, GoalKey<T> key);
 +
-+    @NotNull
-+    <T extends Mob> Collection<Goal<T>> getGoals(@NotNull T mob, @NotNull GoalKey<T> key);
++    <T extends Mob> Collection<Goal<T>> getGoals(T mob, GoalKey<T> key);
 +
-+    @NotNull
-+    <T extends Mob> Collection<Goal<T>> getAllGoals(@NotNull T mob);
++    <T extends Mob> Collection<Goal<T>> getAllGoals(T mob);
 +
-+    @NotNull
-+    <T extends Mob> Collection<Goal<T>> getAllGoals(@NotNull T mob, @NotNull GoalType type);
++    <T extends Mob> Collection<Goal<T>> getAllGoals(T mob, GoalType type);
 +
-+    @NotNull
-+    <T extends Mob> Collection<Goal<T>> getAllGoalsWithout(@NotNull T mob, @NotNull GoalType type);
++    <T extends Mob> Collection<Goal<T>> getAllGoalsWithout(T mob, GoalType type);
 +
-+    @NotNull
-+    <T extends Mob> Collection<Goal<T>> getRunningGoals(@NotNull T mob);
++    <T extends Mob> Collection<Goal<T>> getRunningGoals(T mob);
 +
-+    @NotNull
-+    <T extends Mob> Collection<Goal<T>> getRunningGoals(@NotNull T mob, @NotNull GoalType type);
++    <T extends Mob> Collection<Goal<T>> getRunningGoals(T mob, GoalType type);
 +
-+    @NotNull
-+    <T extends Mob> Collection<Goal<T>> getRunningGoalsWithout(@NotNull T mob, @NotNull GoalType type);
++    <T extends Mob> Collection<Goal<T>> getRunningGoalsWithout(T mob, GoalType type);
 +}
 diff --git a/src/main/java/org/bukkit/Bukkit.java b/src/main/java/org/bukkit/Bukkit.java
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
diff --git a/patches/api/Add-More-Creeper-API.patch b/patches/api/Add-More-Creeper-API.patch
index 25edb3c900..fef0692fb9 100644
--- a/patches/api/Add-More-Creeper-API.patch
+++ b/patches/api/Add-More-Creeper-API.patch
@@ -51,10 +51,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        this.ignited = ignited;
 +    }
 +
++    @Override
 +    public boolean isCancelled() {
 +        return this.cancelled;
 +    }
 +
++    @Override
 +    public void setCancelled(final boolean cancel) {
 +        this.cancelled = cancel;
 +    }
diff --git a/patches/api/Add-Player-Client-Options-API.patch b/patches/api/Add-Player-Client-Options-API.patch
index a83bf921be..d022138b4d 100644
--- a/patches/api/Add-Player-Client-Options-API.patch
+++ b/patches/api/Add-Player-Client-Options-API.patch
@@ -14,10 +14,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +import net.kyori.adventure.translation.Translatable;
 +import net.kyori.adventure.util.Index;
-+import org.jetbrains.annotations.NotNull;
-+
 +import org.bukkit.inventory.MainHand;
++import org.jspecify.annotations.NullMarked;
 +
++@NullMarked
 +public final class ClientOption<T> {
 +
 +    public static final ClientOption<SkinParts> SKIN_PARTS = new ClientOption<>(SkinParts.class);
@@ -31,13 +31,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +    private final Class<T> type;
 +
-+    private ClientOption(@NotNull Class<T> type) {
++    private ClientOption(final Class<T> type) {
 +        this.type = type;
 +    }
 +
-+    @NotNull
 +    public Class<T> getType() {
-+        return type;
++        return this.type;
 +    }
 +
 +    public enum ChatVisibility implements Translatable {
@@ -46,15 +45,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        HIDDEN("hidden"),
 +        UNKNOWN("unknown");
 +
-+        public static Index<String, ChatVisibility> NAMES = Index.create(ChatVisibility.class, chatVisibility -> chatVisibility.name);
++        public static final Index<String, ChatVisibility> NAMES = Index.create(ChatVisibility.class, chatVisibility -> chatVisibility.name);
 +        private final String name;
 +
-+        ChatVisibility(String name) {
++        ChatVisibility(final String name) {
 +            this.name = name;
 +        }
 +
 +        @Override
-+        public @NotNull String translationKey() {
++        public String translationKey() {
 +            if (this == UNKNOWN) {
 +                throw new UnsupportedOperationException(this.name + " doesn't have a translation key");
 +            }
@@ -99,18 +98,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import com.destroystokyo.paper.ClientOption;
 +import com.destroystokyo.paper.ClientOption.ChatVisibility;
 +import com.destroystokyo.paper.SkinParts;
++import java.util.Map;
 +import org.bukkit.entity.Player;
 +import org.bukkit.event.HandlerList;
 +import org.bukkit.event.player.PlayerEvent;
 +import org.bukkit.inventory.MainHand;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
-+
-+import java.util.Map;
++import org.jspecify.annotations.NullMarked;
 +
 +/**
 + * Called when the player changes their client settings
 + */
++@NullMarked
 +public class PlayerClientOptionsChangeEvent extends PlayerEvent {
 +
 +    private static final HandlerList HANDLER_LIST = new HandlerList();
@@ -125,7 +124,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    private final boolean textFilteringEnabled;
 +
 +    @Deprecated
-+    public PlayerClientOptionsChangeEvent(@NotNull Player player, @NotNull String locale, int viewDistance, @NotNull ChatVisibility chatVisibility, boolean chatColors, @NotNull SkinParts skinParts, @NotNull MainHand mainHand) {
++    public PlayerClientOptionsChangeEvent(final Player player, final String locale, final int viewDistance, final ChatVisibility chatVisibility, final boolean chatColors, final SkinParts skinParts, final MainHand mainHand) {
 +        super(player);
 +        this.locale = locale;
 +        this.viewDistance = viewDistance;
@@ -138,7 +137,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
 +
 +    @ApiStatus.Internal
-+    public PlayerClientOptionsChangeEvent(@NotNull Player player, @NotNull Map<ClientOption<?>, ?> options) {
++    public PlayerClientOptionsChangeEvent(final Player player, final Map<ClientOption<?>, ?> options) {
 +        super(player);
 +
 +        this.locale = (String) options.get(ClientOption.LOCALE);
@@ -151,7 +150,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        this.textFilteringEnabled = (boolean) options.get(ClientOption.TEXT_FILTERING_ENABLED);
 +    }
 +
-+    @NotNull
 +    public String getLocale() {
 +        return this.locale;
 +    }
@@ -168,7 +166,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        return this.viewDistance != this.player.getClientOption(ClientOption.VIEW_DISTANCE);
 +    }
 +
-+    @NotNull
 +    public ChatVisibility getChatVisibility() {
 +        return this.chatVisibility;
 +    }
@@ -185,7 +182,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        return this.chatColors != this.player.getClientOption(ClientOption.CHAT_COLORS_ENABLED);
 +    }
 +
-+    @NotNull
 +    public SkinParts getSkinParts() {
 +        return this.skinparts;
 +    }
@@ -194,7 +190,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        return this.skinparts.getRaw() != this.player.getClientOption(ClientOption.SKIN_PARTS).getRaw();
 +    }
 +
-+    @NotNull
 +    public MainHand getMainHand() {
 +        return this.mainHand;
 +    }
@@ -220,12 +215,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
 +
 +    @Override
-+    @NotNull
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
 +
-+    @NotNull
 +    public static HandlerList getHandlerList() {
 +        return HANDLER_LIST;
 +    }
diff --git a/patches/api/Add-PlayerAdvancementCriterionGrantEvent.patch b/patches/api/Add-PlayerAdvancementCriterionGrantEvent.patch
index f189a7c092..f0bf2c05d1 100644
--- a/patches/api/Add-PlayerAdvancementCriterionGrantEvent.patch
+++ b/patches/api/Add-PlayerAdvancementCriterionGrantEvent.patch
@@ -20,24 +20,25 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.event.HandlerList;
 +import org.bukkit.event.player.PlayerEvent;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
 +
 +/**
 + * Called after a player is granted a criteria in an advancement.
 + * If cancelled the criteria will be revoked.
 + */
++@NullMarked
 +public class PlayerAdvancementCriterionGrantEvent extends PlayerEvent implements Cancellable {
 +
 +    private static final HandlerList HANDLER_LIST = new HandlerList();
 +
-+    @NotNull private final Advancement advancement;
-+    @NotNull private final String criterion;
-+    @NotNull private final AdvancementProgress advancementProgress;
++    private final Advancement advancement;
++    private final String criterion;
++    private final AdvancementProgress advancementProgress;
 +
 +    private boolean cancelled;
 +
 +    @ApiStatus.Internal
-+    public PlayerAdvancementCriterionGrantEvent(@NotNull Player player, @NotNull Advancement advancement, @NotNull String criterion) {
++    public PlayerAdvancementCriterionGrantEvent(final Player player, final Advancement advancement, final String criterion) {
 +        super(player);
 +        this.advancement = advancement;
 +        this.criterion = criterion;
@@ -49,7 +50,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return affected advancement
 +     */
-+    @NotNull
 +    public Advancement getAdvancement() {
 +        return this.advancement;
 +    }
@@ -59,7 +59,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return granted criterion
 +     */
-+    @NotNull
 +    public String getCriterion() {
 +        return this.criterion;
 +    }
@@ -69,7 +68,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return advancement progress
 +     */
-+    @NotNull
 +    public AdvancementProgress getAdvancementProgress() {
 +        return this.advancementProgress;
 +    }
@@ -80,17 +78,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
 +
 +    @Override
-+    public void setCancelled(boolean cancel) {
++    public void setCancelled(final boolean cancel) {
 +        this.cancelled = cancel;
 +    }
 +
-+    @NotNull
 +    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
 +
-+    @NotNull
 +    public static HandlerList getHandlerList() {
 +        return HANDLER_LIST;
 +    }
diff --git a/patches/api/Add-PlayerArmorChangeEvent.patch b/patches/api/Add-PlayerArmorChangeEvent.patch
index c4814965b9..75e296b6e5 100644
--- a/patches/api/Add-PlayerArmorChangeEvent.patch
+++ b/patches/api/Add-PlayerArmorChangeEvent.patch
@@ -12,16 +12,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 @@ -0,0 +0,0 @@
 +package com.destroystokyo.paper.event.player;
 +
++import java.util.Set;
 +import org.bukkit.Material;
 +import org.bukkit.entity.Player;
 +import org.bukkit.event.HandlerList;
 +import org.bukkit.event.player.PlayerEvent;
 +import org.bukkit.inventory.ItemStack;
-+
-+import java.util.Set;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
-+import org.jetbrains.annotations.Nullable;
++import org.jspecify.annotations.NullMarked;
++import org.jspecify.annotations.Nullable;
 +
 +import static org.bukkit.Material.*;
 +
@@ -30,16 +29,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 + * <p>
 + * Not currently called for environmental factors though it <strong>MAY BE IN THE FUTURE</strong>
 + */
++@NullMarked
 +public class PlayerArmorChangeEvent extends PlayerEvent {
 +
 +    private static final HandlerList HANDLER_LIST = new HandlerList();
 +
-+    @NotNull private final SlotType slotType;
-+    @NotNull private final ItemStack oldItem;
-+    @NotNull private final ItemStack newItem;
++    private final SlotType slotType;
++    private final ItemStack oldItem;
++    private final ItemStack newItem;
 +
 +    @ApiStatus.Internal
-+    public PlayerArmorChangeEvent(@NotNull Player player, @NotNull SlotType slotType, @NotNull ItemStack oldItem, @NotNull ItemStack newItem) {
++    public PlayerArmorChangeEvent(final Player player, final SlotType slotType, final ItemStack oldItem, final ItemStack newItem) {
 +        super(player);
 +        this.slotType = slotType;
 +        this.oldItem = oldItem;
@@ -51,7 +51,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return type of slot being altered
 +     */
-+    @NotNull
 +    public SlotType getSlotType() {
 +        return this.slotType;
 +    }
@@ -61,7 +60,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return old item
 +     */
-+    @NotNull
 +    public ItemStack getOldItem() {
 +        return this.oldItem;
 +    }
@@ -71,18 +69,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return new item
 +     */
-+    @NotNull
 +    public ItemStack getNewItem() {
 +        return this.newItem;
 +    }
 +
-+    @NotNull
 +    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
 +
-+    @NotNull
 +    public static HandlerList getHandlerList() {
 +        return HANDLER_LIST;
 +    }
@@ -95,7 +90,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +        private final Set<Material> types;
 +
-+        SlotType(Material... types) {
++        SlotType(final Material... types) {
 +            this.types = Set.of(types);
 +        }
 +
@@ -105,7 +100,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +         *
 +         * @return immutable set of material types
 +         */
-+        @NotNull
 +        public Set<Material> getTypes() {
 +            return this.types;
 +        }
@@ -116,9 +110,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +         * @param material material to get slot by
 +         * @return slot type the material will go in, or {@code null} if it won't
 +         */
-+        @Nullable
-+        public static SlotType getByMaterial(@NotNull Material material) {
-+            for (SlotType slotType : values()) {
++        public static @Nullable SlotType getByMaterial(final Material material) {
++            for (final SlotType slotType : values()) {
 +                if (slotType.getTypes().contains(material)) {
 +                    return slotType;
 +                }
@@ -132,7 +125,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +         * @param material material to check
 +         * @return whether this material can be equipped
 +         */
-+        public static boolean isEquipable(@NotNull Material material) {
++        public static boolean isEquipable(final Material material) {
 +            return getByMaterial(material) != null;
 +        }
 +    }
diff --git a/patches/api/Add-PlayerAttackEntityCooldownResetEvent.patch b/patches/api/Add-PlayerAttackEntityCooldownResetEvent.patch
index f111a83542..1e5e83b635 100644
--- a/patches/api/Add-PlayerAttackEntityCooldownResetEvent.patch
+++ b/patches/api/Add-PlayerAttackEntityCooldownResetEvent.patch
@@ -18,22 +18,23 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.event.HandlerList;
 +import org.bukkit.event.player.PlayerEvent;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
 +
 +/**
 + * Called when processing a player's attack on an entity when the player's attack strength cooldown is reset
 + */
++@NullMarked
 +public class PlayerAttackEntityCooldownResetEvent extends PlayerEvent implements Cancellable {
 +
 +    private static final HandlerList HANDLER_LIST = new HandlerList();
 +
-+    @NotNull private final Entity attackedEntity;
++    private final Entity attackedEntity;
 +    private final float cooledAttackStrength;
 +
 +    private boolean cancelled;
 +
 +    @ApiStatus.Internal
-+    public PlayerAttackEntityCooldownResetEvent(@NotNull Player player, @NotNull Entity attackedEntity, float cooledAttackStrength) {
++    public PlayerAttackEntityCooldownResetEvent(final Player player, final Entity attackedEntity, final float cooledAttackStrength) {
 +        super(player);
 +        this.attackedEntity = attackedEntity;
 +        this.cooledAttackStrength = cooledAttackStrength;
@@ -53,7 +54,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return the entity attacked by the player
 +     */
-+    @NotNull
 +    public Entity getAttackedEntity() {
 +        return this.attackedEntity;
 +    }
@@ -74,16 +74,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * Cancelling this event will prevent the target player from having their cooldown reset from attacking this entity
 +     */
 +    @Override
-+    public void setCancelled(boolean cancel) {
++    public void setCancelled(final boolean cancel) {
 +        this.cancelled = cancel;
 +    }
 +
 +    @Override
-+    public @NotNull HandlerList getHandlers() {
++    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
 +
-+    public static @NotNull HandlerList getHandlerList() {
++    public static HandlerList getHandlerList() {
 +        return HANDLER_LIST;
 +    }
 +}
diff --git a/patches/api/Add-PlayerFailMoveEvent.patch b/patches/api/Add-PlayerFailMoveEvent.patch
index bcbe0696db..edf8d0183b 100644
--- a/patches/api/Add-PlayerFailMoveEvent.patch
+++ b/patches/api/Add-PlayerFailMoveEvent.patch
@@ -17,11 +17,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.event.HandlerList;
 +import org.bukkit.event.player.PlayerEvent;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
 +
 +/**
 + * Runs when a player attempts to move, but is prevented from doing so by the server
 + */
++@NullMarked
 +public class PlayerFailMoveEvent extends PlayerEvent {
 +
 +    private static final HandlerList HANDLER_LIST = new HandlerList();
@@ -33,8 +34,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    private boolean logWarning;
 +
 +    @ApiStatus.Internal
-+    public PlayerFailMoveEvent(@NotNull Player player, @NotNull FailReason failReason, boolean allowed,
-+                               boolean logWarning, @NotNull Location from, @NotNull Location to) {
++    public PlayerFailMoveEvent(final Player player, final FailReason failReason, final boolean allowed, final boolean logWarning, final Location from, final Location to) {
 +        super(player);
 +        this.failReason = failReason;
 +        this.allowed = allowed;
@@ -48,7 +48,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return The reason the movement was prevented
 +     */
-+    @NotNull
 +    public FailReason getFailReason() {
 +        return this.failReason;
 +    }
@@ -58,7 +57,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return Location the player moved from
 +     */
-+    @NotNull
 +    public Location getFrom() {
 +        return this.from.clone();
 +    }
@@ -68,7 +66,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return Location the player tried to move to
 +     */
-+    @NotNull
 +    public Location getTo() {
 +        return this.to.clone();
 +    }
@@ -87,7 +84,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @param allowed whether to bypass the check
 +     */
-+    public void setAllowed(boolean allowed) {
++    public void setAllowed(final boolean allowed) {
 +        this.allowed = allowed;
 +    }
 +
@@ -105,17 +102,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @param logWarning whether to log warnings
 +     */
-+    public void setLogWarning(boolean logWarning) {
++    public void setLogWarning(final boolean logWarning) {
 +        this.logWarning = logWarning;
 +    }
 +
-+    @NotNull
 +    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
 +
-+    @NotNull
 +    public static HandlerList getHandlerList() {
 +        return HANDLER_LIST;
 +    }
diff --git a/patches/api/Add-PlayerFlowerPotManipulateEvent.patch b/patches/api/Add-PlayerFlowerPotManipulateEvent.patch
index 88ab8d7377..e9e07b4394 100644
--- a/patches/api/Add-PlayerFlowerPotManipulateEvent.patch
+++ b/patches/api/Add-PlayerFlowerPotManipulateEvent.patch
@@ -19,25 +19,24 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.event.player.PlayerEvent;
 +import org.bukkit.inventory.ItemStack;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
 +
 +/**
 + * Called when a player places an item in or takes an item out of a flowerpot.
 + */
++@NullMarked
 +public class PlayerFlowerPotManipulateEvent extends PlayerEvent implements Cancellable {
 +
 +    private static final HandlerList HANDLER_LIST = new HandlerList();
 +
-+    @NotNull
 +    private final Block flowerpot;
-+    @NotNull
 +    private final ItemStack item;
 +    private final boolean placing;
 +
 +    private boolean cancelled;
 +
 +    @ApiStatus.Internal
-+    public PlayerFlowerPotManipulateEvent(@NotNull final Player player, @NotNull final Block flowerpot, @NotNull final ItemStack item, final boolean placing) {
++    public PlayerFlowerPotManipulateEvent(final Player player, final Block flowerpot, final ItemStack item, final boolean placing) {
 +        super(player);
 +        this.flowerpot = flowerpot;
 +        this.item = item;
@@ -49,7 +48,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return the flowerpot that is involved with this event
 +     */
-+    @NotNull
 +    public Block getFlowerpot() {
 +        return this.flowerpot;
 +    }
@@ -60,7 +58,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return the item placed, or taken from, the flowerpot
 +     */
-+    @NotNull
 +    public ItemStack getItem() {
 +        return this.item;
 +    }
@@ -80,17 +77,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
 +
 +    @Override
-+    public void setCancelled(boolean cancel) {
++    public void setCancelled(final boolean cancel) {
 +        this.cancelled = cancel;
 +    }
 +
-+    @NotNull
 +    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
 +
-+    @NotNull
 +    public static HandlerList getHandlerList() {
 +        return HANDLER_LIST;
 +    }
diff --git a/patches/api/Add-PlayerInventorySlotChangeEvent.patch b/patches/api/Add-PlayerInventorySlotChangeEvent.patch
index 5647dab88c..2de6840225 100644
--- a/patches/api/Add-PlayerInventorySlotChangeEvent.patch
+++ b/patches/api/Add-PlayerInventorySlotChangeEvent.patch
@@ -17,11 +17,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.event.player.PlayerEvent;
 +import org.bukkit.inventory.Inventory;
 +import org.bukkit.inventory.ItemStack;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
 +
 +/**
 + * Called when a slot contents change in a player's inventory.
 + */
++@NullMarked
 +public class PlayerInventorySlotChangeEvent extends PlayerEvent {
 +
 +    private static final HandlerList HANDLER_LIST = new HandlerList();
@@ -32,7 +33,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    private final ItemStack newItemStack;
 +    private boolean triggerAdvancements = true;
 +
-+    public PlayerInventorySlotChangeEvent(@NotNull Player player, int rawSlot, @NotNull ItemStack oldItemStack, @NotNull ItemStack newItemStack) {
++    public PlayerInventorySlotChangeEvent(final Player player, final int rawSlot, final ItemStack oldItemStack, final ItemStack newItemStack) {
 +        super(player);
 +        this.rawSlot = rawSlot;
 +        this.slot = player.getOpenInventory().convertSlot(rawSlot);
@@ -67,7 +68,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return The old ItemStack in the slot.
 +     */
-+    @NotNull
 +    public ItemStack getOldItemStack() {
 +        return this.oldItemStack;
 +    }
@@ -77,7 +77,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return The new ItemStack in the slot.
 +     */
-+    @NotNull
 +    public ItemStack getNewItemStack() {
 +        return this.newItemStack;
 +    }
@@ -96,17 +95,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @param triggerAdvancements Whether the slot change advancements will be triggered.
 +     */
-+    public void setShouldTriggerAdvancements(boolean triggerAdvancements) {
++    public void setShouldTriggerAdvancements(final boolean triggerAdvancements) {
 +        this.triggerAdvancements = triggerAdvancements;
 +    }
 +
-+    @NotNull
 +    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
 +
-+    @NotNull
 +    public static HandlerList getHandlerList() {
 +        return HANDLER_LIST;
 +    }
diff --git a/patches/api/Add-PlayerItemCooldownEvent.patch b/patches/api/Add-PlayerItemCooldownEvent.patch
index 1248dc3478..03ef96e9f2 100644
--- a/patches/api/Add-PlayerItemCooldownEvent.patch
+++ b/patches/api/Add-PlayerItemCooldownEvent.patch
@@ -19,23 +19,23 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.event.HandlerList;
 +import org.bukkit.event.player.PlayerEvent;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
 +
 +/**
 + * Fired when a player receives an item cooldown.
 + */
++@NullMarked
 +public class PlayerItemCooldownEvent extends PlayerEvent implements Cancellable {
 +
 +    private static final HandlerList HANDLER_LIST = new HandlerList();
 +
-+    @NotNull
 +    private final Material type;
 +    private int cooldown;
 +
 +    private boolean cancelled;
 +
 +    @ApiStatus.Internal
-+    public PlayerItemCooldownEvent(@NotNull Player player, @NotNull Material type, int cooldown) {
++    public PlayerItemCooldownEvent(final Player player, final Material type, final int cooldown) {
 +        super(player);
 +        this.type = type;
 +        this.cooldown = cooldown;
@@ -46,7 +46,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return material affected by the cooldown
 +     */
-+    @NotNull
 +    public Material getType() {
 +        return this.type;
 +    }
@@ -66,7 +65,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @param cooldown cooldown in ticks, has to be a positive number
 +     */
-+    public void setCooldown(int cooldown) {
++    public void setCooldown(final int cooldown) {
 +        Preconditions.checkArgument(cooldown >= 0, "The cooldown has to be equal to or greater than 0!");
 +        this.cooldown = cooldown;
 +    }
@@ -77,17 +76,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
 +
 +    @Override
-+    public void setCancelled(boolean cancel) {
++    public void setCancelled(final boolean cancel) {
 +        this.cancelled = cancel;
 +    }
 +
-+    @NotNull
 +    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
 +
-+    @NotNull
 +    public static HandlerList getHandlerList() {
 +        return HANDLER_LIST;
 +    }
diff --git a/patches/api/Add-PlayerItemFrameChangeEvent.patch b/patches/api/Add-PlayerItemFrameChangeEvent.patch
index 481bca5422..a4cf59e59a 100644
--- a/patches/api/Add-PlayerItemFrameChangeEvent.patch
+++ b/patches/api/Add-PlayerItemFrameChangeEvent.patch
@@ -19,12 +19,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.event.player.PlayerEvent;
 +import org.bukkit.inventory.ItemStack;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
-+import org.jetbrains.annotations.Nullable;
++import org.jspecify.annotations.NullMarked;
++import org.jspecify.annotations.Nullable;
 +
 +/**
 + * Called when an {@link ItemFrame} is having an item rotated, added, or removed from it.
 + */
++@NullMarked
 +public class PlayerItemFrameChangeEvent extends PlayerEvent implements Cancellable {
 +
 +    private static final HandlerList HANDLER_LIST = new HandlerList();
@@ -36,8 +37,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    private boolean cancelled;
 +
 +    @ApiStatus.Internal
-+    public PlayerItemFrameChangeEvent(@NotNull Player player, @NotNull ItemFrame itemFrame,
-+                                      @NotNull ItemStack itemStack, @NotNull ItemFrameChangeAction action) {
++    public PlayerItemFrameChangeEvent(final Player player, final ItemFrame itemFrame, final ItemStack itemStack, final ItemFrameChangeAction action) {
 +        super(player);
 +        this.itemFrame = itemFrame;
 +        this.itemStack = itemStack;
@@ -49,7 +49,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return the {@link ItemFrame}
 +     */
-+    @NotNull
 +    public ItemFrame getItemFrame() {
 +        return this.itemFrame;
 +    }
@@ -62,7 +61,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return the {@link ItemStack} being added, rotated, or removed
 +     */
-+    @NotNull
 +    public ItemStack getItemStack() {
 +        return this.itemStack;
 +    }
@@ -73,7 +71,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @param itemStack {@link ItemFrame} item
 +     */
-+    public void setItemStack(@Nullable ItemStack itemStack) {
++    public void setItemStack(final @Nullable ItemStack itemStack) {
 +        this.itemStack = itemStack == null ? ItemStack.empty() : itemStack;
 +    }
 +
@@ -82,7 +80,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return action performed on the item frame in this event
 +     */
-+    @NotNull
 +    public ItemFrameChangeAction getAction() {
 +        return this.action;
 +    }
@@ -93,17 +90,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
 +
 +    @Override
-+    public void setCancelled(boolean cancel) {
++    public void setCancelled(final boolean cancel) {
 +        this.cancelled = cancel;
 +    }
 +
 +    @Override
-+    @NotNull
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
 +
-+    @NotNull
 +    public static HandlerList getHandlerList() {
 +        return HANDLER_LIST;
 +    }
diff --git a/patches/api/Add-PlayerJumpEvent.patch b/patches/api/Add-PlayerJumpEvent.patch
index cc144c6983..c75cb54c59 100644
--- a/patches/api/Add-PlayerJumpEvent.patch
+++ b/patches/api/Add-PlayerJumpEvent.patch
@@ -20,7 +20,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.event.player.PlayerEvent;
 +import org.bukkit.event.player.PlayerMoveEvent;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
 +
 +/**
 + * Called when the server detects the player is jumping.
@@ -29,17 +29,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 + * when checking for jumps via {@link PlayerMoveEvent}, this event is fired whenever
 + * the server detects that the player is jumping.
 + */
++@NullMarked
 +public class PlayerJumpEvent extends PlayerEvent implements Cancellable {
 +
 +    private static final HandlerList HANDLER_LIST = new HandlerList();
 +
-+    @NotNull private final Location to;
-+    @NotNull private Location from;
++    private final Location to;
++    private Location from;
 +
 +    private boolean cancelled;
 +
 +    @ApiStatus.Internal
-+    public PlayerJumpEvent(@NotNull final Player player, @NotNull final Location from, @NotNull final Location to) {
++    public PlayerJumpEvent(final Player player, final Location from, final Location to) {
 +        super(player);
 +        this.from = from;
 +        this.to = to;
@@ -54,6 +55,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return {@code true} if this event is cancelled
 +     */
++    @Override
 +    public boolean isCancelled() {
 +        return this.cancelled;
 +    }
@@ -67,7 +69,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @param cancel {@code true} if you wish to cancel this event
 +     */
-+    public void setCancelled(boolean cancel) {
++    @Override
++    public void setCancelled(final boolean cancel) {
 +        this.cancelled = cancel;
 +    }
 +
@@ -76,7 +79,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return Location the player jumped from
 +     */
-+    @NotNull
 +    public Location getFrom() {
 +        return this.from;
 +    }
@@ -86,7 +88,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @param from New location to mark as the players previous location
 +     */
-+    public void setFrom(@NotNull Location from) {
++    public void setFrom(final Location from) {
 +        Preconditions.checkArgument(from != null, "Cannot use null from location!");
 +        Preconditions.checkArgument(from.getWorld() != null, "Cannot use from location with null world!");
 +        this.from = from;
@@ -100,18 +102,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return Location the player jumped to
 +     */
-+    @NotNull
 +    public Location getTo() {
 +        return this.to.clone();
 +    }
 +
-+    @NotNull
 +    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
 +
-+    @NotNull
 +    public static HandlerList getHandlerList() {
 +        return HANDLER_LIST;
 +    }
diff --git a/patches/api/Add-PlayerPickItemEvent.patch b/patches/api/Add-PlayerPickItemEvent.patch
index 4c203b36e9..893aad1821 100644
--- a/patches/api/Add-PlayerPickItemEvent.patch
+++ b/patches/api/Add-PlayerPickItemEvent.patch
@@ -18,8 +18,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.event.HandlerList;
 +import org.bukkit.event.player.PlayerEvent;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
 +import org.jetbrains.annotations.Range;
++import org.jspecify.annotations.NullMarked;
 +
 +/**
 + * Event that is fired when a player uses the pick item functionality (middle-clicking a block to get the appropriate
@@ -29,6 +29,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 + * <p>
 + * Note: This event will not be fired for players in creative mode.
 + */
++@NullMarked
 +public class PlayerPickItemEvent extends PlayerEvent implements Cancellable {
 +
 +    private static final HandlerList HANDLER_LIST = new HandlerList();
@@ -39,7 +40,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    private boolean cancelled;
 +
 +    @ApiStatus.Internal
-+    public PlayerPickItemEvent(@NotNull Player player, int targetSlot, int sourceSlot) {
++    public PlayerPickItemEvent(final Player player, final int targetSlot, final int sourceSlot) {
 +        super(player);
 +        this.targetSlot = targetSlot;
 +        this.sourceSlot = sourceSlot;
@@ -50,8 +51,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return hotbar slot (0-8 inclusive)
 +     */
-+    @Range(from = 0, to = 8)
-+    public int getTargetSlot() {
++    public @Range(from = 0, to = 8) int getTargetSlot() {
 +        return this.targetSlot;
 +    }
 +
@@ -60,7 +60,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @param targetSlot hotbar slot (0-8 inclusive)
 +     */
-+    public void setTargetSlot(@Range(from = 0, to = 8) int targetSlot) {
++    public void setTargetSlot(final @Range(from = 0, to = 8) int targetSlot) {
 +        Preconditions.checkArgument(targetSlot >= 0 && targetSlot <= 8, "Target slot must be in range 0 - 8 (inclusive)");
 +        this.targetSlot = targetSlot;
 +    }
@@ -70,8 +70,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return player inventory slot (0-35 inclusive)
 +     */
-+    @Range(from = 0, to = 35)
-+    public int getSourceSlot() {
++    public @Range(from = 0, to = 35) int getSourceSlot() {
 +        return this.sourceSlot;
 +    }
 +
@@ -80,7 +79,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @param sourceSlot player inventory slot (0-35 inclusive)
 +     */
-+    public void setSourceSlot(@Range(from = 0, to = 35) int sourceSlot) {
++    public void setSourceSlot(final @Range(from = 0, to = 35) int sourceSlot) {
 +        Preconditions.checkArgument(sourceSlot >= 0 && sourceSlot <= 35, "Source slot must be in range of the player's inventory slot");
 +        this.sourceSlot = sourceSlot;
 +    }
@@ -91,17 +90,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
 +
 +    @Override
-+    public void setCancelled(boolean cancel) {
++    public void setCancelled(final boolean cancel) {
 +        this.cancelled = cancel;
 +    }
 +
-+    @NotNull
 +    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
 +
-+    @NotNull
 +    public static HandlerList getHandlerList() {
 +        return HANDLER_LIST;
 +    }
diff --git a/patches/api/Add-PlayerPostRespawnEvent.patch b/patches/api/Add-PlayerPostRespawnEvent.patch
index 6bd8835ee9..f601e87c6d 100644
--- a/patches/api/Add-PlayerPostRespawnEvent.patch
+++ b/patches/api/Add-PlayerPostRespawnEvent.patch
@@ -17,20 +17,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.event.HandlerList;
 +import org.bukkit.event.player.PlayerEvent;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
 +
 +/**
 + * Fired after a player has respawned
 + */
++@NullMarked
 +public class PlayerPostRespawnEvent extends PlayerEvent {
 +
-+    private final static HandlerList HANDLER_LIST = new HandlerList();
++    private static final HandlerList HANDLER_LIST = new HandlerList();
 +
 +    private final Location respawnedLocation;
 +    private final boolean isBedSpawn;
 +
 +    @ApiStatus.Internal
-+    public PlayerPostRespawnEvent(@NotNull final Player respawnPlayer, @NotNull final Location respawnedLocation, final boolean isBedSpawn) {
++    public PlayerPostRespawnEvent(final Player respawnPlayer, final Location respawnedLocation, final boolean isBedSpawn) {
 +        super(respawnPlayer);
 +        this.respawnedLocation = respawnedLocation;
 +        this.isBedSpawn = isBedSpawn;
@@ -41,7 +42,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return location of the respawned player
 +     */
-+    @NotNull
 +    public Location getRespawnedLocation() {
 +        return this.respawnedLocation.clone();
 +    }
@@ -56,12 +56,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
 +
 +    @Override
-+    @NotNull
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
 +
-+    @NotNull
 +    public static HandlerList getHandlerList() {
 +        return HANDLER_LIST;
 +    }
diff --git a/patches/api/Add-PlayerSetSpawnEvent.patch b/patches/api/Add-PlayerSetSpawnEvent.patch
index 85ebbf523c..8c6dfe4238 100644
--- a/patches/api/Add-PlayerSetSpawnEvent.patch
+++ b/patches/api/Add-PlayerSetSpawnEvent.patch
@@ -19,28 +19,29 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.event.HandlerList;
 +import org.bukkit.event.player.PlayerEvent;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
-+import org.jetbrains.annotations.Nullable;
++import org.jspecify.annotations.NullMarked;
++import org.jspecify.annotations.Nullable;
 +
 +/**
 + * Called when a player's spawn is set, either by themselves or otherwise.
 + * <br>
 + * Cancelling this event will prevent the spawn from being set.
 + */
++@NullMarked
 +public class PlayerSetSpawnEvent extends PlayerEvent implements Cancellable {
 +
 +    private static final HandlerList HANDLER_LIST = new HandlerList();
 +
 +    private final Cause cause;
-+    private Location location;
++    private @Nullable Location location;
 +    private boolean forced;
 +    private boolean notifyPlayer;
-+    private Component notification;
++    private @Nullable Component notification;
 +
 +    private boolean cancelled;
 +
 +    @ApiStatus.Internal
-+    public PlayerSetSpawnEvent(@NotNull Player player, @NotNull Cause cause, @Nullable Location location, boolean forced, boolean notifyPlayer, @Nullable Component notification) {
++    public PlayerSetSpawnEvent(final Player player, final Cause cause, final @Nullable Location location, final boolean forced, final boolean notifyPlayer, final @Nullable Component notification) {
 +        super(player);
 +        this.cause = cause;
 +        this.location = location;
@@ -54,7 +55,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return the cause
 +     */
-+    @NotNull
 +    public Cause getCause() {
 +        return this.cause;
 +    }
@@ -67,8 +67,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return the spawn location, or {@code null} if removing the location
 +     */
-+    @Nullable
-+    public Location getLocation() {
++    public @Nullable Location getLocation() {
 +        return this.location;
 +    }
 +
@@ -78,7 +77,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @param location the spawn location, or {@code null} to remove the spawn location
 +     */
-+    public void setLocation(@Nullable Location location) {
++    public void setLocation(final @Nullable Location location) {
 +        this.location = location;
 +    }
 +
@@ -96,7 +95,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @param forced {@code true} to force
 +     */
-+    public void setForced(boolean forced) {
++    public void setForced(final boolean forced) {
 +        this.forced = forced;
 +    }
 +
@@ -116,7 +115,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @param notifyPlayer {@code true} to notify
 +     */
-+    public void setNotifyPlayer(boolean notifyPlayer) {
++    public void setNotifyPlayer(final boolean notifyPlayer) {
 +        this.notifyPlayer = notifyPlayer;
 +    }
 +
@@ -126,8 +125,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return {@code null} if no notification
 +     */
-+    @Nullable
-+    public Component getNotification() {
++    public @Nullable Component getNotification() {
 +        return this.notification;
 +    }
 +
@@ -136,7 +134,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @param notification {@code null} to send no message
 +     */
-+    public void setNotification(@Nullable Component notification) {
++    public void setNotification(final @Nullable Component notification) {
 +        this.notification = notification;
 +    }
 +
@@ -146,16 +144,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
 +
 +    @Override
-+    public void setCancelled(boolean cancel) {
++    public void setCancelled(final boolean cancel) {
 +        this.cancelled = cancel;
 +    }
 +
 +    @Override
-+    public @NotNull HandlerList getHandlers() {
++    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
 +
-+    @NotNull
 +    public static HandlerList getHandlerList() {
 +        return HANDLER_LIST;
 +    }
diff --git a/patches/api/Add-PlayerShieldDisableEvent.patch b/patches/api/Add-PlayerShieldDisableEvent.patch
index 5eadfa4c77..858450e5c7 100644
--- a/patches/api/Add-PlayerShieldDisableEvent.patch
+++ b/patches/api/Add-PlayerShieldDisableEvent.patch
@@ -30,7 +30,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.event.HandlerList;
 +import org.bukkit.event.player.PlayerEvent;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
 +
 +/**
 + * Called whenever a players shield is disabled due to an attack from another entity that was capable of disabling the
@@ -41,6 +41,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 + * It follows that, if this event is cancelled, no {@link PlayerItemCooldownEvent} is called as the shield is never
 + * disabled in the first place.
 + */
++@NullMarked
 +public class PlayerShieldDisableEvent extends PlayerEvent implements Cancellable {
 +
 +    private static final HandlerList HANDLER_LIST = new HandlerList();
@@ -51,7 +52,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    private boolean cancelled;
 +
 +    @ApiStatus.Internal
-+    public PlayerShieldDisableEvent(@NotNull final Player player, @NotNull final Entity damager, final int cooldown) {
++    public PlayerShieldDisableEvent(final Player player, final Entity damager, final int cooldown) {
 +        super(player);
 +        this.damager = damager;
 +        this.cooldown = cooldown;
@@ -62,7 +63,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return the entity instance that damaged the player in a way that caused the shield to be disabled.
 +     */
-+    @NotNull
 +    public Entity getDamager() {
 +        return this.damager;
 +    }
@@ -87,7 +87,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @param cooldown cooldown in ticks, has to be a positive number
 +     */
-+    public void setCooldown(int cooldown) {
++    public void setCooldown(final int cooldown) {
 +        Preconditions.checkArgument(cooldown >= 0, "The cooldown has to be equal to or greater than 0!");
 +        this.cooldown = cooldown;
 +    }
@@ -102,13 +102,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        this.cancelled = cancel;
 +    }
 +
-+    @NotNull
 +    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
 +
-+    @NotNull
 +    public static HandlerList getHandlerList() {
 +        return HANDLER_LIST;
 +    }
diff --git a/patches/api/Add-PlayerSignCommandPreprocessEvent.patch b/patches/api/Add-PlayerSignCommandPreprocessEvent.patch
index e09d111827..da95f5dc4a 100644
--- a/patches/api/Add-PlayerSignCommandPreprocessEvent.patch
+++ b/patches/api/Add-PlayerSignCommandPreprocessEvent.patch
@@ -12,14 +12,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 @@ -0,0 +0,0 @@
 +package io.papermc.paper.event.player;
 +
++import java.util.Set;
 +import org.bukkit.block.Sign;
 +import org.bukkit.block.sign.Side;
 +import org.bukkit.entity.Player;
 +import org.bukkit.event.player.PlayerCommandPreprocessEvent;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
-+
-+import java.util.Set;
++import org.jspecify.annotations.NullMarked;
 +
 +/**
 + * Called when a {@link Player} clicks a side on a sign that causes a command to run.
@@ -27,13 +26,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 + * This command is run with elevated permissions which allows players to access commands on signs they wouldn't
 + * normally be able to run.
 + */
++@NullMarked
 +public class PlayerSignCommandPreprocessEvent extends PlayerCommandPreprocessEvent {
 +
 +    private final Sign sign;
 +    private final Side side;
 +
 +    @ApiStatus.Internal
-+    public PlayerSignCommandPreprocessEvent(@NotNull Player player, @NotNull String message, @NotNull Set<Player> recipients, @NotNull Sign sign, @NotNull Side side) {
++    public PlayerSignCommandPreprocessEvent(final Player player, final String message, final Set<Player> recipients, final Sign sign, final Side side) {
 +        super(player, message, recipients);
 +        this.sign = sign;
 +        this.side = side;
@@ -44,7 +44,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return the sign
 +     */
-+    public @NotNull Sign getSign() {
++    public Sign getSign() {
 +        return this.sign;
 +    }
 +
@@ -53,7 +53,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return the sign side
 +     */
-+    public @NotNull Side getSide() {
++    public Side getSide() {
 +        return this.side;
 +    }
 +}
diff --git a/patches/api/Add-PlayerStopUsingItemEvent.patch b/patches/api/Add-PlayerStopUsingItemEvent.patch
index 00d01b35a1..329f6cb16b 100644
--- a/patches/api/Add-PlayerStopUsingItemEvent.patch
+++ b/patches/api/Add-PlayerStopUsingItemEvent.patch
@@ -16,20 +16,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.event.HandlerList;
 +import org.bukkit.event.player.PlayerEvent;
 +import org.bukkit.inventory.ItemStack;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
 +
 +/**
 + * Called when the server detects a player stopping using an item.
 + * Examples of this are letting go of the interact button when holding a bow, an edible item, or a spyglass.
 + */
++@NullMarked
 +public class PlayerStopUsingItemEvent extends PlayerEvent {
 +
 +    private static final HandlerList HANDLER_LIST = new HandlerList();
 +
-+    @NotNull private final ItemStack item;
++    private final ItemStack item;
 +    private final int ticksHeldFor;
 +
-+    public PlayerStopUsingItemEvent(@NotNull final Player player, @NotNull final ItemStack item, final int ticksHeldFor) {
++    public PlayerStopUsingItemEvent(final Player player, final ItemStack item, final int ticksHeldFor) {
 +        super(player);
 +        this.item = item;
 +        this.ticksHeldFor = ticksHeldFor;
@@ -40,7 +41,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return ItemStack the exact item the player released
 +     */
-+    @NotNull
 +    public ItemStack getItem() {
 +        return this.item;
 +    }
@@ -54,13 +54,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        return this.ticksHeldFor;
 +    }
 +
-+    @NotNull
 +    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
 +
-+    @NotNull
 +    public static HandlerList getHandlerList() {
 +        return HANDLER_LIST;
 +    }
diff --git a/patches/api/Add-PlayerUseUnknownEntityEvent.patch b/patches/api/Add-PlayerUseUnknownEntityEvent.patch
index f37810e586..d399c2999e 100644
--- a/patches/api/Add-PlayerUseUnknownEntityEvent.patch
+++ b/patches/api/Add-PlayerUseUnknownEntityEvent.patch
@@ -23,8 +23,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.inventory.EquipmentSlot;
 +import org.bukkit.util.Vector;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
-+import org.jetbrains.annotations.Nullable;
++import org.jspecify.annotations.NullMarked;
++import org.jspecify.annotations.Nullable;
 +
 +/**
 + * Represents an event that is called when a player right-clicks an unknown entity.
@@ -33,17 +33,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 + * This event may be called multiple times per interaction with different interaction hands
 + * and with or without the clicked position.
 + */
++@NullMarked
 +public class PlayerUseUnknownEntityEvent extends PlayerEvent {
 +
 +    private static final HandlerList HANDLER_LIST = new HandlerList();
 +
 +    private final int entityId;
 +    private final boolean attack;
-+    private final @NotNull EquipmentSlot hand;
++    private final EquipmentSlot hand;
 +    private final @Nullable Vector clickedPosition;
 +
 +    @ApiStatus.Internal
-+    public PlayerUseUnknownEntityEvent(@NotNull Player player, int entityId, boolean attack, @NotNull EquipmentSlot hand, @Nullable Vector clickedPosition) {
++    public PlayerUseUnknownEntityEvent(final Player player, final int entityId, final boolean attack, final EquipmentSlot hand, final @Nullable Vector clickedPosition) {
 +        super(player);
 +        this.entityId = entityId;
 +        this.attack = attack;
@@ -74,7 +75,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return the hand used to interact
 +     */
-+    public @NotNull EquipmentSlot getHand() {
++    public EquipmentSlot getHand() {
 +        return this.hand;
 +    }
 +
@@ -89,13 +90,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        return this.clickedPosition != null ? this.clickedPosition.clone() : null;
 +    }
 +
-+    @NotNull
 +    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
 +
-+    @NotNull
 +    public static HandlerList getHandlerList() {
 +        return HANDLER_LIST;
 +    }
diff --git a/patches/api/Add-PrePlayerAttackEntityEvent.patch b/patches/api/Add-PrePlayerAttackEntityEvent.patch
index 2dd944464f..d6e180fda0 100644
--- a/patches/api/Add-PrePlayerAttackEntityEvent.patch
+++ b/patches/api/Add-PrePlayerAttackEntityEvent.patch
@@ -18,7 +18,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.event.HandlerList;
 +import org.bukkit.event.player.PlayerEvent;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
 +
 +/**
 + * Called when the player tries to attack an entity.
@@ -31,18 +31,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 + * <p>
 + * Note: there may be other factors (invulnerability, etc.) that will prevent this entity from being attacked that this event will not cover
 + */
++@NullMarked
 +public class PrePlayerAttackEntityEvent extends PlayerEvent implements Cancellable {
 +
 +    private static final HandlerList HANDLER_LIST = new HandlerList();
 +
-+    @NotNull
 +    private final Entity attacked;
 +    private final boolean willAttack;
 +
 +    private boolean cancelled;
 +
 +    @ApiStatus.Internal
-+    public PrePlayerAttackEntityEvent(@NotNull Player player, @NotNull Entity attacked, boolean willAttack) {
++    public PrePlayerAttackEntityEvent(final Player player, final Entity attacked, final boolean willAttack) {
 +        super(player);
 +        this.attacked = attacked;
 +        this.willAttack = willAttack;
@@ -54,7 +54,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return entity that was attacked
 +     */
-+    @NotNull
 +    public Entity getAttacked() {
 +        return this.attacked;
 +    }
@@ -84,7 +83,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * @param cancel {@code true} if you wish to cancel this event
 +     */
 +    @Override
-+    public void setCancelled(boolean cancel) {
++    public void setCancelled(final boolean cancel) {
 +        if (!this.willAttack) {
 +            return;
 +        }
@@ -92,13 +91,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        this.cancelled = cancel;
 +    }
 +
-+    @NotNull
 +    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
 +
-+    @NotNull
 +    public static HandlerList getHandlerList() {
 +        return HANDLER_LIST;
 +    }
diff --git a/patches/api/Add-PrepareResultEvent-PrepareGrindstoneEvent.patch b/patches/api/Add-PrepareResultEvent-PrepareGrindstoneEvent.patch
index 066f7b008b..f6b598beaa 100644
--- a/patches/api/Add-PrepareResultEvent-PrepareGrindstoneEvent.patch
+++ b/patches/api/Add-PrepareResultEvent-PrepareGrindstoneEvent.patch
@@ -79,6 +79,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return result item
 +     */
++    @Override
 +    public @Nullable ItemStack getResult() {
 +        return super.getResult();
 +    }
@@ -88,6 +89,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @param result result item
 +     */
++    @Override
 +    public void setResult(final @Nullable ItemStack result) {
 +        super.setResult(result);
 +    }
diff --git a/patches/api/Add-StructuresLocateEvent.patch b/patches/api/Add-StructuresLocateEvent.patch
index 92be15dbc0..9febf91f2a 100644
--- a/patches/api/Add-StructuresLocateEvent.patch
+++ b/patches/api/Add-StructuresLocateEvent.patch
@@ -24,9 +24,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.generator.structure.Structure;
 +import org.bukkit.generator.structure.StructureType;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
-+import org.jetbrains.annotations.Nullable;
 +import org.jetbrains.annotations.UnmodifiableView;
++import org.jspecify.annotations.NullMarked;
++import org.jspecify.annotations.Nullable;
 +
 +/**
 + * Called <b>before</b> a set of configured structures is located.
@@ -41,12 +41,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 + *     <li>{@link World#locateNearestStructure(Location, Structure, int, boolean)} is invoked.</li>
 + * </ul>
 + */
++@NullMarked
 +public class StructuresLocateEvent extends WorldEvent implements Cancellable {
 +
 +    private static final HandlerList HANDLER_LIST = new HandlerList();
 +
 +    private final Location origin;
-+    private Result result;
++    private @Nullable Result result;
 +    private List<Structure> structures;
 +    private int radius;
 +    private boolean findUnexplored;
@@ -54,7 +55,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    private boolean cancelled;
 +
 +    @ApiStatus.Internal
-+    public StructuresLocateEvent(@NotNull World world, @NotNull Location origin, @NotNull List<Structure> structures, int radius, boolean findUnexplored) {
++    public StructuresLocateEvent(final World world, final Location origin, final List<Structure> structures, final int radius, final boolean findUnexplored) {
 +        super(world);
 +        this.origin = origin;
 +        this.structures = structures;
@@ -67,7 +68,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return {@link Location} where search begins
 +     */
-+    public @NotNull Location getOrigin() {
++    public Location getOrigin() {
 +        return this.origin.clone();
 +    }
 +
@@ -90,7 +91,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @param result the {@link Location} and {@link Structure} of the search.
 +     */
-+    public void setResult(@Nullable Result result) {
++    public void setResult(final @Nullable Result result) {
 +        this.result = result;
 +    }
 +
@@ -99,7 +100,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return an unmodifiable list of Structures
 +     */
-+    public @NotNull @UnmodifiableView List<Structure> getStructures() {
++    public @UnmodifiableView List<Structure> getStructures() {
 +        return Collections.unmodifiableList(this.structures);
 +    }
 +
@@ -108,7 +109,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @param structures a list of Structures targets
 +     */
-+    public void setStructures(final @NotNull List<Structure> structures) {
++    public void setStructures(final List<Structure> structures) {
 +        this.structures = structures;
 +    }
 +
@@ -130,7 +131,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @param radius the search radius (in chunks)
 +     */
-+    public void setRadius(int radius) {
++    public void setRadius(final int radius) {
 +        this.radius = radius;
 +    }
 +
@@ -152,7 +153,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @param findUnexplored Whether to search for only unexplored structures.
 +     */
-+    public void setFindUnexplored(boolean findUnexplored) {
++    public void setFindUnexplored(final boolean findUnexplored) {
 +        this.findUnexplored = findUnexplored;
 +    }
 +
@@ -162,26 +163,26 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
 +
 +    @Override
-+    public void setCancelled(boolean cancel) {
++    public void setCancelled(final boolean cancel) {
 +        this.cancelled = cancel;
 +    }
 +
 +    @Override
-+    public @NotNull HandlerList getHandlers() {
++    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
 +
-+    public static @NotNull HandlerList getHandlerList() {
++    public static HandlerList getHandlerList() {
 +        return HANDLER_LIST;
 +    }
 +
 +    /**
 +     * Result for {@link StructuresLocateEvent}.
 +     */
-+    public record Result(@NotNull Position pos, @NotNull Structure structure) {
++    public record Result(Position pos, Structure structure) {
 +
 +        @Deprecated(forRemoval = true)
-+        public @NotNull Location position() {
++        public Location position() {
 +            //noinspection DataFlowIssue
 +            return this.pos.toLocation(null);
 +        }
diff --git a/patches/api/Add-and-implement-PlayerRecipeBookClickEvent.patch b/patches/api/Add-and-implement-PlayerRecipeBookClickEvent.patch
index 7055e92701..d6e2156c95 100644
--- a/patches/api/Add-and-implement-PlayerRecipeBookClickEvent.patch
+++ b/patches/api/Add-and-implement-PlayerRecipeBookClickEvent.patch
@@ -18,22 +18,23 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.event.HandlerList;
 +import org.bukkit.event.player.PlayerEvent;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
 +
 +/**
 + * Called when a player clicks a recipe in the recipe book
 + */
++@NullMarked
 +public class PlayerRecipeBookClickEvent extends PlayerEvent implements Cancellable {
 +
 +    private static final HandlerList HANDLER_LIST = new HandlerList();
 +
-+    @NotNull private NamespacedKey recipe;
++    private NamespacedKey recipe;
 +    private boolean makeAll;
 +
 +    private boolean cancelled;
 +
 +    @ApiStatus.Internal
-+    public PlayerRecipeBookClickEvent(@NotNull Player player, @NotNull NamespacedKey recipe, boolean makeAll) {
++    public PlayerRecipeBookClickEvent(final Player player, final NamespacedKey recipe, final boolean makeAll) {
 +        super(player);
 +        this.recipe = recipe;
 +        this.makeAll = makeAll;
@@ -44,7 +45,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return The namespaced key of the recipe
 +     */
-+    @NotNull
 +    public NamespacedKey getRecipe() {
 +        return this.recipe;
 +    }
@@ -54,7 +54,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @param recipe The key of the recipe that should be requested
 +     */
-+    public void setRecipe(@NotNull NamespacedKey recipe) {
++    public void setRecipe(final NamespacedKey recipe) {
 +        this.recipe = recipe;
 +    }
 +
@@ -74,7 +74,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @param makeAll {@code true} if the request should attempt to make the maximum amount of results
 +     */
-+    public void setMakeAll(boolean makeAll) {
++    public void setMakeAll(final boolean makeAll) {
 +        this.makeAll = makeAll;
 +    }
 +
@@ -84,17 +84,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
 +
 +    @Override
-+    public void setCancelled(boolean cancel) {
++    public void setCancelled(final boolean cancel) {
 +        this.cancelled = cancel;
 +    }
 +
-+    @NotNull
 +    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
 +
-+    @NotNull
 +    public static HandlerList getHandlerList() {
 +        return HANDLER_LIST;
 +    }
diff --git a/patches/api/Add-event-for-player-editing-sign.patch b/patches/api/Add-event-for-player-editing-sign.patch
index d52c886c5a..a498062b6e 100644
--- a/patches/api/Add-event-for-player-editing-sign.patch
+++ b/patches/api/Add-event-for-player-editing-sign.patch
@@ -20,13 +20,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.event.HandlerList;
 +import org.bukkit.event.player.PlayerEvent;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
 +
 +/**
 + * Called when a player begins editing a sign's text.
 + * <p>
 + * Cancelling this event stops the sign editing menu from opening.
 + */
++@NullMarked
 +public class PlayerOpenSignEvent extends PlayerEvent implements Cancellable {
 +
 +    private static final HandlerList HANDLER_LIST = new HandlerList();
@@ -38,7 +39,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    private boolean cancelled;
 +
 +    @ApiStatus.Internal
-+    public PlayerOpenSignEvent(final @NotNull Player editor, final @NotNull Sign sign, final @NotNull Side side, final @NotNull Cause cause) {
++    public PlayerOpenSignEvent(final Player editor, final Sign sign, final Side side, final Cause cause) {
 +        super(editor);
 +        this.sign = sign;
 +        this.side = side;
@@ -50,7 +51,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return {@link Sign} that was clicked
 +     */
-+    @NotNull
 +    public Sign getSign() {
 +        return this.sign;
 +    }
@@ -61,7 +61,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * @return {@link Side} that was clicked
 +     * @see Sign#getSide(Side)
 +     */
-+    @NotNull
 +    public Side getSide() {
 +        return this.side;
 +    }
@@ -71,7 +70,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return the cause
 +     */
-+    public @NotNull Cause getCause() {
++    public Cause getCause() {
 +        return this.cause;
 +    }
 +
@@ -81,17 +80,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
 +
 +    @Override
-+    public void setCancelled(boolean cancel) {
++    public void setCancelled(final boolean cancel) {
 +        this.cancelled = cancel;
 +    }
 +
-+    @NotNull
 +    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
 +
-+    @NotNull
 +    public static HandlerList getHandlerList() {
 +        return HANDLER_LIST;
 +    }
diff --git a/patches/api/Add-exception-reporting-event.patch b/patches/api/Add-exception-reporting-event.patch
index 14c5ddfe0d..7e603c4576 100644
--- a/patches/api/Add-exception-reporting-event.patch
+++ b/patches/api/Add-exception-reporting-event.patch
@@ -12,24 +12,25 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 @@ -0,0 +0,0 @@
 +package com.destroystokyo.paper.event.server;
 +
++import com.destroystokyo.paper.exception.ServerException;
 +import org.bukkit.Bukkit;
 +import org.bukkit.event.Event;
 +import org.bukkit.event.HandlerList;
-+import com.destroystokyo.paper.exception.ServerException;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
 +
 +/**
 + * Called whenever an exception is thrown in a recoverable section of the server.
 + */
++@NullMarked
 +public class ServerExceptionEvent extends Event {
 +
 +    private static final HandlerList HANDLER_LIST = new HandlerList();
 +
-+    @NotNull private final ServerException exception;
++    private final ServerException exception;
 +
 +    @ApiStatus.Internal
-+    public ServerExceptionEvent(@NotNull ServerException exception) {
++    public ServerExceptionEvent(final ServerException exception) {
 +        super(!Bukkit.isPrimaryThread());
 +        this.exception = exception;
 +    }
@@ -39,18 +40,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return Exception thrown
 +     */
-+    @NotNull
 +    public ServerException getException() {
 +        return this.exception;
 +    }
 +
-+    @NotNull
 +    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
 +
-+    @NotNull
 +    public static HandlerList getHandlerList() {
 +        return HANDLER_LIST;
 +    }
diff --git a/patches/api/Add-legacy-ping-support-to-PaperServerListPingEvent.patch b/patches/api/Add-legacy-ping-support-to-PaperServerListPingEvent.patch
index 124b2f221e..67d0480df5 100644
--- a/patches/api/Add-legacy-ping-support-to-PaperServerListPingEvent.patch
+++ b/patches/api/Add-legacy-ping-support-to-PaperServerListPingEvent.patch
@@ -17,7 +17,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
  
 +    /**
 +     * Returns whether the client is using an older version that doesn't
-+     * support all of the features in {@link PaperServerListPingEvent}.
++     * support all the features in {@link PaperServerListPingEvent}.
 +     *
 +     * <p>For Vanilla, this returns {@code true} for all clients older than 1.7.</p>
 +     *
diff --git a/patches/api/Add-paper-dumplisteners-command.patch b/patches/api/Add-paper-dumplisteners-command.patch
index abdb47e4bd..0c484672a0 100644
--- a/patches/api/Add-paper-dumplisteners-command.patch
+++ b/patches/api/Add-paper-dumplisteners-command.patch
@@ -23,21 +23,21 @@ diff --git a/src/main/java/com/destroystokyo/paper/event/executor/MethodHandleEv
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/com/destroystokyo/paper/event/executor/MethodHandleEventExecutor.java
 +++ b/src/main/java/com/destroystokyo/paper/event/executor/MethodHandleEventExecutor.java
-@@ -0,0 +0,0 @@ import org.jetbrains.annotations.NotNull;
- public class MethodHandleEventExecutor implements EventExecutor {
+@@ -0,0 +0,0 @@ public class MethodHandleEventExecutor implements EventExecutor {
+ 
      private final Class<? extends Event> eventClass;
      private final MethodHandle handle;
-+    private final Method method;
++    private final @Nullable Method method;
  
-     public MethodHandleEventExecutor(@NotNull Class<? extends Event> eventClass, @NotNull MethodHandle handle) {
+     public MethodHandleEventExecutor(final Class<? extends Event> eventClass, final MethodHandle handle) {
          this.eventClass = eventClass;
          this.handle = handle;
 +        this.method = null;
      }
  
-     public MethodHandleEventExecutor(@NotNull Class<? extends Event> eventClass, @NotNull Method m) {
+     public MethodHandleEventExecutor(final Class<? extends Event> eventClass, final Method m) {
 @@ -0,0 +0,0 @@ public class MethodHandleEventExecutor implements EventExecutor {
-         } catch (IllegalAccessException e) {
+         } catch (final IllegalAccessException e) {
              throw new AssertionError("Unable to set accessible", e);
          }
 +        this.method = m;
@@ -50,7 +50,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      }
 +
 +    @Override
-+    @NotNull
 +    public String toString() {
 +        return "MethodHandleEventExecutor['" + this.method + "']";
 +    }
@@ -59,16 +58,16 @@ diff --git a/src/main/java/com/destroystokyo/paper/event/executor/StaticMethodHa
 index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
 --- a/src/main/java/com/destroystokyo/paper/event/executor/StaticMethodHandleEventExecutor.java
 +++ b/src/main/java/com/destroystokyo/paper/event/executor/StaticMethodHandleEventExecutor.java
-@@ -0,0 +0,0 @@ import org.jetbrains.annotations.NotNull;
- public class StaticMethodHandleEventExecutor implements EventExecutor {
+@@ -0,0 +0,0 @@ public class StaticMethodHandleEventExecutor implements EventExecutor {
+ 
      private final Class<? extends Event> eventClass;
      private final MethodHandle handle;
 +    private final Method method;
  
-     public StaticMethodHandleEventExecutor(@NotNull Class<? extends Event> eventClass, @NotNull Method m) {
+     public StaticMethodHandleEventExecutor(final Class<? extends Event> eventClass, final Method m) {
          Preconditions.checkArgument(Modifier.isStatic(m.getModifiers()), "Not a static method: %s", m);
 @@ -0,0 +0,0 @@ public class StaticMethodHandleEventExecutor implements EventExecutor {
-         } catch (IllegalAccessException e) {
+         } catch (final IllegalAccessException e) {
              throw new AssertionError("Unable to set accessible", e);
          }
 +        this.method = m;
@@ -81,7 +80,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
      }
 +
 +    @Override
-+    @NotNull
 +    public String toString() {
 +        return "StaticMethodHandleEventExecutor['" + this.method + "']";
 +    }
diff --git a/patches/api/Add-spectator-target-events.patch b/patches/api/Add-spectator-target-events.patch
index 52c1ecf707..46569f1a86 100644
--- a/patches/api/Add-spectator-target-events.patch
+++ b/patches/api/Add-spectator-target-events.patch
@@ -20,22 +20,23 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.event.HandlerList;
 +import org.bukkit.event.player.PlayerEvent;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
 +
 +/**
 + * Triggered when a player starts spectating an entity in spectator mode.
 + */
++@NullMarked
 +public class PlayerStartSpectatingEntityEvent extends PlayerEvent implements Cancellable {
 +
 +    private static final HandlerList HANDLER_LIST = new HandlerList();
 +
-+    @NotNull private final Entity currentSpectatorTarget;
-+    @NotNull private final Entity newSpectatorTarget;
++    private final Entity currentSpectatorTarget;
++    private final Entity newSpectatorTarget;
 +
 +    private boolean cancelled;
 +
 +    @ApiStatus.Internal
-+    public PlayerStartSpectatingEntityEvent(@NotNull Player player, @NotNull Entity currentSpectatorTarget, @NotNull Entity newSpectatorTarget) {
++    public PlayerStartSpectatingEntityEvent(final Player player, final Entity currentSpectatorTarget, final Entity newSpectatorTarget) {
 +        super(player);
 +        this.currentSpectatorTarget = currentSpectatorTarget;
 +        this.newSpectatorTarget = newSpectatorTarget;
@@ -46,7 +47,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return The entity the player is currently spectating (before they start spectating the new target).
 +     */
-+    @NotNull
 +    public Entity getCurrentSpectatorTarget() {
 +        return this.currentSpectatorTarget;
 +    }
@@ -56,7 +56,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return The entity the player is now going to be spectating.
 +     */
-+    @NotNull
 +    public Entity getNewSpectatorTarget() {
 +        return this.newSpectatorTarget;
 +    }
@@ -67,17 +66,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
 +
 +    @Override
-+    public void setCancelled(boolean cancel) {
++    public void setCancelled(final boolean cancel) {
 +        this.cancelled = cancel;
 +    }
 +
-+    @NotNull
 +    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
 +
-+    @NotNull
 +    public static HandlerList getHandlerList() {
 +        return HANDLER_LIST;
 +    }
@@ -97,20 +94,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.event.HandlerList;
 +import org.bukkit.event.player.PlayerEvent;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
 +
 +/**
 + * Triggered when a player stops spectating an entity in spectator mode.
 + */
++@NullMarked
 +public class PlayerStopSpectatingEntityEvent extends PlayerEvent implements Cancellable {
 +
 +    private static final HandlerList HANDLER_LIST = new HandlerList();
 +
-+    @NotNull private final Entity spectatorTarget;
++    private final Entity spectatorTarget;
 +    private boolean cancelled;
 +
 +    @ApiStatus.Internal
-+    public PlayerStopSpectatingEntityEvent(@NotNull Player player, @NotNull Entity spectatorTarget) {
++    public PlayerStopSpectatingEntityEvent(final Player player, final Entity spectatorTarget) {
 +        super(player);
 +        this.spectatorTarget = spectatorTarget;
 +    }
@@ -120,7 +118,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return The entity the player is currently spectating (before they will stop).
 +     */
-+    @NotNull
 +    public Entity getSpectatorTarget() {
 +        return this.spectatorTarget;
 +    }
@@ -131,17 +128,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
 +
 +    @Override
-+    public void setCancelled(boolean cancel) {
++    public void setCancelled(final boolean cancel) {
 +        this.cancelled = cancel;
 +    }
 +
-+    @NotNull
 +    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
 +
-+    @NotNull
 +    public static HandlerList getHandlerList() {
 +        return HANDLER_LIST;
 +    }
diff --git a/patches/api/Add-villager-reputation-API.patch b/patches/api/Add-villager-reputation-API.patch
index 843e1bdebf..7f2096ac3c 100644
--- a/patches/api/Add-villager-reputation-API.patch
+++ b/patches/api/Add-villager-reputation-API.patch
@@ -17,20 +17,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import java.util.EnumMap;
 +import java.util.Map;
 +import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
 +
 +/**
 + * A reputation score for a player on a villager.
 + */
++@NullMarked
 +public final class Reputation {
 +
-+    @NotNull
 +    private final Map<ReputationType, Integer> reputation;
 +
 +    public Reputation() {
 +        this(new EnumMap<>(ReputationType.class));
 +    }
 +
-+    public Reputation(@NotNull Map<ReputationType, Integer> reputation) {
++    public Reputation(Map<ReputationType, Integer> reputation) {
 +        Preconditions.checkNotNull(reputation, "reputation cannot be null");
 +        this.reputation = reputation;
 +    }
@@ -41,7 +42,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * @param type The {@link ReputationType type} of reputation to get.
 +     * @return The value of the {@link ReputationType type}.
 +     */
-+    public int getReputation(@NotNull ReputationType type) {
++    public int getReputation(ReputationType type) {
 +        Preconditions.checkNotNull(type, "the reputation type cannot be null");
 +        return this.reputation.getOrDefault(type, 0);
 +    }
@@ -52,7 +53,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * @param type The {@link ReputationType type} of reputation to set.
 +     * @param value The value of the {@link ReputationType type}.
 +     */
-+    public void setReputation(@NotNull ReputationType type, int value) {
++    public void setReputation(ReputationType type, int value) {
 +        Preconditions.checkNotNull(type, "the reputation type cannot be null");
 +        this.reputation.put(type, value);
 +    }
@@ -63,7 +64,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * @param type The {@link ReputationType type} to check
 +     * @return If there is a value for this {@link ReputationType type} set.
 +     */
-+    public boolean hasReputationSet(@NotNull ReputationType type) {
++    public boolean hasReputationSet(ReputationType type) {
 +        return this.reputation.containsKey(type);
 +    }
 +}
diff --git a/patches/api/Add-workaround-for-plugins-modifying-the-parent-of-t.patch b/patches/api/Add-workaround-for-plugins-modifying-the-parent-of-t.patch
index ff4691499f..eac8221ce2 100644
--- a/patches/api/Add-workaround-for-plugins-modifying-the-parent-of-t.patch
+++ b/patches/api/Add-workaround-for-plugins-modifying-the-parent-of-t.patch
@@ -21,26 +21,24 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +package com.destroystokyo.paper.utils;
 +
 +import io.papermc.paper.plugin.configuration.PluginMeta;
-+import org.bukkit.plugin.PluginDescriptionFile;
-+
 +import java.util.logging.Level;
 +import java.util.logging.LogManager;
 +import java.util.logging.Logger;
-+import org.jetbrains.annotations.NotNull;
++import org.bukkit.plugin.PluginDescriptionFile;
++import org.jspecify.annotations.NullMarked;
 +
 +/**
 + * Prevents plugins (e.g. Essentials) from changing the parent of the plugin logger.
 + */
++@NullMarked
 +public class PaperPluginLogger extends Logger {
 +
 +    @Deprecated(forRemoval = true)
-+    @NotNull
-+    public static Logger getLogger(@NotNull PluginDescriptionFile description) {
++    public static Logger getLogger(final PluginDescriptionFile description) {
 +        return getLogger((PluginMeta) description);
 +    }
 +
-+    @NotNull
-+    public static Logger getLogger(@NotNull PluginMeta meta) {
++    public static Logger getLogger(final PluginMeta meta) {
 +        Logger logger = new PaperPluginLogger(meta);
 +        if (!LogManager.getLogManager().addLogger(logger)) {
 +            // Disable this if it's going to happen across reloads anyways...
@@ -51,14 +49,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        return logger;
 +    }
 +
-+    private PaperPluginLogger(@NotNull PluginMeta meta) {
++    private PaperPluginLogger(final PluginMeta meta) {
 +        super(meta.getLoggerPrefix() != null ? meta.getLoggerPrefix() : meta.getName(), null);
 +    }
 +
 +    @Override
-+    public void setParent(@NotNull Logger parent) {
-+        if (getParent() != null) {
-+            warning("Ignoring attempt to change parent of plugin logger");
++    public void setParent(final Logger parent) {
++        if (this.getParent() != null) {
++            this.warning("Ignoring attempt to change parent of plugin logger");
 +        } else {
 +            this.log(Level.FINE, "Setting plugin logger parent to {0}", parent);
 +            super.setParent(parent);
diff --git a/patches/api/Add-worldborder-events.patch b/patches/api/Add-worldborder-events.patch
index 273da4b0e9..0d97a60a76 100644
--- a/patches/api/Add-worldborder-events.patch
+++ b/patches/api/Add-worldborder-events.patch
@@ -17,11 +17,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.event.Cancellable;
 +import org.bukkit.event.HandlerList;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
 +
 +/**
 + * Called when a world border changes its bounds, either over time, or instantly.
 + */
++@NullMarked
 +public class WorldBorderBoundsChangeEvent extends WorldBorderEvent implements Cancellable {
 +
 +    private static final HandlerList HANDLER_LIST = new HandlerList();
@@ -33,7 +34,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    private boolean cancelled;
 +
 +    @ApiStatus.Internal
-+    public WorldBorderBoundsChangeEvent(@NotNull World world, @NotNull WorldBorder worldBorder, @NotNull Type type, double oldSize, double newSize, long duration) {
++    public WorldBorderBoundsChangeEvent(final World world, final WorldBorder worldBorder, final Type type, final double oldSize, final double newSize, final long duration) {
 +        super(world, worldBorder);
 +        this.type = type;
 +        this.oldSize = oldSize;
@@ -46,7 +47,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return the change type
 +     */
-+    @NotNull
 +    public Type getType() {
 +        return this.type;
 +    }
@@ -74,7 +74,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @param newSize the new size
 +     */
-+    public void setNewSize(double newSize) {
++    public void setNewSize(final double newSize) {
 +        this.newSize = Math.min(this.worldBorder.getMaxSize(), Math.max(1.0D, newSize));
 +    }
 +
@@ -93,7 +93,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @param duration the time in milliseconds for the change
 +     */
-+    public void setDuration(long duration) {
++    public void setDuration(final long duration) {
 +        // PAIL: TODO: Magic Values
 +        this.duration = Math.min(9223372036854775L, Math.max(0L, duration));
 +        if (duration >= 0 && this.type == Type.INSTANT_MOVE) {
@@ -107,17 +107,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
 +
 +    @Override
-+    public void setCancelled(boolean cancel) {
++    public void setCancelled(final boolean cancel) {
 +        this.cancelled = cancel;
 +    }
 +
-+    @NotNull
 +    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
 +
-+    @NotNull
 +    public static HandlerList getHandlerList() {
 +        return HANDLER_LIST;
 +    }
@@ -139,11 +137,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.WorldBorder;
 +import org.bukkit.event.HandlerList;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
 +
 +/**
 + * Called when a moving world border has finished its move.
 + */
++@NullMarked
 +public class WorldBorderBoundsChangeFinishEvent extends WorldBorderEvent {
 +
 +    private static final HandlerList HANDLER_LIST = new HandlerList();
@@ -153,7 +152,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    private final double duration;
 +
 +    @ApiStatus.Internal
-+    public WorldBorderBoundsChangeFinishEvent(@NotNull World world, @NotNull WorldBorder worldBorder, double oldSize, double newSize, double duration) {
++    public WorldBorderBoundsChangeFinishEvent(final World world, final WorldBorder worldBorder, final double oldSize, final double newSize, final double duration) {
 +        super(world, worldBorder);
 +        this.oldSize = oldSize;
 +        this.newSize = newSize;
@@ -189,13 +188,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        return this.duration;
 +    }
 +
-+    @NotNull
 +    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
 +
-+    @NotNull
 +    public static HandlerList getHandlerList() {
 +        return HANDLER_LIST;
 +    }
@@ -214,11 +211,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.event.Cancellable;
 +import org.bukkit.event.HandlerList;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
 +
 +/**
 + * Called when a world border's center is changed.
 + */
++@NullMarked
 +public class WorldBorderCenterChangeEvent extends WorldBorderEvent implements Cancellable {
 +
 +    private static final HandlerList HANDLER_LIST = new HandlerList();
@@ -229,7 +227,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    private boolean cancelled;
 +
 +    @ApiStatus.Internal
-+    public WorldBorderCenterChangeEvent(@NotNull World world, @NotNull WorldBorder worldBorder, @NotNull Location oldCenter, @NotNull Location newCenter) {
++    public WorldBorderCenterChangeEvent(final World world, final WorldBorder worldBorder, final Location oldCenter, final Location newCenter) {
 +        super(world, worldBorder);
 +        this.oldCenter = oldCenter;
 +        this.newCenter = newCenter;
@@ -240,7 +238,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return the old center
 +     */
-+    @NotNull
 +    public Location getOldCenter() {
 +        return this.oldCenter.clone();
 +    }
@@ -250,7 +247,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return the new center
 +     */
-+    @NotNull
 +    public Location getNewCenter() {
 +        return this.newCenter;
 +    }
@@ -260,7 +256,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @param newCenter the new center
 +     */
-+    public void setNewCenter(@NotNull Location newCenter) {
++    public void setNewCenter(final Location newCenter) {
 +        this.newCenter = newCenter;
 +    }
 +
@@ -270,17 +266,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
 +
 +    @Override
-+    public void setCancelled(boolean cancel) {
++    public void setCancelled(final boolean cancel) {
 +        this.cancelled = cancel;
 +    }
 +
-+    @NotNull
 +    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
 +
-+    @NotNull
 +    public static HandlerList getHandlerList() {
 +        return HANDLER_LIST;
 +    }
@@ -297,19 +291,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.WorldBorder;
 +import org.bukkit.event.world.WorldEvent;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
 +
++@NullMarked
 +public abstract class WorldBorderEvent extends WorldEvent {
 +
 +    protected final WorldBorder worldBorder;
 +
 +    @ApiStatus.Internal
-+    protected WorldBorderEvent(@NotNull World world, @NotNull WorldBorder worldBorder) {
++    protected WorldBorderEvent(final World world, final WorldBorder worldBorder) {
 +        super(world);
 +        this.worldBorder = worldBorder;
 +    }
 +
-+    @NotNull
 +    public WorldBorder getWorldBorder() {
 +        return this.worldBorder;
 +    }
diff --git a/patches/api/Added-PlayerBedFailEnterEvent.patch b/patches/api/Added-PlayerBedFailEnterEvent.patch
index eff5f28a33..0761063aa6 100644
--- a/patches/api/Added-PlayerBedFailEnterEvent.patch
+++ b/patches/api/Added-PlayerBedFailEnterEvent.patch
@@ -19,9 +19,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.event.HandlerList;
 +import org.bukkit.event.player.PlayerEvent;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
-+import org.jetbrains.annotations.Nullable;
++import org.jspecify.annotations.NullMarked;
++import org.jspecify.annotations.Nullable;
 +
++@NullMarked
 +public class PlayerBedFailEnterEvent extends PlayerEvent implements Cancellable {
 +
 +    private static final HandlerList HANDLER_LIST = new HandlerList();
@@ -29,12 +30,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    private final FailReason failReason;
 +    private final Block bed;
 +    private boolean willExplode;
-+    private Component message;
++    private @Nullable Component message;
 +
 +    private boolean cancelled;
 +
 +    @ApiStatus.Internal
-+    public PlayerBedFailEnterEvent(@NotNull Player player, @NotNull FailReason failReason, @NotNull Block bed, boolean willExplode, @Nullable Component message) {
++    public PlayerBedFailEnterEvent(final Player player, final FailReason failReason, final Block bed, final boolean willExplode, final @Nullable Component message) {
 +        super(player);
 +        this.failReason = failReason;
 +        this.bed = bed;
@@ -42,12 +43,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        this.message = message;
 +    }
 +
-+    @NotNull
 +    public FailReason getFailReason() {
 +        return this.failReason;
 +    }
 +
-+    @NotNull
 +    public Block getBed() {
 +        return this.bed;
 +    }
@@ -56,16 +55,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        return this.willExplode;
 +    }
 +
-+    public void setWillExplode(boolean willExplode) {
++    public void setWillExplode(final boolean willExplode) {
 +        this.willExplode = willExplode;
 +    }
 +
-+    @Nullable
-+    public Component getMessage() {
++    public @Nullable Component getMessage() {
 +        return this.message;
 +    }
 +
-+    public void setMessage(@Nullable Component message) {
++    public void setMessage(final @Nullable Component message) {
 +        this.message = message;
 +    }
 +
@@ -81,17 +79,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * that may occur because of the interaction.
 +     */
 +    @Override
-+    public void setCancelled(boolean cancel) {
++    public void setCancelled(final boolean cancel) {
 +        this.cancelled = cancel;
 +    }
 +
-+    @NotNull
 +    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
 +
-+    @NotNull
 +    public static HandlerList getHandlerList() {
 +        return HANDLER_LIST;
 +    }
diff --git a/patches/api/Added-PlayerChangeBeaconEffectEvent.patch b/patches/api/Added-PlayerChangeBeaconEffectEvent.patch
index 741e023b05..4aa79119ac 100644
--- a/patches/api/Added-PlayerChangeBeaconEffectEvent.patch
+++ b/patches/api/Added-PlayerChangeBeaconEffectEvent.patch
@@ -19,25 +19,26 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.event.player.PlayerEvent;
 +import org.bukkit.potion.PotionEffectType;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
-+import org.jetbrains.annotations.Nullable;
++import org.jspecify.annotations.NullMarked;
++import org.jspecify.annotations.Nullable;
 +
 +/**
 + * Called when a player sets the effect for a beacon
 + */
++@NullMarked
 +public class PlayerChangeBeaconEffectEvent extends PlayerEvent implements Cancellable {
 +
 +    private static final HandlerList HANDLER_LIST = new HandlerList();
 +
 +    private final Block beacon;
-+    private PotionEffectType primary;
-+    private PotionEffectType secondary;
++    private @Nullable PotionEffectType primary;
++    private @Nullable PotionEffectType secondary;
 +    private boolean consumeItem = true;
 +
 +    private boolean cancelled;
 +
 +    @ApiStatus.Internal
-+    public PlayerChangeBeaconEffectEvent(@NotNull Player player, @Nullable PotionEffectType primary, @Nullable PotionEffectType secondary, @NotNull Block beacon) {
++    public PlayerChangeBeaconEffectEvent(final Player player, final @Nullable PotionEffectType primary, final @Nullable PotionEffectType secondary, final Block beacon) {
 +        super(player);
 +        this.primary = primary;
 +        this.secondary = secondary;
@@ -47,7 +48,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    /**
 +     * @return the primary effect
 +     */
-+    @Nullable public PotionEffectType getPrimary() {
++    public @Nullable PotionEffectType getPrimary() {
 +        return this.primary;
 +    }
 +
@@ -58,14 +59,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @param primary the primary effect
 +     */
-+    public void setPrimary(@Nullable PotionEffectType primary) {
++    public void setPrimary(final @Nullable PotionEffectType primary) {
 +        this.primary = primary;
 +    }
 +
 +    /**
 +     * @return the secondary effect
 +     */
-+    @Nullable public PotionEffectType getSecondary() {
++    public @Nullable PotionEffectType getSecondary() {
 +        return this.secondary;
 +    }
 +
@@ -77,14 +78,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @param secondary the secondary effect
 +     */
-+    public void setSecondary(@Nullable PotionEffectType secondary) {
++    public void setSecondary(final @Nullable PotionEffectType secondary) {
 +        this.secondary = secondary;
 +    }
 +
 +    /**
 +     * @return the beacon block associated with this event
 +     */
-+    @NotNull
 +    public Block getBeacon() {
 +        return this.beacon;
 +    }
@@ -109,7 +109,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @param consumeItem {@code true} if item should be consumed
 +     */
-+    public void setConsumeItem(boolean consumeItem) {
++    public void setConsumeItem(final boolean consumeItem) {
 +        this.consumeItem = consumeItem;
 +    }
 +
@@ -133,16 +133,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * or saved.
 +     */
 +    @Override
-+    public void setCancelled(boolean cancel) {
++    public void setCancelled(final boolean cancel) {
 +        this.cancelled = cancel;
 +    }
 +
 +    @Override
-+    public @NotNull HandlerList getHandlers() {
++    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
 +
-+    @NotNull
 +    public static HandlerList getHandlerList() {
 +        return HANDLER_LIST;
 +    }
diff --git a/patches/api/Added-PlayerDeepSleepEvent.patch b/patches/api/Added-PlayerDeepSleepEvent.patch
index c78c4cb01a..9899504cbe 100644
--- a/patches/api/Added-PlayerDeepSleepEvent.patch
+++ b/patches/api/Added-PlayerDeepSleepEvent.patch
@@ -17,7 +17,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.event.HandlerList;
 +import org.bukkit.event.player.PlayerEvent;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
 +
 +/**
 + * Called when a player has slept long enough
@@ -26,6 +26,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 + * Cancelling this event will prevent the player from being counted as deeply sleeping
 + * unless they exit and re-enter the bed.
 + */
++@NullMarked
 +public class PlayerDeepSleepEvent extends PlayerEvent implements Cancellable {
 +
 +    private static final HandlerList HANDLER_LIST = new HandlerList();
@@ -33,7 +34,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    private boolean cancelled;
 +
 +    @ApiStatus.Internal
-+    public PlayerDeepSleepEvent(@NotNull Player player) {
++    public PlayerDeepSleepEvent(final Player player) {
 +        super(player);
 +    }
 +
@@ -43,17 +44,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
 +
 +    @Override
-+    public void setCancelled(boolean cancel) {
++    public void setCancelled(final boolean cancel) {
 +        this.cancelled = cancel;
 +    }
 +
-+    @NotNull
 +    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
 +
-+    @NotNull
 +    public static HandlerList getHandlerList() {
 +        return HANDLER_LIST;
 +    }
diff --git a/patches/api/Added-PlayerLecternPageChangeEvent.patch b/patches/api/Added-PlayerLecternPageChangeEvent.patch
index 13507005bc..cc3e64f46f 100644
--- a/patches/api/Added-PlayerLecternPageChangeEvent.patch
+++ b/patches/api/Added-PlayerLecternPageChangeEvent.patch
@@ -19,8 +19,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.event.player.PlayerEvent;
 +import org.bukkit.inventory.ItemStack;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
 +
++@NullMarked
 +public class PlayerLecternPageChangeEvent extends PlayerEvent implements Cancellable {
 +
 +    private static final HandlerList HANDLER_LIST = new HandlerList();
@@ -34,7 +35,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    private boolean cancelled;
 +
 +    @ApiStatus.Internal
-+    public PlayerLecternPageChangeEvent(@NotNull Player player, @NotNull Lectern lectern, @NotNull ItemStack book, @NotNull PageChangeDirection pageChangeDirection, int oldPage, int newPage) {
++    public PlayerLecternPageChangeEvent(final Player player, final Lectern lectern, final ItemStack book, final PageChangeDirection pageChangeDirection, final int oldPage, final int newPage) {
 +        super(player);
 +        this.lectern = lectern;
 +        this.book = book;
@@ -48,7 +49,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return the Lectern
 +     */
-+    @NotNull
 +    public Lectern getLectern() {
 +        return this.lectern;
 +    }
@@ -58,7 +58,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return the ItemStack on the Lectern
 +     */
-+    @NotNull
 +    public ItemStack getBook() {
 +        return this.book;
 +    }
@@ -68,7 +67,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return the page change direction
 +     */
-+    @NotNull
 +    public PageChangeDirection getPageChangeDirection() {
 +        return this.pageChangeDirection;
 +    }
@@ -97,7 +95,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @param newPage the new paged changed to
 +     */
-+    public void setNewPage(int newPage) {
++    public void setNewPage(final int newPage) {
 +        this.newPage = newPage;
 +    }
 +
@@ -107,17 +105,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
 +
 +    @Override
-+    public void setCancelled(boolean cancel) {
++    public void setCancelled(final boolean cancel) {
 +        this.cancelled = cancel;
 +    }
 +
-+    @NotNull
 +    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
 +
-+    @NotNull
 +    public static HandlerList getHandlerList() {
 +        return HANDLER_LIST;
 +    }
diff --git a/patches/api/Added-PlayerLoomPatternSelectEvent.patch b/patches/api/Added-PlayerLoomPatternSelectEvent.patch
index 956b2b6ba1..1eb38f6dd3 100644
--- a/patches/api/Added-PlayerLoomPatternSelectEvent.patch
+++ b/patches/api/Added-PlayerLoomPatternSelectEvent.patch
@@ -19,11 +19,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.event.player.PlayerEvent;
 +import org.bukkit.inventory.LoomInventory;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
 +
 +/**
 + * Called when a player selects a banner patten in a loom inventory.
 + */
++@NullMarked
 +public class PlayerLoomPatternSelectEvent extends PlayerEvent implements Cancellable {
 +
 +    private static final HandlerList HANDLER_LIST = new HandlerList();
@@ -34,7 +35,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    private boolean cancelled;
 +
 +    @ApiStatus.Internal
-+    public PlayerLoomPatternSelectEvent(@NotNull Player player, @NotNull LoomInventory loomInventory, @NotNull PatternType patternType) {
++    public PlayerLoomPatternSelectEvent(final Player player, final LoomInventory loomInventory, final PatternType patternType) {
 +        super(player);
 +        this.loomInventory = loomInventory;
 +        this.patternType = patternType;
@@ -45,7 +46,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return the loom inventory
 +     */
-+    @NotNull
 +    public LoomInventory getLoomInventory() {
 +        return this.loomInventory;
 +    }
@@ -55,7 +55,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return the pattern type
 +     */
-+    @NotNull
 +    public PatternType getPatternType() {
 +        return this.patternType;
 +    }
@@ -65,7 +64,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @param patternType the pattern type
 +     */
-+    public void setPatternType(@NotNull PatternType patternType) {
++    public void setPatternType(final PatternType patternType) {
 +        this.patternType = patternType;
 +    }
 +
@@ -75,17 +74,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
 +
 +    @Override
-+    public void setCancelled(boolean cancel) {
++    public void setCancelled(final boolean cancel) {
 +        this.cancelled = cancel;
 +    }
 +
-+    @NotNull
 +    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
 +
-+    @NotNull
 +    public static HandlerList getHandlerList() {
 +        return HANDLER_LIST;
 +    }
diff --git a/patches/api/Added-PlayerStonecutterRecipeSelectEvent.patch b/patches/api/Added-PlayerStonecutterRecipeSelectEvent.patch
index 2ec5bdb075..c35b3d8d60 100644
--- a/patches/api/Added-PlayerStonecutterRecipeSelectEvent.patch
+++ b/patches/api/Added-PlayerStonecutterRecipeSelectEvent.patch
@@ -18,8 +18,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.event.player.PlayerEvent;
 +import org.bukkit.inventory.StonecutterInventory;
 +import org.bukkit.inventory.StonecuttingRecipe;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
 +
++@NullMarked
 +public class PlayerStonecutterRecipeSelectEvent extends PlayerEvent implements Cancellable {
 +
 +    private static final HandlerList HANDLER_LIST = new HandlerList();
@@ -29,23 +30,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +    private boolean cancelled;
 +
-+    public PlayerStonecutterRecipeSelectEvent(@NotNull Player player, @NotNull StonecutterInventory stonecutterInventory, @NotNull StonecuttingRecipe stonecuttingRecipe) {
++    public PlayerStonecutterRecipeSelectEvent(final Player player, final StonecutterInventory stonecutterInventory, final StonecuttingRecipe stonecuttingRecipe) {
 +        super(player);
 +        this.stonecutterInventory = stonecutterInventory;
 +        this.stonecuttingRecipe = stonecuttingRecipe;
 +    }
 +
-+    @NotNull
 +    public StonecutterInventory getStonecutterInventory() {
 +        return this.stonecutterInventory;
 +    }
 +
-+    @NotNull
 +    public StonecuttingRecipe getStonecuttingRecipe() {
 +        return this.stonecuttingRecipe;
 +    }
 +
-+    public void setStonecuttingRecipe(@NotNull StonecuttingRecipe stonecuttingRecipe) {
++    public void setStonecuttingRecipe(final StonecuttingRecipe stonecuttingRecipe) {
 +        this.stonecuttingRecipe = stonecuttingRecipe;
 +    }
 +
@@ -55,17 +54,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
 +
 +    @Override
-+    public void setCancelled(boolean cancel) {
++    public void setCancelled(final boolean cancel) {
 +        this.cancelled = cancel;
 +    }
 +
-+    @NotNull
 +    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
 +
-+    @NotNull
 +    public static HandlerList getHandlerList() {
 +        return HANDLER_LIST;
 +    }
diff --git a/patches/api/Added-PlayerTradeEvent.patch b/patches/api/Added-PlayerTradeEvent.patch
index d8ca8fafc3..43ef567de9 100644
--- a/patches/api/Added-PlayerTradeEvent.patch
+++ b/patches/api/Added-PlayerTradeEvent.patch
@@ -26,11 +26,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.event.player.PlayerEvent;
 +import org.bukkit.inventory.MerchantRecipe;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
 +
 +/**
 + * Called when a player trades with a standalone merchant GUI.
 + */
++@NullMarked
 +public class PlayerPurchaseEvent extends PlayerEvent implements Cancellable {
 +
 +    private static final HandlerList HANDLER_LIST = new HandlerList();
@@ -42,12 +43,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    private boolean cancelled;
 +
 +    @ApiStatus.Internal
-+    public PlayerPurchaseEvent(@NotNull Player player,
-+                               @NotNull MerchantRecipe trade,
-+                               boolean rewardExp,
-+                               boolean increaseTradeUses) {
++    public PlayerPurchaseEvent(final Player player, final MerchantRecipe trade, final boolean rewardExp, final boolean increaseTradeUses) {
 +        super(player);
-+        setTrade(trade);
++        this.trade = trade;
 +        this.rewardExp = rewardExp;
 +        this.increaseTradeUses = increaseTradeUses;
 +    }
@@ -57,7 +55,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return the trade
 +     */
-+    @NotNull
 +    public MerchantRecipe getTrade() {
 +        return this.trade;
 +    }
@@ -67,7 +64,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @param trade the trade to use
 +     */
-+    public void setTrade(@NotNull MerchantRecipe trade) {
++    public void setTrade(final MerchantRecipe trade) {
 +        Preconditions.checkArgument(trade != null, "Trade cannot be null!");
 +        this.trade = trade;
 +    }
@@ -84,7 +81,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @param rewardExp try to reward exp
 +     */
-+    public void setRewardExp(boolean rewardExp) {
++    public void setRewardExp(final boolean rewardExp) {
 +        this.rewardExp = rewardExp;
 +    }
 +
@@ -100,7 +97,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @param increaseTradeUses {@code true} to count, {@code false} otherwise
 +     */
-+    public void setIncreaseTradeUses(boolean increaseTradeUses) {
++    public void setIncreaseTradeUses(final boolean increaseTradeUses) {
 +        this.increaseTradeUses = increaseTradeUses;
 +    }
 +
@@ -110,17 +107,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
 +
 +    @Override
-+    public void setCancelled(boolean cancel) {
++    public void setCancelled(final boolean cancel) {
 +        this.cancelled = cancel;
 +    }
 +
-+    @NotNull
 +    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
 +
-+    @NotNull
 +    public static HandlerList getHandlerList() {
 +        return HANDLER_LIST;
 +    }
@@ -138,17 +133,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.entity.Player;
 +import org.bukkit.inventory.MerchantRecipe;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
 +
 +/**
 + * Called when a player trades with a villager or wandering trader
 + */
++@NullMarked
 +public class PlayerTradeEvent extends PlayerPurchaseEvent {
 +
 +    private final AbstractVillager villager;
 +
 +    @ApiStatus.Internal
-+    public PlayerTradeEvent(@NotNull Player player, @NotNull AbstractVillager villager, @NotNull MerchantRecipe trade, boolean rewardExp, boolean increaseTradeUses) {
++    public PlayerTradeEvent(final Player player, final AbstractVillager villager, final MerchantRecipe trade, final boolean rewardExp, final boolean increaseTradeUses) {
 +        super(player, trade, rewardExp, increaseTradeUses);
 +        this.villager = villager;
 +    }
@@ -158,7 +154,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return the villager or wandering trader
 +     */
-+    @NotNull
 +    public AbstractVillager getVillager() {
 +        return this.villager;
 +    }
diff --git a/patches/api/Added-WorldGameRuleChangeEvent.patch b/patches/api/Added-WorldGameRuleChangeEvent.patch
index 3164c0d828..1f37fdbb45 100644
--- a/patches/api/Added-WorldGameRuleChangeEvent.patch
+++ b/patches/api/Added-WorldGameRuleChangeEvent.patch
@@ -19,23 +19,24 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.event.HandlerList;
 +import org.bukkit.event.world.WorldEvent;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
-+import org.jetbrains.annotations.Nullable;
++import org.jspecify.annotations.NullMarked;
++import org.jspecify.annotations.Nullable;
 +
 +/**
 + * Called when a world's gamerule is changed, either by command or by api.
 + */
++@NullMarked
 +public class WorldGameRuleChangeEvent extends WorldEvent implements Cancellable {
 +
 +    private static final HandlerList HANDLER_LIST = new HandlerList();
 +
-+    private final CommandSender commandSender;
++    private final @Nullable CommandSender commandSender;
 +    private final GameRule<?> gameRule;
 +    private String value;
 +    private boolean cancelled;
 +
 +    @ApiStatus.Internal
-+    public WorldGameRuleChangeEvent(@NotNull World world, @Nullable CommandSender commandSender, @NotNull GameRule<?> gameRule, @NotNull String value) {
++    public WorldGameRuleChangeEvent(final World world, final @Nullable CommandSender commandSender, final GameRule<?> gameRule, final String value) {
 +        super(world);
 +        this.commandSender = commandSender;
 +        this.gameRule = gameRule;
@@ -47,8 +48,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return {@code null} if the gamerule was changed via api, otherwise the {@link CommandSender}.
 +     */
-+    @Nullable
-+    public CommandSender getCommandSender() {
++    public @Nullable CommandSender getCommandSender() {
 +        return this.commandSender;
 +    }
 +
@@ -57,7 +57,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return the gamerule being changed.
 +     */
-+    @NotNull
 +    public GameRule<?> getGameRule() {
 +        return this.gameRule;
 +    }
@@ -67,7 +66,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return the new value of the gamerule.
 +     */
-+    @NotNull
 +    public String getValue() {
 +        return this.value;
 +    }
@@ -77,7 +75,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @param value the new value of the gamerule.
 +     */
-+    public void setValue(@NotNull String value) {
++    public void setValue(final String value) {
 +        this.value = value;
 +    }
 +
@@ -87,17 +85,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
 +
 +    @Override
-+    public void setCancelled(boolean cancel) {
++    public void setCancelled(final boolean cancel) {
 +        this.cancelled = cancel;
 +    }
 +
-+    @NotNull
 +    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
 +
-+    @NotNull
 +    public static HandlerList getHandlerList() {
 +        return HANDLER_LIST;
 +    }
diff --git a/patches/api/Adds-PlayerArmSwingEvent.patch b/patches/api/Adds-PlayerArmSwingEvent.patch
index a2a4d7f1e0..857f819198 100644
--- a/patches/api/Adds-PlayerArmSwingEvent.patch
+++ b/patches/api/Adds-PlayerArmSwingEvent.patch
@@ -17,14 +17,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.event.player.PlayerAnimationType;
 +import org.bukkit.inventory.EquipmentSlot;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
 +
++@NullMarked
 +public class PlayerArmSwingEvent extends PlayerAnimationEvent {
 +
 +    private final EquipmentSlot equipmentSlot;
 +
 +    @ApiStatus.Internal
-+    public PlayerArmSwingEvent(@NotNull Player player, @NotNull EquipmentSlot equipmentSlot) {
++    public PlayerArmSwingEvent(final Player player, final EquipmentSlot equipmentSlot) {
 +        super(player, equipmentSlot == EquipmentSlot.HAND ? PlayerAnimationType.ARM_SWING : PlayerAnimationType.OFF_ARM_SWING);
 +        this.equipmentSlot = equipmentSlot;
 +    }
@@ -34,7 +35,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return the hand
 +     */
-+    @NotNull
 +    public EquipmentSlot getHand() {
 +        return this.equipmentSlot;
 +    }
diff --git a/patches/api/Adventure.patch b/patches/api/Adventure.patch
index 5d1460cd30..3065b13863 100644
--- a/patches/api/Adventure.patch
+++ b/patches/api/Adventure.patch
@@ -64,6 +64,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
          // Paper start - add missing javadoc links
          "https://javadoc.io/doc/org.joml/joml/1.10.5/index.html",
          "https://www.javadoc.io/doc/com.google.code.gson/gson/2.10.1",
+         "https://jspecify.dev/docs/api/",
          // Paper end
 +        // Paper start
 +        "https://jd.advntr.dev/api/$adventureVersion/",
@@ -215,6 +216,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +package io.papermc.paper.event.player;
 +
 +import io.papermc.paper.chat.ChatRenderer;
++import java.util.Set;
 +import net.kyori.adventure.audience.Audience;
 +import net.kyori.adventure.chat.SignedMessage;
 +import net.kyori.adventure.text.Component;
@@ -222,9 +224,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.event.Cancellable;
 +import org.bukkit.event.player.PlayerEvent;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
-+
-+import java.util.Set;
++import org.jspecify.annotations.NullMarked;
 +
 +import static java.util.Objects.requireNonNull;
 +
@@ -232,6 +232,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 + * An abstract implementation of a chat event, handling shared logic.
 + */
 +@ApiStatus.NonExtendable
++@NullMarked
 +public abstract class AbstractChatEvent extends PlayerEvent implements Cancellable {
 +
 +    private final Set<Audience> viewers;
@@ -242,7 +243,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +    private boolean cancelled;
 +
-+    AbstractChatEvent(final boolean async, final @NotNull Player player, final @NotNull Set<Audience> viewers, final @NotNull ChatRenderer renderer, final @NotNull Component message, final @NotNull Component originalMessage, final @NotNull SignedMessage signedMessage) {
++    AbstractChatEvent(final boolean async, final Player player, final Set<Audience> viewers, final ChatRenderer renderer, final Component message, final Component originalMessage, final SignedMessage signedMessage) {
 +        super(player, async);
 +        this.viewers = viewers;
 +        this.renderer = renderer;
@@ -259,7 +260,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return a mutable set of {@link Audience audiences} who will receive the chat message
 +     */
-+    @NotNull
 +    public final Set<Audience> viewers() {
 +        return this.viewers;
 +    }
@@ -270,7 +270,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * @param renderer the chat renderer
 +     * @throws NullPointerException if {@code renderer} is {@code null}
 +     */
-+    public final void renderer(final @NotNull ChatRenderer renderer) {
++    public final void renderer(final ChatRenderer renderer) {
 +        this.renderer = requireNonNull(renderer, "renderer");
 +    }
 +
@@ -279,7 +279,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return the chat renderer
 +     */
-+    @NotNull
 +    public final ChatRenderer renderer() {
 +        return this.renderer;
 +    }
@@ -290,7 +289,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return the user-supplied message
 +     */
-+    @NotNull
 +    public final Component message() {
 +        return this.message;
 +    }
@@ -301,7 +299,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * @param message the user-supplied message
 +     * @throws NullPointerException if {@code message} is {@code null}
 +     */
-+    public final void message(final @NotNull Component message) {
++    public final void message(final Component message) {
 +        this.message = requireNonNull(message, "message");
 +    }
 +
@@ -312,7 +310,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return the original user-supplied message
 +     */
-+    @NotNull
 +    public final Component originalMessage() {
 +        return this.originalMessage;
 +    }
@@ -324,7 +321,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return the signed message
 +     */
-+    @NotNull
 +    public final SignedMessage signedMessage() {
 +        return this.signedMessage;
 +    }
@@ -351,25 +347,26 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.entity.Player;
 +import org.bukkit.event.HandlerList;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
-+import org.jetbrains.annotations.Nullable;
++import org.jspecify.annotations.NullMarked;
++import org.jspecify.annotations.Nullable;
 +
 +@ApiStatus.Experimental
++@NullMarked
 +public class AsyncChatCommandDecorateEvent extends AsyncChatDecorateEvent {
 +
 +    private static final HandlerList HANDLER_LIST = new HandlerList();
 +
 +    @ApiStatus.Internal
-+    public AsyncChatCommandDecorateEvent(@Nullable Player player, @NotNull Component originalMessage) {
++    public AsyncChatCommandDecorateEvent(final @Nullable Player player, final Component originalMessage) {
 +        super(player, originalMessage);
 +    }
 +
 +    @Override
-+    public @NotNull HandlerList getHandlers() {
++    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
 +
-+    public static @NotNull HandlerList getHandlerList() {
++    public static HandlerList getHandlerList() {
 +        return HANDLER_LIST;
 +    }
 +}
@@ -387,9 +384,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.event.HandlerList;
 +import org.bukkit.event.server.ServerEvent;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.Contract;
-+import org.jetbrains.annotations.NotNull;
-+import org.jetbrains.annotations.Nullable;
++import org.jspecify.annotations.NullMarked;
++import org.jspecify.annotations.Nullable;
 +
 +/**
 + * This event is fired when the server decorates a component for chat purposes. This is called
@@ -401,18 +397,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 + * See {@link AsyncChatCommandDecorateEvent} for the decoration of messages sent via commands
 + */
 +@ApiStatus.Experimental
++@NullMarked
 +public class AsyncChatDecorateEvent extends ServerEvent implements Cancellable {
 +
 +    private static final HandlerList HANDLER_LIST = new HandlerList();
 +
-+    private final Player player;
++    private final @Nullable Player player;
 +    private final Component originalMessage;
 +    private Component result;
 +
 +    private boolean cancelled;
 +
 +    @ApiStatus.Internal
-+    public AsyncChatDecorateEvent(final @Nullable Player player, final @NotNull Component originalMessage) {
++    public AsyncChatDecorateEvent(final @Nullable Player player, final Component originalMessage) {
 +        super(true);
 +        this.player = player;
 +        this.originalMessage = originalMessage;
@@ -436,7 +433,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return the input
 +     */
-+    public @NotNull Component originalMessage() {
++    public Component originalMessage() {
 +        return this.originalMessage;
 +    }
 +
@@ -447,7 +444,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return the result
 +     */
-+    public @NotNull Component result() {
++    public Component result() {
 +        return this.result;
 +    }
 +
@@ -456,7 +453,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @param result the result
 +     */
-+    public void result(@NotNull Component result) {
++    public void result(final Component result) {
 +        this.result = result;
 +    }
 +
@@ -471,16 +468,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * component.
 +     */
 +    @Override
-+    public void setCancelled(boolean cancel) {
++    public void setCancelled(final boolean cancel) {
 +        this.cancelled = cancel;
 +    }
 +
 +    @Override
-+    public @NotNull HandlerList getHandlers() {
++    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
 +
-+    public static @NotNull HandlerList getHandlerList() {
++    public static HandlerList getHandlerList() {
 +        return HANDLER_LIST;
 +    }
 +}
@@ -492,15 +489,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 @@ -0,0 +0,0 @@
 +package io.papermc.paper.event.player;
 +
-+import java.util.Set;
 +import io.papermc.paper.chat.ChatRenderer;
++import java.util.Set;
 +import net.kyori.adventure.audience.Audience;
 +import net.kyori.adventure.chat.SignedMessage;
 +import net.kyori.adventure.text.Component;
 +import org.bukkit.entity.Player;
 +import org.bukkit.event.HandlerList;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
 +
 +/**
 + * An event fired when a {@link Player} sends a chat message to the server.
@@ -515,22 +512,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 + * Care should be taken to check {@link #isAsynchronous()} and treat the event
 + * appropriately.
 + */
++@NullMarked
 +public final class AsyncChatEvent extends AbstractChatEvent {
 +
 +    private static final HandlerList HANDLER_LIST = new HandlerList();
 +
 +    @ApiStatus.Internal
-+    public AsyncChatEvent(final boolean async, final @NotNull Player player, final @NotNull Set<Audience> viewers, final @NotNull ChatRenderer renderer, final @NotNull Component message, final @NotNull Component originalMessage, final @NotNull SignedMessage signedMessage) {
++    public AsyncChatEvent(final boolean async, final Player player, final Set<Audience> viewers, final ChatRenderer renderer, final Component message, final Component originalMessage, final SignedMessage signedMessage) {
 +        super(async, player, viewers, renderer, message, originalMessage, signedMessage);
 +    }
 +
-+    @NotNull
 +    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
 +
-+    @NotNull
 +    public static HandlerList getHandlerList() {
 +        return HANDLER_LIST;
 +    }
@@ -543,8 +539,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 @@ -0,0 +0,0 @@
 +package io.papermc.paper.event.player;
 +
-+import java.util.Set;
 +import io.papermc.paper.chat.ChatRenderer;
++import java.util.Set;
 +import net.kyori.adventure.audience.Audience;
 +import net.kyori.adventure.chat.SignedMessage;
 +import net.kyori.adventure.text.Component;
@@ -552,7 +548,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.entity.Player;
 +import org.bukkit.event.HandlerList;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
 +
 +/**
 + * An event fired when a {@link Player} sends a chat message to the server.
@@ -562,22 +558,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 + */
 +@Deprecated
 +@Warning(reason = "Listening to this event forces chat to wait for the main thread, delaying chat messages.")
++@NullMarked
 +public final class ChatEvent extends AbstractChatEvent {
 +
 +    private static final HandlerList HANDLER_LIST = new HandlerList();
 +
 +    @ApiStatus.Internal
-+    public ChatEvent(final @NotNull Player player, final @NotNull Set<Audience> viewers, final @NotNull ChatRenderer renderer, final @NotNull Component message, final @NotNull Component originalMessage, final @NotNull SignedMessage signedMessage) {
++    public ChatEvent(final Player player, final Set<Audience> viewers, final ChatRenderer renderer, final Component message, final Component originalMessage, final SignedMessage signedMessage) {
 +        super(false, player, viewers, renderer, message, originalMessage, signedMessage);
 +    }
 +
-+    @NotNull
 +    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
 +
-+    @NotNull
 +    public static HandlerList getHandlerList() {
 +        return HANDLER_LIST;
 +    }
diff --git a/patches/api/AnvilDamageEvent.patch b/patches/api/AnvilDamageEvent.patch
index 8dcb163dd2..8287c0280e 100644
--- a/patches/api/AnvilDamageEvent.patch
+++ b/patches/api/AnvilDamageEvent.patch
@@ -95,6 +95,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        this.cancelled = cancel;
 +    }
 +
++    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
diff --git a/patches/api/AsyncTabCompleteEvent.patch b/patches/api/AsyncTabCompleteEvent.patch
index 4ee92d170e..8067d1efe0 100644
--- a/patches/api/AsyncTabCompleteEvent.patch
+++ b/patches/api/AsyncTabCompleteEvent.patch
@@ -244,6 +244,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        this.cancelled = cancel;
 +    }
 +
++    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
diff --git a/patches/api/Basic-PlayerProfile-API.patch b/patches/api/Basic-PlayerProfile-API.patch
index 9cdb49297c..4831c91b5b 100644
--- a/patches/api/Basic-PlayerProfile-API.patch
+++ b/patches/api/Basic-PlayerProfile-API.patch
@@ -262,7 +262,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +/**
 + * Represents a property on a {@link PlayerProfile}
 + */
-+public class ProfileProperty {
++public final class ProfileProperty {
 +    private final String name;
 +    private final String value;
 +    private final String signature;
diff --git a/patches/api/Brigadier-based-command-API.patch b/patches/api/Brigadier-based-command-API.patch
index 0e916dfd38..f3978be8ea 100644
--- a/patches/api/Brigadier-based-command-API.patch
+++ b/patches/api/Brigadier-based-command-API.patch
@@ -141,7 +141,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +@NullMarked
 +public class AsyncPlayerSendCommandsEvent<S extends CommandSourceStack> extends PlayerEvent {
 +
-+    private static final HandlerList handlers = new HandlerList();
++    private static final HandlerList HANDLER_LIST = new HandlerList();
 +    private final RootCommandNode<S> node;
 +    private final boolean hasFiredAsync;
 +
@@ -170,12 +170,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        return this.hasFiredAsync;
 +    }
 +
++    @Override
 +    public HandlerList getHandlers() {
-+        return handlers;
++        return HANDLER_LIST;
 +    }
 +
 +    public static HandlerList getHandlerList() {
-+        return handlers;
++        return HANDLER_LIST;
 +    }
 +}
 diff --git a/src/main/java/com/destroystokyo/paper/event/brigadier/AsyncPlayerSendSuggestionsEvent.java b/src/main/java/com/destroystokyo/paper/event/brigadier/AsyncPlayerSendSuggestionsEvent.java
@@ -203,7 +204,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +@NullMarked
 +public class AsyncPlayerSendSuggestionsEvent extends PlayerEvent implements Cancellable {
 +
-+    private static final HandlerList handlers = new HandlerList();
++    private static final HandlerList HANDLER_LIST = new HandlerList();
 +    private boolean cancelled = false;
 +
 +    private Suggestions suggestions;
@@ -260,12 +261,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        this.cancelled = cancel;
 +    }
 +
++    @Override
 +    public HandlerList getHandlers() {
-+        return handlers;
++        return HANDLER_LIST;
 +    }
 +
 +    public static HandlerList getHandlerList() {
-+        return handlers;
++        return HANDLER_LIST;
 +    }
 +}
 diff --git a/src/main/java/com/destroystokyo/paper/event/brigadier/CommandRegisteredEvent.java b/src/main/java/com/destroystokyo/paper/event/brigadier/CommandRegisteredEvent.java
diff --git a/patches/api/Build-system-changes.patch b/patches/api/Build-system-changes.patch
index 415a144846..13f45865d9 100644
--- a/patches/api/Build-system-changes.patch
+++ b/patches/api/Build-system-changes.patch
@@ -47,6 +47,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        // Paper start - add missing javadoc links
 +        "https://javadoc.io/doc/org.joml/joml/1.10.5/index.html",
 +        "https://www.javadoc.io/doc/com.google.code.gson/gson/2.10.1",
++        "https://jspecify.dev/docs/api/",
 +        // Paper end
      )
      options.tags("apiNote:a:API Note:")
diff --git a/patches/api/EnderDragon-Events.patch b/patches/api/EnderDragon-Events.patch
index d6224a8034..01b8494918 100644
--- a/patches/api/EnderDragon-Events.patch
+++ b/patches/api/EnderDragon-Events.patch
@@ -142,6 +142,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        this.cancelled = cancel;
 +    }
 +
++    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
diff --git a/patches/api/EndermanAttackPlayerEvent.patch b/patches/api/EndermanAttackPlayerEvent.patch
index 3644824db5..1efb853a3f 100644
--- a/patches/api/EndermanAttackPlayerEvent.patch
+++ b/patches/api/EndermanAttackPlayerEvent.patch
@@ -103,6 +103,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        this.cancelled = cancel;
 +    }
 +
++    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
diff --git a/patches/api/Entity-AddTo-RemoveFrom-World-Events.patch b/patches/api/Entity-AddTo-RemoveFrom-World-Events.patch
index da68ef3129..a20c2f6606 100644
--- a/patches/api/Entity-AddTo-RemoveFrom-World-Events.patch
+++ b/patches/api/Entity-AddTo-RemoveFrom-World-Events.patch
@@ -45,6 +45,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        return this.world;
 +    }
 +
++    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
@@ -92,6 +93,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        return this.world;
 +    }
 +
++    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
diff --git a/patches/api/Entity-Jump-API.patch b/patches/api/Entity-Jump-API.patch
index 98f335e051..5430c8eb5b 100644
--- a/patches/api/Entity-Jump-API.patch
+++ b/patches/api/Entity-Jump-API.patch
@@ -41,10 +41,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        return (LivingEntity) super.getEntity();
 +    }
 +
++    @Override
 +    public boolean isCancelled() {
 +        return this.cancelled;
 +    }
 +
++    @Override
 +    public void setCancelled(final boolean cancel) {
 +        this.cancelled = cancel;
 +    }
diff --git a/patches/api/EntityPathfindEvent.patch b/patches/api/EntityPathfindEvent.patch
index 5c904661c2..85038eb62d 100644
--- a/patches/api/EntityPathfindEvent.patch
+++ b/patches/api/EntityPathfindEvent.patch
@@ -49,6 +49,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return The Entity that is pathfinding.
 +     */
++    @Override
 +    public Entity getEntity() {
 +        return this.entity;
 +    }
diff --git a/patches/api/Expand-World.spawnParticle-API-and-add-Builder.patch b/patches/api/Expand-World.spawnParticle-API-and-add-Builder.patch
index 7b16a5d55f..31860c009f 100644
--- a/patches/api/Expand-World.spawnParticle-API-and-add-Builder.patch
+++ b/patches/api/Expand-World.spawnParticle-API-and-add-Builder.patch
@@ -19,37 +19,36 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import com.google.common.base.Preconditions;
 +import com.google.common.collect.Lists;
 +import it.unimi.dsi.fastutil.objects.ObjectArrayList;
++import java.util.Collection;
++import java.util.List;
 +import org.bukkit.Color;
 +import org.bukkit.Location;
 +import org.bukkit.Particle;
 +import org.bukkit.World;
 +import org.bukkit.entity.Player;
 +import org.bukkit.util.NumberConversions;
-+
-+import java.util.Collection;
-+import java.util.List;
-+import org.jetbrains.annotations.Contract;
-+import org.jetbrains.annotations.NotNull;
-+import org.jetbrains.annotations.Nullable;
++import org.jspecify.annotations.NullMarked;
++import org.jspecify.annotations.Nullable;
 +
 +/**
 + * Helps prepare a particle to be sent to players.
-+ *
++ * <p>
 + * Usage of the builder is preferred over the super long {@link World#spawnParticle(Particle, Location, int, double, double, double, double, Object)} API
 + */
++@NullMarked
 +public class ParticleBuilder implements Cloneable {
 +
 +    private Particle particle;
-+    private List<Player> receivers;
-+    private Player source;
-+    private Location location;
++    private @Nullable List<Player> receivers;
++    private @Nullable Player source;
++    private @Nullable Location location;
 +    private int count = 1;
 +    private double offsetX = 0, offsetY = 0, offsetZ = 0;
 +    private double extra = 1;
-+    private Object data;
++    private @Nullable Object data;
 +    private boolean force = true;
 +
-+    public ParticleBuilder(@NotNull Particle particle) {
++    public ParticleBuilder(final Particle particle) {
 +        this.particle = particle;
 +    }
 +
@@ -59,14 +58,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return a reference to this object.
 +     */
-+    @NotNull
 +    public ParticleBuilder spawn() {
 +        if (this.location == null) {
 +            throw new IllegalStateException("Please specify location for this particle");
 +        }
-+        location.getWorld().spawnParticle(particle, receivers, source,
-+            location.getX(), location.getY(), location.getZ(),
-+            count, offsetX, offsetY, offsetZ, extra, data, force
++        this.location.getWorld().spawnParticle(
++            this.particle, this.receivers, this.source,
++            this.location.getX(), this.location.getY(), this.location.getZ(),
++            this.count, this.offsetX, this.offsetY, this.offsetZ, this.extra, this.data, this.force
 +        );
 +        return this;
 +    }
@@ -74,9 +73,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    /**
 +     * @return The particle going to be sent
 +     */
-+    @NotNull
 +    public Particle particle() {
-+        return particle;
++        return this.particle;
 +    }
 +
 +    /**
@@ -85,8 +83,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * @param particle The particle
 +     * @return a reference to this object.
 +     */
-+    @NotNull
-+    public ParticleBuilder particle(@NotNull Particle particle) {
++    public ParticleBuilder particle(final Particle particle) {
 +        this.particle = particle;
 +        return this;
 +    }
@@ -94,32 +91,30 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    /**
 +     * @return List of players who will receive the particle, or null for all in world
 +     */
-+    @Nullable
-+    public List<Player> receivers() {
-+        return receivers;
++    public @Nullable List<Player> receivers() {
++        return this.receivers;
 +    }
 +
 +    /**
 +     * Example use:
-+     *
++     * <p>
 +     * builder.receivers(16); if (builder.hasReceivers()) { sendParticleAsync(builder); }
 +     *
 +     * @return If this particle is going to be sent to someone
 +     */
 +    public boolean hasReceivers() {
-+        return (receivers == null && !location.getWorld().getPlayers().isEmpty()) || (
-+            receivers != null && !receivers.isEmpty());
++        return (this.receivers == null && this.location != null && !this.location.getWorld().getPlayers().isEmpty()) || (
++            this.receivers != null && !this.receivers.isEmpty());
 +    }
 +
 +    /**
-+     * Sends this particle to all players in the world. This is rather silly and you should likely not
++     * Sends this particle to all players in the world. This is rather silly, and you should likely not
 +     * be doing this.
-+     *
++     * <p>
 +     * Just be a logical person and use receivers by radius or collection.
 +     *
 +     * @return a reference to this object.
 +     */
-+    @NotNull
 +    public ParticleBuilder allPlayers() {
 +        this.receivers = null;
 +        return this;
@@ -127,11 +122,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +    /**
 +     * @param receivers List of players to receive this particle, or null for all players in the
-+     * world
++     *                  world
 +     * @return a reference to this object.
 +     */
-+    @NotNull
-+    public ParticleBuilder receivers(@Nullable List<Player> receivers) {
++    public ParticleBuilder receivers(final @Nullable List<Player> receivers) {
 +        // Had to keep this as we first made API List<> and not Collection, but removing this may break plugins compiled on older jars
 +        // TODO: deprecate?
 +        this.receivers = receivers != null ? Lists.newArrayList(receivers) : null;
@@ -140,22 +134,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +    /**
 +     * @param receivers List of players to receive this particle, or null for all players in the
-+     * world
++     *                  world
 +     * @return a reference to this object.
 +     */
-+    @NotNull
-+    public ParticleBuilder receivers(@Nullable Collection<Player> receivers) {
++    public ParticleBuilder receivers(final @Nullable Collection<Player> receivers) {
 +        this.receivers = receivers != null ? Lists.newArrayList(receivers) : null;
 +        return this;
 +    }
 +
 +    /**
-+     * @param receivers List of players to be receive this particle, or null for all players in the
-+     * world
++     * @param receivers List of players to receive this particle, or null for all players in the
++     *                  world
 +     * @return a reference to this object.
 +     */
-+    @NotNull
-+    public ParticleBuilder receivers(@Nullable Player... receivers) {
++    public ParticleBuilder receivers(final Player @Nullable... receivers) {
 +        this.receivers = receivers != null ? Lists.newArrayList(receivers) : null;
 +        return this;
 +    }
@@ -168,9 +160,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * @param radius amount to add on all axis
 +     * @return a reference to this object.
 +     */
-+    @NotNull
-+    public ParticleBuilder receivers(int radius) {
-+        return receivers(radius, radius);
++    public ParticleBuilder receivers(final int radius) {
++        return this.receivers(radius, radius);
 +    }
 +
 +    /**
@@ -178,22 +169,24 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * false, behavior uses cuboid selection the same as {@link #receivers(int, int)} If byDistance is
 +     * true, radius is tested by distance in a spherical shape
 +     *
-+     * @param radius amount to add on each axis
++     * @param radius     amount to add on each axis
 +     * @param byDistance true to use a spherical radius, false to use a cuboid
 +     * @return a reference to this object.
 +     */
-+    @NotNull
-+    public ParticleBuilder receivers(int radius, boolean byDistance) {
++    public ParticleBuilder receivers(final int radius, final boolean byDistance) {
 +        if (!byDistance) {
-+            return receivers(radius, radius, radius);
++            return this.receivers(radius, radius, radius);
 +        } else {
++            if (this.location == null) {
++                throw new IllegalStateException("Please set location first");
++            }
 +            this.receivers = Lists.newArrayList();
-+            for (Player nearbyPlayer : location.getWorld()
-+                .getNearbyPlayers(location, radius, radius, radius)) {
-+                Location loc = nearbyPlayer.getLocation();
-+                double x = NumberConversions.square(location.getX() - loc.getX());
-+                double y = NumberConversions.square(location.getY() - loc.getY());
-+                double z = NumberConversions.square(location.getZ() - loc.getZ());
++            for (final Player nearbyPlayer : this.location.getWorld()
++                .getNearbyPlayers(this.location, radius, radius, radius)) {
++                final Location loc = nearbyPlayer.getLocation();
++                final double x = NumberConversions.square(this.location.getX() - loc.getX());
++                final double y = NumberConversions.square(this.location.getY() - loc.getY());
++                final double z = NumberConversions.square(this.location.getZ() - loc.getZ());
 +                if (Math.sqrt(x + y + z) > radius) {
 +                    continue;
 +                }
@@ -210,12 +203,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * see {@link #receivers(int, boolean)}
 +     *
 +     * @param xzRadius amount to add on the x/z axis
-+     * @param yRadius amount to add on the y axis
++     * @param yRadius  amount to add on the y axis
 +     * @return a reference to this object.
 +     */
-+    @NotNull
-+    public ParticleBuilder receivers(int xzRadius, int yRadius) {
-+        return receivers(xzRadius, yRadius, xzRadius);
++    public ParticleBuilder receivers(final int xzRadius, final int yRadius) {
++        return this.receivers(xzRadius, yRadius, xzRadius);
 +    }
 +
 +    /**
@@ -223,25 +215,28 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * false, behavior uses cuboid selection the same as {@link #receivers(int, int)} If byDistance is
 +     * true, radius is tested by distance on the y plane and on the x/z plane, in a cylinder shape.
 +     *
-+     * @param xzRadius amount to add on the x/z axis
-+     * @param yRadius amount to add on the y axis
++     * @param xzRadius   amount to add on the x/z axis
++     * @param yRadius    amount to add on the y axis
 +     * @param byDistance true to use a cylinder shape, false to use cuboid
 +     * @return a reference to this object.
++     * @throws IllegalStateException if a location hasn't been specified yet
 +     */
-+    @NotNull
-+    public ParticleBuilder receivers(int xzRadius, int yRadius, boolean byDistance) {
++    public ParticleBuilder receivers(final int xzRadius, final int yRadius, final boolean byDistance) {
 +        if (!byDistance) {
-+            return receivers(xzRadius, yRadius, xzRadius);
++            return this.receivers(xzRadius, yRadius, xzRadius);
 +        } else {
++            if (this.location == null) {
++                throw new IllegalStateException("Please set location first");
++            }
 +            this.receivers = Lists.newArrayList();
-+            for (Player nearbyPlayer : location.getWorld()
-+                .getNearbyPlayers(location, xzRadius, yRadius, xzRadius)) {
-+                Location loc = nearbyPlayer.getLocation();
++            for (final Player nearbyPlayer : this.location.getWorld()
++                .getNearbyPlayers(this.location, xzRadius, yRadius, xzRadius)) {
++                final Location loc = nearbyPlayer.getLocation();
 +                if (Math.abs(loc.getY() - this.location.getY()) > yRadius) {
 +                    continue;
 +                }
-+                double x = NumberConversions.square(location.getX() - loc.getX());
-+                double z = NumberConversions.square(location.getZ() - loc.getZ());
++                final double x = NumberConversions.square(this.location.getX() - loc.getX());
++                final double z = NumberConversions.square(this.location.getZ() - loc.getZ());
 +                if (x + z > NumberConversions.square(xzRadius)) {
 +                    continue;
 +                }
@@ -261,20 +256,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * @param zRadius amount to add on the z axis
 +     * @return a reference to this object.
 +     */
-+    @NotNull
-+    public ParticleBuilder receivers(int xRadius, int yRadius, int zRadius) {
-+        if (location == null) {
++    public ParticleBuilder receivers(final int xRadius, final int yRadius, final int zRadius) {
++        if (this.location == null) {
 +            throw new IllegalStateException("Please set location first");
 +        }
-+        return receivers(location.getWorld().getNearbyPlayers(location, xRadius, yRadius, zRadius));
++        return this.receivers(this.location.getWorld().getNearbyPlayers(this.location, xRadius, yRadius, zRadius));
 +    }
 +
 +    /**
 +     * @return The player considered the source of this particle (for Visibility concerns), or null
 +     */
-+    @Nullable
-+    public Player source() {
-+        return source;
++    public @Nullable Player source() {
++        return this.source;
 +    }
 +
 +    /**
@@ -283,8 +276,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * @param source The player who is considered the source
 +     * @return a reference to this object.
 +     */
-+    @NotNull
-+    public ParticleBuilder source(@Nullable Player source) {
++    public ParticleBuilder source(final @Nullable Player source) {
 +        this.source = source;
 +        return this;
 +    }
@@ -292,9 +284,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    /**
 +     * @return Location of where the particle will spawn
 +     */
-+    @Nullable
-+    public Location location() {
-+        return location;
++    public @Nullable Location location() {
++        return this.location;
 +    }
 +
 +    /**
@@ -303,8 +294,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * @param location The location of the particle
 +     * @return a reference to this object.
 +     */
-+    @NotNull
-+    public ParticleBuilder location(@NotNull Location location) {
++    public ParticleBuilder location(final Location location) {
 +        this.location = location.clone();
 +        return this;
 +    }
@@ -313,13 +303,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * Sets the location of where to spawn the particle
 +     *
 +     * @param world World to spawn particle in
-+     * @param x X location
-+     * @param y Y location
-+     * @param z Z location
++     * @param x     X location
++     * @param y     Y location
++     * @param z     Z location
 +     * @return a reference to this object.
 +     */
-+    @NotNull
-+    public ParticleBuilder location(@NotNull World world, double x, double y, double z) {
++    public ParticleBuilder location(final World world, final double x, final double y, final double z) {
 +        this.location = new Location(world, x, y, z);
 +        return this;
 +    }
@@ -328,7 +317,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * @return Number of particles to spawn
 +     */
 +    public int count() {
-+        return count;
++        return this.count;
 +    }
 +
 +    /**
@@ -337,8 +326,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * @param count Number of particles
 +     * @return a reference to this object.
 +     */
-+    @NotNull
-+    public ParticleBuilder count(int count) {
++    public ParticleBuilder count(final int count) {
 +        this.count = count;
 +        return this;
 +    }
@@ -349,7 +337,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * @return Particle offset X.
 +     */
 +    public double offsetX() {
-+        return offsetX;
++        return this.offsetX;
 +    }
 +
 +    /**
@@ -358,7 +346,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * @return Particle offset Y.
 +     */
 +    public double offsetY() {
-+        return offsetY;
++        return this.offsetY;
 +    }
 +
 +    /**
@@ -367,7 +355,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * @return Particle offset Z.
 +     */
 +    public double offsetZ() {
-+        return offsetZ;
++        return this.offsetZ;
 +    }
 +
 +    /**
@@ -378,8 +366,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * @param offsetZ Particle offset Z
 +     * @return a reference to this object.
 +     */
-+    @NotNull
-+    public ParticleBuilder offset(double offsetX, double offsetY, double offsetZ) {
++    public ParticleBuilder offset(final double offsetX, final double offsetY, final double offsetZ) {
 +        this.offsetX = offsetX;
 +        this.offsetY = offsetY;
 +        this.offsetZ = offsetZ;
@@ -392,7 +379,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * @return the extra particle data
 +     */
 +    public double extra() {
-+        return extra;
++        return this.extra;
 +    }
 +
 +    /**
@@ -401,8 +388,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * @param extra the extra particle data
 +     * @return a reference to this object.
 +     */
-+    @NotNull
-+    public ParticleBuilder extra(double extra) {
++    public ParticleBuilder extra(final double extra) {
 +        this.extra = extra;
 +        return this;
 +    }
@@ -413,21 +399,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * @param <T> The Particle data type
 +     * @return the ParticleData for this particle
 +     */
-+    @Nullable
-+    public <T> T data() {
++    public @Nullable <T> T data() {
 +        //noinspection unchecked
-+        return (T) data;
++        return (T) this.data;
 +    }
 +
 +    /**
 +     * Sets the particle custom data. Varies by particle on how this is used
 +     *
 +     * @param data The new particle data
-+     * @param <T> The Particle data type
++     * @param <T>  The Particle data type
 +     * @return a reference to this object.
 +     */
-+    @NotNull
-+    public <T> ParticleBuilder data(@Nullable T data) {
++    public <T> ParticleBuilder data(final @Nullable T data) {
 +        this.data = data;
 +        return this;
 +    }
@@ -436,7 +420,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * @return whether the particle is forcefully shown to players.
 +     */
 +    public boolean force() {
-+        return force;
++        return this.force;
 +    }
 +
 +    /**
@@ -447,8 +431,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * @param force true to force, false for normal
 +     * @return a reference to this object.
 +     */
-+    @NotNull
-+    public ParticleBuilder force(boolean force) {
++    public ParticleBuilder force(final boolean force) {
 +        this.force = force;
 +        return this;
 +    }
@@ -460,12 +443,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * @param color the new particle color
 +     * @return a reference to this object.
 +     */
-+    @NotNull
-+    public ParticleBuilder color(@Nullable Color color) {
-+        if (particle.getDataType() == Color.class) {
-+            return data(color);
++    public ParticleBuilder color(final @Nullable Color color) {
++        if (this.particle.getDataType() == Color.class) {
++            return this.data(color);
 +        }
-+        return color(color, 1);
++        return this.color(color, 1);
 +    }
 +
 +    /**
@@ -473,25 +455,24 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * Only valid for particles with a data type of {@link Particle.DustOptions}.
 +     *
 +     * @param color the new particle color
-+     * @param size the size of the particle
++     * @param size  the size of the particle
 +     * @return a reference to this object.
 +     */
-+    @NotNull
-+    public ParticleBuilder color(@Nullable Color color, float size) {
-+        if (particle.getDataType() != Particle.DustOptions.class && color != null) {
++    public ParticleBuilder color(final @Nullable Color color, final float size) {
++        if (this.particle.getDataType() != Particle.DustOptions.class && color != null) {
 +            throw new IllegalStateException("The combination of Color and size cannot be set on this particle type.");
 +        }
 +
 +        // We don't officially support reusing these objects, but here we go
 +        if (color == null) {
-+            if (data instanceof Particle.DustOptions) {
-+                return data(null);
++            if (this.data instanceof Particle.DustOptions) {
++                return this.data(null);
 +            } else {
 +                return this;
 +            }
 +        }
 +
-+        return data(new Particle.DustOptions(color, size));
++        return this.data(new Particle.DustOptions(color, size));
 +    }
 +
 +    /**
@@ -503,9 +484,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * @param b blue color component
 +     * @return a reference to this object.
 +     */
-+    @NotNull
-+    public ParticleBuilder color(int r, int g, int b) {
-+        return color(Color.fromRGB(r, g, b));
++    public ParticleBuilder color(final int r, final int g, final int b) {
++        return this.color(Color.fromRGB(r, g, b));
 +    }
 +
 +    /**
@@ -519,13 +499,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *              the color is treated as RGB. Otherwise, it is treated as ARGB.
 +     * @return a reference to this object.
 +     */
-+    @NotNull
 +    public ParticleBuilder color(final int color) {
-+        int alpha = (color >> 24) & 0xFF;
++        final int alpha = (color >> 24) & 0xFF;
 +        if (alpha == 0) {
-+            return color(Color.fromRGB(color));
++            return this.color(Color.fromRGB(color));
 +        }
-+        return color(Color.fromARGB(color));
++        return this.color(Color.fromARGB(color));
 +    }
 +
 +    /**
@@ -538,9 +517,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * @param b blue color component
 +     * @return a reference to this object.
 +     */
-+    @NotNull
 +    public ParticleBuilder color(final int a, final int r, final int g, final int b) {
-+        return color(Color.fromARGB(a, r, g, b));
++        return this.color(Color.fromARGB(a, r, g, b));
 +    }
 +
 +    /**
@@ -548,69 +526,64 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * Only valid for {@link Particle#DUST_COLOR_TRANSITION}.
 +     *
 +     * @param fromColor the new particle from color
-+     * @param toColor the new particle to color
++     * @param toColor   the new particle to color
 +     * @return a reference to this object.
 +     * @throws IllegalArgumentException if the particle builder's {@link #particle()} isn't {@link Particle#DUST_COLOR_TRANSITION}.
 +     */
-+    @NotNull
-+    public ParticleBuilder colorTransition(@NotNull final Color fromColor, @NotNull final Color toColor) {
-+        return colorTransition(fromColor, toColor, 1);
++    public ParticleBuilder colorTransition(final Color fromColor, final Color toColor) {
++        return this.colorTransition(fromColor, toColor, 1);
 +    }
 +
 +    /**
 +     * Sets the particle Color Transition.
 +     * Only valid for {@link Particle#DUST_COLOR_TRANSITION}.
 +     *
-+     * @param fromRed red color component for the from color
-+     * @param fromGreen green color component for the from color
-+     * @param fromBlue blue color component for the from color
-+     * @param toRed red color component for the to color
-+     * @param toGreen green color component for the to color
-+     * @param toBlue blue color component for the to color
++     * @param fromRed   red color component for the "from" color
++     * @param fromGreen green color component for the "from" color
++     * @param fromBlue  blue color component for the "from" color
++     * @param toRed     red color component for the to color
++     * @param toGreen   green color component for the to color
++     * @param toBlue    blue color component for the to color
 +     * @return a reference to this object.
 +     * @throws IllegalArgumentException if the particle builder's {@link #particle()} isn't {@link Particle#DUST_COLOR_TRANSITION}.
 +     */
-+    @NotNull
-+    public ParticleBuilder colorTransition(final int fromRed, final int fromGreen, final int fromBlue,
-+                                           final int toRed, final int toGreen, final int toBlue) {
-+        return colorTransition(Color.fromRGB(fromRed, fromGreen, fromBlue), Color.fromRGB(toRed, toGreen, toBlue));
++    public ParticleBuilder colorTransition(
++        final int fromRed, final int fromGreen, final int fromBlue,
++        final int toRed, final int toGreen, final int toBlue
++    ) {
++        return this.colorTransition(Color.fromRGB(fromRed, fromGreen, fromBlue), Color.fromRGB(toRed, toGreen, toBlue));
 +    }
 +
 +    /**
 +     * Sets the particle Color Transition.
 +     * Only valid for {@link Particle#DUST_COLOR_TRANSITION}.
 +     *
-+     * @param fromRgb an integer representing the red, green, and blue color components for the from color
-+     * @param toRgb   an integer representing the red, green, and blue color components for the to color
++     * @param fromRgb an integer representing the red, green, and blue color components for the "from" color
++     * @param toRgb   an integer representing the red, green, and blue color components for the "to" color
 +     * @return a reference to this object.
 +     * @throws IllegalArgumentException if the particle builder's {@link #particle()} isn't {@link Particle#DUST_COLOR_TRANSITION}.
 +     */
-+    @NotNull
 +    public ParticleBuilder colorTransition(final int fromRgb, final int toRgb) {
-+        return colorTransition(Color.fromRGB(fromRgb), Color.fromRGB(toRgb));
++        return this.colorTransition(Color.fromRGB(fromRgb), Color.fromRGB(toRgb));
 +    }
 +
 +    /**
 +     * Sets the particle Color Transition and size.
 +     * Only valid for {@link Particle#DUST_COLOR_TRANSITION}.
 +     *
-+     * @param fromColor the new particle color for the from color.
-+     * @param toColor the new particle color for the to color.
-+     * @param size the size of the particle
++     * @param fromColor the new particle color for the "from" color.
++     * @param toColor   the new particle color for the "to" color.
++     * @param size      the size of the particle
 +     * @return a reference to this object.
 +     * @throws IllegalArgumentException if the particle builder's {@link #particle()} isn't {@link Particle#DUST_COLOR_TRANSITION}.
 +     */
-+    @NotNull
-+    public ParticleBuilder colorTransition(@NotNull final Color fromColor,
-+                                           @NotNull final Color toColor,
-+                                           final float size) {
++    public ParticleBuilder colorTransition(final Color fromColor, final Color toColor, final float size) {
 +        Preconditions.checkArgument(fromColor != null, "Cannot define color transition with null fromColor.");
 +        Preconditions.checkArgument(toColor != null, "Cannot define color transition with null toColor.");
 +        Preconditions.checkArgument(this.particle() == Particle.DUST_COLOR_TRANSITION, "Can only define a color transition on particle DUST_COLOR_TRANSITION.");
-+        return data(new Particle.DustTransition(fromColor, toColor, size));
++        return this.data(new Particle.DustTransition(fromColor, toColor, size));
 +    }
 +
-+    @NotNull
 +    @Override
 +    public ParticleBuilder clone() {
 +        try {
diff --git a/patches/api/Expose-client-protocol-version-and-virtual-host.patch b/patches/api/Expose-client-protocol-version-and-virtual-host.patch
index a3bfc0b0cb..c0b340ac6e 100644
--- a/patches/api/Expose-client-protocol-version-and-virtual-host.patch
+++ b/patches/api/Expose-client-protocol-version-and-virtual-host.patch
@@ -18,13 +18,13 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +package com.destroystokyo.paper.network;
 +
 +import java.net.InetSocketAddress;
-+
-+import org.jetbrains.annotations.NotNull;
-+import org.jetbrains.annotations.Nullable;
++import org.jspecify.annotations.NullMarked;
++import org.jspecify.annotations.Nullable;
 +
 +/**
 + * Represents a client connected to the server.
 + */
++@NullMarked
 +public interface NetworkClient {
 +
 +    /**
@@ -32,7 +32,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return The client's socket address
 +     */
-+    @NotNull
 +    InetSocketAddress getAddress();
 +
 +    /**
@@ -52,8 +51,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return The client's virtual host, or {@code null} if unknown
 +     */
-+    @Nullable
-+    InetSocketAddress getVirtualHost();
++    @Nullable InetSocketAddress getVirtualHost();
 +
 +}
 diff --git a/src/main/java/org/bukkit/entity/Player.java b/src/main/java/org/bukkit/entity/Player.java
diff --git a/patches/api/Expose-server-build-information.patch b/patches/api/Expose-server-build-information.patch
index 439050da7f..f854e71f36 100644
--- a/patches/api/Expose-server-build-information.patch
+++ b/patches/api/Expose-server-build-information.patch
@@ -19,9 +19,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import net.kyori.adventure.text.Component;
 +import net.kyori.adventure.text.format.NamedTextColor;
 +import org.bukkit.Bukkit;
-+import org.jetbrains.annotations.NotNull;
++import org.jetbrains.annotations.ApiStatus;
++import org.jspecify.annotations.NullMarked;
 +
++@NullMarked
 +public interface VersionFetcher {
++
 +    /**
 +     * Amount of time to cache results for in milliseconds
 +     * <p>
@@ -39,9 +42,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * @param serverVersion the current version of the server (will match {@link Bukkit#getVersion()})
 +     * @return the message to show when requesting a version
 +     */
-+    @NotNull
-+    Component getVersionMessage(@NotNull String serverVersion);
++    Component getVersionMessage(String serverVersion);
 +
++    @ApiStatus.Internal
 +    class DummyVersionFetcher implements VersionFetcher {
 +
 +        @Override
@@ -49,9 +52,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +            return -1;
 +        }
 +
-+        @NotNull
 +        @Override
-+        public Component getVersionMessage(@NotNull String serverVersion) {
++        public Component getVersionMessage(final String serverVersion) {
 +            Bukkit.getLogger().warning("Version provider has not been set, cannot check for updates!");
 +            Bukkit.getLogger().info("Override the default implementation of org.bukkit.UnsafeValues#getVersionFetcher()");
 +            new Throwable().printStackTrace();
diff --git a/patches/api/Fill-Profile-Property-Events.patch b/patches/api/Fill-Profile-Property-Events.patch
index 1ad6342921..e35339072f 100644
--- a/patches/api/Fill-Profile-Property-Events.patch
+++ b/patches/api/Fill-Profile-Property-Events.patch
@@ -43,24 +43,24 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +import com.destroystokyo.paper.profile.PlayerProfile;
 +import com.destroystokyo.paper.profile.ProfileProperty;
++import java.util.Set;
 +import org.bukkit.event.Event;
 +import org.bukkit.event.HandlerList;
-+
-+import java.util.Set;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
 +
 +/**
 + * Fired once a profiles additional properties (such as textures) has been filled
 + */
++@NullMarked
 +public class FillProfileEvent extends Event {
 +
 +    private static final HandlerList HANDLER_LIST = new HandlerList();
 +
-+    @NotNull private final PlayerProfile profile;
++    private final PlayerProfile profile;
 +
 +    @ApiStatus.Internal
-+    public FillProfileEvent(@NotNull PlayerProfile profile) {
++    public FillProfileEvent(final PlayerProfile profile) {
 +        super(!org.bukkit.Bukkit.isPrimaryThread());
 +        this.profile = profile;
 +    }
@@ -68,7 +68,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    /**
 +     * @return The Profile that had properties filled
 +     */
-+    @NotNull
 +    public PlayerProfile getPlayerProfile() {
 +        return this.profile;
 +    }
@@ -76,21 +75,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    /**
 +     * Same as .getPlayerProfile().getProperties()
 +     *
-+     * @see PlayerProfile#getProperties()
 +     * @return The new properties on the profile.
++     * @see PlayerProfile#getProperties()
 +     */
-+    @NotNull
 +    public Set<ProfileProperty> getProperties() {
 +        return this.profile.getProperties();
 +    }
 +
-+    @NotNull
 +    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
 +
-+    @NotNull
 +    public static HandlerList getHandlerList() {
 +        return HANDLER_LIST;
 +    }
@@ -128,26 +124,26 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +import com.destroystokyo.paper.profile.PlayerProfile;
 +import com.destroystokyo.paper.profile.ProfileProperty;
++import java.util.Collection;
 +import org.bukkit.event.Event;
 +import org.bukkit.event.HandlerList;
-+
-+import java.util.Collection;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
 +
 +/**
 + * Fired when the server is requesting to fill in properties of an incomplete profile, such as textures.
 + * <p>
 + * Allows plugins to pre-populate cached properties and avoid a call to the Mojang API
 + */
++@NullMarked
 +public class PreFillProfileEvent extends Event {
 +
 +    private static final HandlerList HANDLER_LIST = new HandlerList();
 +
-+    @NotNull private final PlayerProfile profile;
++    private final PlayerProfile profile;
 +
 +    @ApiStatus.Internal
-+    public PreFillProfileEvent(@NotNull PlayerProfile profile) {
++    public PreFillProfileEvent(final PlayerProfile profile) {
 +        super(!org.bukkit.Bukkit.isPrimaryThread());
 +        this.profile = profile;
 +    }
@@ -155,7 +151,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    /**
 +     * @return The profile that needs its properties filled
 +     */
-+    @NotNull
 +    public PlayerProfile getPlayerProfile() {
 +        return this.profile;
 +    }
@@ -163,21 +158,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    /**
 +     * Sets the properties on the profile, avoiding the call to the Mojang API
 +     * Same as .getPlayerProfile().setProperties(properties);
-+     * 
-+     * @see PlayerProfile#setProperties(Collection)
++     *
 +     * @param properties The properties to set/append
++     * @see PlayerProfile#setProperties(Collection)
 +     */
-+    public void setProperties(@NotNull Collection<ProfileProperty> properties) {
++    public void setProperties(final Collection<ProfileProperty> properties) {
 +        this.profile.setProperties(properties);
 +    }
 +
-+    @NotNull
 +    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
 +
-+    @NotNull
 +    public static HandlerList getHandlerList() {
 +        return HANDLER_LIST;
 +    }
diff --git a/patches/api/LootTable-API.patch b/patches/api/LootTable-API.patch
index 4502964142..4b6aa05bee 100644
--- a/patches/api/LootTable-API.patch
+++ b/patches/api/LootTable-API.patch
@@ -20,17 +20,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +import org.bukkit.block.Block;
 +import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
 +
 +/**
 + * Represents an Inventory that can generate loot, such as Chests inside of Fortresses and Mineshafts
 + */
++@NullMarked
 +public interface LootableBlockInventory extends LootableInventory {
 +
 +    /**
 +     * Gets the block that is lootable
 +     * @return The Block
 +     */
-+    @NotNull
 +    Block getBlock();
 +}
 diff --git a/src/main/java/com/destroystokyo/paper/loottable/LootableEntityInventory.java b/src/main/java/com/destroystokyo/paper/loottable/LootableEntityInventory.java
@@ -43,17 +44,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +import org.bukkit.entity.Entity;
 +import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
 +
 +/**
 + * Represents an Inventory that can generate loot, such as Minecarts inside of Mineshafts
 + */
++@NullMarked
 +public interface LootableEntityInventory extends LootableInventory {
 +
 +    /**
 +     * Gets the entity that is lootable
 +     * @return The Entity
 +     */
-+    @NotNull
 +    Entity getEntity();
 +}
 diff --git a/src/main/java/com/destroystokyo/paper/loottable/LootableInventory.java b/src/main/java/com/destroystokyo/paper/loottable/LootableInventory.java
@@ -64,44 +66,46 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 @@ -0,0 +0,0 @@
 +package com.destroystokyo.paper.loottable;
 +
++import java.util.UUID;
 +import org.bukkit.entity.Player;
 +import org.bukkit.loot.Lootable;
-+
-+import java.util.UUID;
-+import org.jetbrains.annotations.NotNull;
 +import org.jetbrains.annotations.Nullable;
++import org.jspecify.annotations.NullMarked;
 +
 +/**
 + * Represents an Inventory that contains a Loot Table associated to it that will
 + * automatically fill on first open.
-+ *
++ * <p>
 + * A new feature and API is provided to support automatically refreshing the contents
 + * of the inventory based on that Loot Table after a configurable amount of time has passed.
-+ *
++ * <p>
 + * The behavior of how the Inventory is filled based on the loot table may vary based
 + * on Minecraft versions and the Loot Table feature.
 + */
++@NullMarked
 +public interface LootableInventory extends Lootable {
 +
 +    /**
-+     * Server owners have to enable whether or not an object in a world should refill
++     * Server owners have to enable whether an object in a world should refill
 +     *
 +     * @return If the world this inventory is currently in has Replenishable Lootables enabled
 +     */
 +    boolean isRefillEnabled();
 +
 +    /**
-+     * Whether or not this object has ever been filled
++     * Whether this object has ever been filled
++     *
 +     * @return Has ever been filled
 +     */
 +    boolean hasBeenFilled();
 +
 +    /**
 +     * Has this player ever looted this block
++     *
 +     * @param player The player to check
-+     * @return Whether or not this player has looted this block
++     * @return Whether this player has looted this block
 +     */
-+    default boolean hasPlayerLooted(final @NotNull Player player) {
++    default boolean hasPlayerLooted(final Player player) {
 +        return this.hasPlayerLooted(player.getUniqueId());
 +    }
 +
@@ -109,17 +113,17 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * Checks if this player can loot this block. Takes into account the "restrict player reloot" settings
 +     *
 +     * @param player the player to check
-+     *
 +     * @return Whether this player can loot this block
 +     */
-+    boolean canPlayerLoot(@NotNull UUID player);
++    boolean canPlayerLoot(UUID player);
 +
 +    /**
 +     * Has this player ever looted this block
++     *
 +     * @param player The player to check
-+     * @return Whether or not this player has looted this block
++     * @return Whether this player has looted this block
 +     */
-+    boolean hasPlayerLooted(@NotNull UUID player);
++    boolean hasPlayerLooted(UUID player);
 +
 +    /**
 +     * Gets the timestamp, in milliseconds, of when the player last looted this object
@@ -127,7 +131,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * @param player The player to check
 +     * @return Timestamp last looted, or null if player has not looted this object
 +     */
-+    default @Nullable Long getLastLooted(final @NotNull Player player) {
++    default @Nullable Long getLastLooted(final Player player) {
 +        return this.getLastLooted(player.getUniqueId());
 +    }
 +
@@ -138,28 +142,31 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * @return Timestamp last looted, or null if player has not looted this object
 +     */
 +    @Nullable
-+    Long getLastLooted(@NotNull UUID player);
++    Long getLastLooted(UUID player);
 +
 +    /**
-+     * Change the state of whether or not a player has looted this block
++     * Change the state of whether a player has looted this block
++     *
 +     * @param player The player to change state for
 +     * @param looted true to add player to looted list, false to remove
 +     * @return The previous state of whether the player had looted this or not
 +     */
-+    default boolean setHasPlayerLooted(final @NotNull Player player, final boolean looted) {
++    default boolean setHasPlayerLooted(final Player player, final boolean looted) {
 +        return this.setHasPlayerLooted(player.getUniqueId(), looted);
 +    }
 +
 +    /**
-+     * Change the state of whether or not a player has looted this block
++     * Change the state of whether a player has looted this block
++     *
 +     * @param player The player to change state for
 +     * @param looted true to add player to looted list, false to remove
 +     * @return The previous state of whether the player had looted this or not
 +     */
-+    boolean setHasPlayerLooted(@NotNull UUID player, boolean looted);
++    boolean setHasPlayerLooted(UUID player, boolean looted);
 +
 +    /**
-+     * Returns Whether or not this object has been filled and now has a pending refill
++     * Returns Whether this object has been filled and now has a pending refill
++     *
 +     * @return Has pending refill
 +     */
 +    boolean hasPendingRefill();
@@ -199,22 +206,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.event.HandlerList;
 +import org.bukkit.event.player.PlayerEvent;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
 +
++@NullMarked
 +public class LootableInventoryReplenishEvent extends PlayerEvent implements Cancellable {
 +
 +    private static final HandlerList HANDLER_LIST = new HandlerList();
 +
-+    @NotNull private final LootableInventory inventory;
++    private final LootableInventory inventory;
 +    private boolean cancelled;
 +
 +    @ApiStatus.Internal
-+    public LootableInventoryReplenishEvent(@NotNull Player player, @NotNull LootableInventory inventory) {
++    public LootableInventoryReplenishEvent(final Player player, final LootableInventory inventory) {
 +        super(player);
 +        this.inventory = inventory;
 +    }
 +
-+    @NotNull
 +    public LootableInventory getInventory() {
 +        return this.inventory;
 +    }
@@ -225,16 +232,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
 +
 +    @Override
-+    public void setCancelled(boolean cancel) {
++    public void setCancelled(final boolean cancel) {
 +        this.cancelled = cancel;
 +    }
 +
-+    @NotNull
++    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
 +
-+    @NotNull
 +    public static HandlerList getHandlerList() {
 +        return HANDLER_LIST;
 +    }
diff --git a/patches/api/Mob-Pathfinding-API.patch b/patches/api/Mob-Pathfinding-API.patch
index 09d62a197d..376f0bebb7 100644
--- a/patches/api/Mob-Pathfinding-API.patch
+++ b/patches/api/Mob-Pathfinding-API.patch
@@ -19,24 +19,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 @@ -0,0 +0,0 @@
 +package com.destroystokyo.paper.entity;
 +
++import java.util.List;
 +import org.bukkit.Location;
 +import org.bukkit.entity.LivingEntity;
 +import org.bukkit.entity.Mob;
-+
-+import java.util.List;
-+import org.jetbrains.annotations.NotNull;
-+import org.jetbrains.annotations.Nullable;
++import org.jspecify.annotations.NullMarked;
++import org.jspecify.annotations.Nullable;
 +
 +/**
 + * Handles pathfinding operations for an Entity
 + */
++@NullMarked
 +public interface Pathfinder {
 +
 +    /**
-+     *
 +     * @return The entity that is controlled by this pathfinder
 +     */
-+    @NotNull
 +    Mob getEntity();
 +
 +    /**
@@ -46,6 +44,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +    /**
 +     * If the entity is currently trying to navigate to a destination, this will return true
++     *
 +     * @return true if the entity is navigating to a destination
 +     */
 +    boolean hasPath();
@@ -53,86 +52,88 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    /**
 +     * @return The location the entity is trying to navigate to, or null if there is no destination
 +     */
-+    @Nullable
-+    PathResult getCurrentPath();
++    @Nullable PathResult getCurrentPath();
 +
 +    /**
 +     * Calculates a destination for the Entity to navigate to, but does not set it
 +     * as the current target. Useful for calculating what would happen before setting it.
++     *
 +     * @param loc Location to navigate to
 +     * @return The closest Location the Entity can get to for this navigation, or null if no path could be calculated
 +     */
-+    @Nullable PathResult findPath(@NotNull Location loc);
++    @Nullable PathResult findPath(Location loc);
 +
 +    /**
 +     * Calculates a destination for the Entity to navigate to to reach the target entity,
 +     * but does not set it as the current target.
 +     * Useful for calculating what would happen before setting it.
-+     *
++     * <p>
 +     * The behavior of this PathResult is subject to the games pathfinding rules, and may
 +     * result in the pathfinding automatically updating to follow the target Entity.
-+     *
++     * <p>
 +     * However, this behavior is not guaranteed, and is subject to the games behavior.
 +     *
 +     * @param target the Entity to navigate to
 +     * @return The closest Location the Entity can get to for this navigation, or null if no path could be calculated
 +     */
-+    @Nullable PathResult findPath(@NotNull LivingEntity target);
++    @Nullable PathResult findPath(LivingEntity target);
 +
 +    /**
 +     * Calculates a destination for the Entity to navigate to, and sets it with default speed
 +     * as the current target.
++     *
 +     * @param loc Location to navigate to
 +     * @return If the pathfinding was successfully started
 +     */
-+    default boolean moveTo(@NotNull Location loc) {
-+        return moveTo(loc, 1);
++    default boolean moveTo(Location loc) {
++        return this.moveTo(loc, 1);
 +    }
 +
 +    /**
 +     * Calculates a destination for the Entity to navigate to, with desired speed
 +     * as the current target.
-+     * @param loc Location to navigate to
++     *
++     * @param loc   Location to navigate to
 +     * @param speed Speed multiplier to navigate at, where 1 is 'normal'
 +     * @return If the pathfinding was successfully started
 +     */
-+    default boolean moveTo(@NotNull Location loc, double speed) {
-+        PathResult path = findPath(loc);
-+        return path != null && moveTo(path, speed);
++    default boolean moveTo(Location loc, double speed) {
++        PathResult path = this.findPath(loc);
++        return path != null && this.moveTo(path, speed);
 +    }
 +
 +    /**
 +     * Calculates a destination for the Entity to navigate to to reach the target entity,
 +     * and sets it with default speed.
-+     *
++     * <p>
 +     * The behavior of this PathResult is subject to the games pathfinding rules, and may
 +     * result in the pathfinding automatically updating to follow the target Entity.
-+     *
++     * <p>
 +     * However, this behavior is not guaranteed, and is subject to the games behavior.
 +     *
 +     * @param target the Entity to navigate to
 +     * @return If the pathfinding was successfully started
 +     */
-+    default boolean moveTo(@NotNull LivingEntity target) {
-+        return moveTo(target, 1);
++    default boolean moveTo(LivingEntity target) {
++        return this.moveTo(target, 1);
 +    }
 +
 +    /**
 +     * Calculates a destination for the Entity to navigate to to reach the target entity,
 +     * and sets it with specified speed.
-+     *
++     * <p>
 +     * The behavior of this PathResult is subject to the games pathfinding rules, and may
 +     * result in the pathfinding automatically updating to follow the target Entity.
-+     *
++     * <p>
 +     * However, this behavior is not guaranteed, and is subject to the games behavior.
 +     *
 +     * @param target the Entity to navigate to
-+     * @param speed Speed multiplier to navigate at, where 1 is 'normal'
++     * @param speed  Speed multiplier to navigate at, where 1 is 'normal'
 +     * @return If the pathfinding was successfully started
 +     */
-+    default boolean moveTo(@NotNull LivingEntity target, double speed) {
-+        PathResult path = findPath(target);
-+        return path != null && moveTo(path, speed);
++    default boolean moveTo(LivingEntity target, double speed) {
++        PathResult path = this.findPath(target);
++        return path != null && this.moveTo(path, speed);
 +    }
 +
 +    /**
@@ -142,19 +143,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * @param path The Path to start following
 +     * @return If the pathfinding was successfully started
 +     */
-+    default boolean moveTo(@NotNull PathResult path) {
-+        return moveTo(path, 1);
++    default boolean moveTo(PathResult path) {
++        return this.moveTo(path, 1);
 +    }
 +
 +    /**
 +     * Takes the result of a previous pathfinding calculation and sets it
 +     * as the active pathfinding,
 +     *
-+     * @param path The Path to start following
++     * @param path  The Path to start following
 +     * @param speed Speed multiplier to navigate at, where 1 is 'normal'
 +     * @return If the pathfinding was successfully started
 +     */
-+    boolean moveTo(@NotNull PathResult path, double speed);
++    boolean moveTo(PathResult path, double speed);
 +
 +    /**
 +     * Checks if this pathfinder allows passing through closed doors.
@@ -205,11 +206,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +        /**
 +         * All currently calculated points to follow along the path to reach the destination location
-+         *
++         * <p>
 +         * Will return points the entity has already moved past, see {@link #getNextPointIndex()}
++         *
 +         * @return List of points
 +         */
-+        @NotNull
 +        List<Location> getPoints();
 +
 +        /**
diff --git a/patches/api/Paper-Utils.patch b/patches/api/Paper-Utils.patch
index 1996a0190d..72f5ec6584 100644
--- a/patches/api/Paper-Utils.patch
+++ b/patches/api/Paper-Utils.patch
@@ -12,16 +12,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 @@ -0,0 +0,0 @@
 +package com.destroystokyo.paper.util;
 +
-+import org.jetbrains.annotations.NotNull;
++import org.jetbrains.annotations.ApiStatus;
++import org.jspecify.annotations.NullMarked;
 +
-+public class SneakyThrow {
++@ApiStatus.Internal
++@NullMarked
++public final class SneakyThrow {
 +
-+    public static void sneaky(@NotNull Throwable exception) {
-+        SneakyThrow.<RuntimeException>throwSneaky(exception);
++    public static void sneaky(final Throwable exception) {
++        SneakyThrow.throwSneaky(exception);
 +    }
 +
 +    @SuppressWarnings("unchecked")
-+    private static <T extends Throwable> void throwSneaky(@NotNull Throwable exception) throws T {
++    private static <T extends Throwable> void throwSneaky(final Throwable exception) throws T {
 +        throw (T) exception;
 +    }
 +
diff --git a/patches/api/Player-Chunk-Load-Unload-Events.patch b/patches/api/Player-Chunk-Load-Unload-Events.patch
index 5b28480f69..dd299315d5 100644
--- a/patches/api/Player-Chunk-Load-Unload-Events.patch
+++ b/patches/api/Player-Chunk-Load-Unload-Events.patch
@@ -17,7 +17,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.event.HandlerList;
 +import org.bukkit.event.world.ChunkEvent;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
 +
 +/**
 + * Is called when a {@link Player} receives a {@link Chunk}
@@ -27,6 +27,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 + * Should only be used for packet/clientside related stuff.
 + * Not intended for modifying server side state.
 + */
++@NullMarked
 +public class PlayerChunkLoadEvent extends ChunkEvent {
 +
 +    private static final HandlerList HANDLER_LIST = new HandlerList();
@@ -34,23 +35,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    private final Player player;
 +
 +    @ApiStatus.Internal
-+    public PlayerChunkLoadEvent(@NotNull Chunk chunk, @NotNull Player player) {
++    public PlayerChunkLoadEvent(final Chunk chunk, final Player player) {
 +        super(chunk);
 +        this.player = player;
 +    }
 +
-+    @NotNull
 +    public Player getPlayer() {
 +        return this.player;
 +    }
 +
-+    @NotNull
 +    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
 +
-+    @NotNull
 +    public static HandlerList getHandlerList() {
 +        return HANDLER_LIST;
 +    }
@@ -68,7 +66,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.event.HandlerList;
 +import org.bukkit.event.world.ChunkEvent;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
 +
 +/**
 + * Is called when a {@link Player} receives a chunk unload packet.
@@ -76,6 +74,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 + * Should only be used for packet/clientside related stuff.
 + * Not intended for modifying server side.
 + */
++@NullMarked
 +public class PlayerChunkUnloadEvent extends ChunkEvent {
 +
 +    private static final HandlerList HANDLER_LIST = new HandlerList();
@@ -83,23 +82,20 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    private final Player player;
 +
 +    @ApiStatus.Internal
-+    public PlayerChunkUnloadEvent(@NotNull Chunk chunk, @NotNull Player player) {
++    public PlayerChunkUnloadEvent(final Chunk chunk, final Player player) {
 +        super(chunk);
 +        this.player = player;
 +    }
 +
-+    @NotNull
 +    public Player getPlayer() {
 +        return this.player;
 +    }
 +
-+    @NotNull
 +    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
 +
-+    @NotNull
 +    public static HandlerList getHandlerList() {
 +        return HANDLER_LIST;
 +    }
diff --git a/patches/api/Player-Entity-Tracking-Events.patch b/patches/api/Player-Entity-Tracking-Events.patch
index 5f891d3d25..e6c4597e56 100644
--- a/patches/api/Player-Entity-Tracking-Events.patch
+++ b/patches/api/Player-Entity-Tracking-Events.patch
@@ -18,7 +18,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.event.HandlerList;
 +import org.bukkit.event.player.PlayerEvent;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
 +
 +/**
 + * Is called when a {@link Player} tracks an {@link Entity}.
@@ -28,6 +28,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 + * Adding or removing entities from the world at the point in time this event is called is completely
 + * unsupported and should be avoided.
 + */
++@NullMarked
 +public class PlayerTrackEntityEvent extends PlayerEvent implements Cancellable {
 +
 +    private static final HandlerList HANDLER_LIST = new HandlerList();
@@ -36,7 +37,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    private boolean cancelled;
 +
 +    @ApiStatus.Internal
-+    public PlayerTrackEntityEvent(@NotNull Player player, @NotNull Entity entity) {
++    public PlayerTrackEntityEvent(final Player player, final Entity entity) {
 +        super(player);
 +        this.entity = entity;
 +    }
@@ -46,7 +47,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return the entity tracked
 +     */
-+    @NotNull
 +    public Entity getEntity() {
 +        return this.entity;
 +    }
@@ -57,16 +57,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
 +
 +    @Override
-+    public void setCancelled(boolean cancel) {
++    public void setCancelled(final boolean cancel) {
 +        this.cancelled = cancel;
 +    }
 +
-+    @NotNull
 +    public static HandlerList getHandlerList() {
 +        return HANDLER_LIST;
 +    }
 +
-+    @NotNull
 +    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
@@ -85,7 +83,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.event.HandlerList;
 +import org.bukkit.event.player.PlayerEvent;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
 +
 +/**
 + * Is called when a {@link Player} untracks an {@link Entity}.
@@ -93,6 +91,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 + * Adding or removing entities from the world at the point in time this event is called is completely
 + * unsupported and should be avoided.
 + */
++@NullMarked
 +public class PlayerUntrackEntityEvent extends PlayerEvent {
 +
 +    private static final HandlerList HANDLER_LIST = new HandlerList();
@@ -100,7 +99,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    private final Entity entity;
 +
 +    @ApiStatus.Internal
-+    public PlayerUntrackEntityEvent(@NotNull Player player, @NotNull Entity entity) {
++    public PlayerUntrackEntityEvent(final Player player, final Entity entity) {
 +        super(player);
 +        this.entity = entity;
 +    }
@@ -110,17 +109,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return the entity untracked
 +     */
-+    @NotNull
 +    public Entity getEntity() {
 +        return this.entity;
 +    }
 +
-+    @NotNull
 +    public static HandlerList getHandlerList() {
 +        return HANDLER_LIST;
 +    }
 +
-+    @NotNull
 +    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
diff --git a/patches/api/PlayerElytraBoostEvent.patch b/patches/api/PlayerElytraBoostEvent.patch
index ae001dfca5..42b5c8c61f 100644
--- a/patches/api/PlayerElytraBoostEvent.patch
+++ b/patches/api/PlayerElytraBoostEvent.patch
@@ -20,25 +20,25 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.inventory.EquipmentSlot;
 +import org.bukkit.inventory.ItemStack;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
 +
 +/**
 + * Fired when a player boosts elytra flight with a firework
 + */
++@NullMarked
 +public class PlayerElytraBoostEvent extends PlayerEvent implements Cancellable {
 +
 +    private static final HandlerList HANDLER_LIST = new HandlerList();
 +
-+    @NotNull private final ItemStack itemStack;
-+    @NotNull private final Firework firework;
++    private final ItemStack itemStack;
++    private final Firework firework;
 +    private boolean consume = true;
-+    @NotNull
 +    private final EquipmentSlot hand;
 +
 +    private boolean cancelled;
 +
 +    @ApiStatus.Internal
-+    public PlayerElytraBoostEvent(@NotNull Player player, @NotNull ItemStack itemStack, @NotNull Firework firework, @NotNull EquipmentSlot hand) {
++    public PlayerElytraBoostEvent(final Player player, final ItemStack itemStack, final Firework firework, final EquipmentSlot hand) {
 +        super(player);
 +        this.itemStack = itemStack;
 +        this.firework = firework;
@@ -50,7 +50,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return ItemStack of firework
 +     */
-+    @NotNull
 +    public ItemStack getItemStack() {
 +        return this.itemStack;
 +    }
@@ -60,7 +59,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return Firework entity
 +     */
-+    @NotNull
 +    public Firework getFirework() {
 +        return this.firework;
 +    }
@@ -79,7 +77,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @param consume {@code true} to consume
 +     */
-+    public void setShouldConsume(boolean consume) {
++    public void setShouldConsume(final boolean consume) {
 +        this.consume = consume;
 +    }
 +
@@ -88,7 +86,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return interaction hand
 +     */
-+    @NotNull
 +    public EquipmentSlot getHand() {
 +        return this.hand;
 +    }
@@ -99,17 +96,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
 +
 +    @Override
-+    public void setCancelled(boolean cancel) {
++    public void setCancelled(final boolean cancel) {
 +        this.cancelled = cancel;
 +    }
 +
-+    @NotNull
 +    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
 +
-+    @NotNull
 +    public static HandlerList getHandlerList() {
 +        return HANDLER_LIST;
 +    }
diff --git a/patches/api/PlayerLaunchProjectileEvent.patch b/patches/api/PlayerLaunchProjectileEvent.patch
index c08581d7af..e0623138b0 100644
--- a/patches/api/PlayerLaunchProjectileEvent.patch
+++ b/patches/api/PlayerLaunchProjectileEvent.patch
@@ -20,7 +20,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.event.player.PlayerEvent;
 +import org.bukkit.inventory.ItemStack;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
 +
 +/**
 + * Called when a player shoots a projectile.
@@ -29,18 +29,19 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 + * of a bow or crossbow. A plugin may listen to {@link EntityShootBowEvent}
 + * for these actions instead.
 + */
++@NullMarked
 +public class PlayerLaunchProjectileEvent extends PlayerEvent implements Cancellable {
 +
 +    private static final HandlerList HANDLER_LIST = new HandlerList();
 +
-+    @NotNull private final Projectile projectile;
-+    @NotNull private final ItemStack itemStack;
++    private final Projectile projectile;
++    private final ItemStack itemStack;
 +    private boolean consumeItem = true;
 +
 +    private boolean cancelled;
 +
 +    @ApiStatus.Internal
-+    public PlayerLaunchProjectileEvent(@NotNull Player shooter, @NotNull ItemStack itemStack, @NotNull Projectile projectile) {
++    public PlayerLaunchProjectileEvent(final Player shooter, final ItemStack itemStack, final Projectile projectile) {
 +        super(shooter);
 +        this.itemStack = itemStack;
 +        this.projectile = projectile;
@@ -51,7 +52,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return the launched projectile
 +     */
-+    @NotNull
 +    public Projectile getProjectile() {
 +        return this.projectile;
 +    }
@@ -61,7 +61,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return The ItemStack used
 +     */
-+    @NotNull
 +    public ItemStack getItemStack() {
 +        return this.itemStack;
 +    }
@@ -80,7 +79,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @param consumeItem {@code true} to consume
 +     */
-+    public void setShouldConsume(boolean consumeItem) {
++    public void setShouldConsume(final boolean consumeItem) {
 +        this.consumeItem = consumeItem;
 +    }
 +
@@ -90,17 +89,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
 +
 +    @Override
-+    public void setCancelled(boolean cancel) {
++    public void setCancelled(final boolean cancel) {
 +        this.cancelled = cancel;
 +    }
 +
-+    @NotNull
 +    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
 +
-+    @NotNull
 +    public static HandlerList getHandlerList() {
 +        return HANDLER_LIST;
 +    }
diff --git a/patches/api/PlayerPickupExperienceEvent.patch b/patches/api/PlayerPickupExperienceEvent.patch
index ef85c5b775..6fb2c304a6 100644
--- a/patches/api/PlayerPickupExperienceEvent.patch
+++ b/patches/api/PlayerPickupExperienceEvent.patch
@@ -42,20 +42,21 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.event.HandlerList;
 +import org.bukkit.event.player.PlayerEvent;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
 +
 +/**
 + * Fired when a player is attempting to pick up an experience orb
 + */
++@NullMarked
 +public class PlayerPickupExperienceEvent extends PlayerEvent implements Cancellable {
 +
 +    private static final HandlerList HANDLER_LIST = new HandlerList();
 +
-+    @NotNull private final ExperienceOrb experienceOrb;
++    private final ExperienceOrb experienceOrb;
 +    private boolean cancelled;
 +
 +    @ApiStatus.Internal
-+    public PlayerPickupExperienceEvent(@NotNull Player player, @NotNull ExperienceOrb experienceOrb) {
++    public PlayerPickupExperienceEvent(final Player player, final ExperienceOrb experienceOrb) {
 +        super(player);
 +        this.experienceOrb = experienceOrb;
 +    }
@@ -63,7 +64,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    /**
 +     * @return Returns the Orb that the player is picking up
 +     */
-+    @NotNull
 +    public ExperienceOrb getExperienceOrb() {
 +        return this.experienceOrb;
 +    }
@@ -79,17 +79,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * If {@code true}, cancels picking up the experience orb, leaving it in the world
 +     */
 +    @Override
-+    public void setCancelled(boolean cancel) {
++    public void setCancelled(final boolean cancel) {
 +        this.cancelled = cancel;
 +    }
 +
-+    @NotNull
 +    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
 +
-+    @NotNull
 +    public static HandlerList getHandlerList() {
 +        return HANDLER_LIST;
 +    }
diff --git a/patches/api/PlayerReadyArrowEvent.patch b/patches/api/PlayerReadyArrowEvent.patch
index ab8e049080..abbb2d84fa 100644
--- a/patches/api/PlayerReadyArrowEvent.patch
+++ b/patches/api/PlayerReadyArrowEvent.patch
@@ -42,21 +42,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.event.HandlerList;
 +import org.bukkit.event.player.PlayerEvent;
 +import org.bukkit.inventory.ItemStack;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
 +
 +/**
 + * Called when a player is firing a bow and the server is choosing an arrow to use.
 + */
++@NullMarked
 +public class PlayerReadyArrowEvent extends PlayerEvent implements Cancellable {
 +
 +    private static final HandlerList HANDLER_LIST = new HandlerList();
 +
-+    @NotNull private final ItemStack bow;
-+    @NotNull private final ItemStack arrow;
++    private final ItemStack bow;
++    private final ItemStack arrow;
 +
 +    private boolean cancelled;
 +
-+    public PlayerReadyArrowEvent(@NotNull Player player, @NotNull ItemStack bow, @NotNull ItemStack arrow) {
++    public PlayerReadyArrowEvent(final Player player, final ItemStack bow, final ItemStack arrow) {
 +        super(player);
 +        this.bow = bow;
 +        this.arrow = arrow;
@@ -65,7 +66,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    /**
 +     * @return the player is using to fire the arrow
 +     */
-+    @NotNull
 +    public ItemStack getBow() {
 +        return this.bow;
 +    }
@@ -73,7 +73,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    /**
 +     * @return the arrow that is attempting to be used
 +     */
-+    @NotNull
 +    public ItemStack getArrow() {
 +        return this.arrow;
 +    }
@@ -92,16 +91,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * Cancel use of this arrow. On cancel, the server will try the next arrow available and fire another event.
 +     */
 +    @Override
-+    public void setCancelled(boolean cancel) {
-+       this.cancelled = cancel;
++    public void setCancelled(final boolean cancel) {
++        this.cancelled = cancel;
 +    }
 +
-+    @NotNull
++    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
 +
-+    @NotNull
 +    public static HandlerList getHandlerList() {
 +        return HANDLER_LIST;
 +    }
diff --git a/patches/api/PlayerTeleportEndGatewayEvent.patch b/patches/api/PlayerTeleportEndGatewayEvent.patch
index 69b61ed8bd..fac07252cc 100644
--- a/patches/api/PlayerTeleportEndGatewayEvent.patch
+++ b/patches/api/PlayerTeleportEndGatewayEvent.patch
@@ -18,17 +18,18 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.entity.Player;
 +import org.bukkit.event.player.PlayerTeleportEvent;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
 +
 +/**
 + * Fired when a teleport is triggered for an End Gateway
 + */
++@NullMarked
 +public class PlayerTeleportEndGatewayEvent extends PlayerTeleportEvent {
 +
-+    @NotNull private final EndGateway gateway;
++    private final EndGateway gateway;
 +
 +    @ApiStatus.Internal
-+    public PlayerTeleportEndGatewayEvent(@NotNull Player player, @NotNull Location from, @NotNull Location to, @NotNull EndGateway gateway) {
++    public PlayerTeleportEndGatewayEvent(final Player player, final Location from, final Location to, final EndGateway gateway) {
 +        super(player, from, to, PlayerTeleportEvent.TeleportCause.END_GATEWAY);
 +        this.gateway = gateway;
 +    }
@@ -38,7 +39,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return EndGateway used
 +     */
-+    @NotNull
 +    public EndGateway getGateway() {
 +        return this.gateway;
 +    }
diff --git a/patches/api/ProfileWhitelistVerifyEvent.patch b/patches/api/ProfileWhitelistVerifyEvent.patch
index a4c86876a1..81f76c0b47 100644
--- a/patches/api/ProfileWhitelistVerifyEvent.patch
+++ b/patches/api/ProfileWhitelistVerifyEvent.patch
@@ -44,8 +44,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.event.Event;
 +import org.bukkit.event.HandlerList;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
-+import org.jetbrains.annotations.Nullable;
++import org.jspecify.annotations.NullMarked;
++import org.jspecify.annotations.Nullable;
 +
 +/**
 + * Fires when the server needs to verify if a player is whitelisted.
@@ -53,24 +53,25 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 + * Plugins may override/control the servers whitelist with this event,
 + * and dynamically change the kick message.
 + */
++@NullMarked
 +public class ProfileWhitelistVerifyEvent extends Event {
 +
 +    private static final HandlerList HANDLER_LIST = new HandlerList();
 +
-+    @NotNull private final PlayerProfile profile;
++    private final PlayerProfile profile;
 +    private final boolean whitelistEnabled;
 +    private final boolean isOp;
 +    private boolean whitelisted;
-+    @Nullable private Component kickMessage;
++    private @Nullable Component kickMessage;
 +
 +    @Deprecated
 +    @ApiStatus.Internal
-+    public ProfileWhitelistVerifyEvent(@NotNull final PlayerProfile profile, boolean whitelistEnabled, boolean whitelisted, boolean isOp, @Nullable String kickMessage) {
++    public ProfileWhitelistVerifyEvent(final PlayerProfile profile, final boolean whitelistEnabled, final boolean whitelisted, final boolean isOp, final @Nullable String kickMessage) {
 +        this(profile, whitelistEnabled, whitelisted, isOp, kickMessage == null ? null : LegacyComponentSerializer.legacySection().deserialize(kickMessage));
 +    }
 +
 +    @ApiStatus.Internal
-+    public ProfileWhitelistVerifyEvent(@NotNull final PlayerProfile profile, boolean whitelistEnabled, boolean whitelisted, boolean isOp, @Nullable Component kickMessage) {
++    public ProfileWhitelistVerifyEvent(final PlayerProfile profile, final boolean whitelistEnabled, final boolean whitelisted, final boolean isOp, final @Nullable Component kickMessage) {
 +        this.profile = profile;
 +        this.whitelistEnabled = whitelistEnabled;
 +        this.whitelisted = whitelisted;
@@ -83,8 +84,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * @deprecated use {@link #kickMessage()}
 +     */
 +    @Deprecated
-+    @Nullable
-+    public String getKickMessage() {
++    public @Nullable String getKickMessage() {
 +        return this.kickMessage == null ? null : LegacyComponentSerializer.legacySection().serialize(this.kickMessage);
 +    }
 +
@@ -93,35 +93,33 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * @deprecated Use {@link #kickMessage(Component)}
 +     */
 +    @Deprecated
-+    public void setKickMessage(@Nullable String kickMessage) {
++    public void setKickMessage(final @Nullable String kickMessage) {
 +        this.kickMessage(kickMessage == null ? null : LegacyComponentSerializer.legacySection().deserialize(kickMessage));
 +    }
 +
 +    /**
 +     * @return the currently planned message to send to the user if they are not whitelisted
 +     */
-+    @Nullable
-+    public Component kickMessage() {
++    public @Nullable Component kickMessage() {
 +        return this.kickMessage;
 +    }
 +
 +    /**
 +     * @param kickMessage The message to send to the player on kick if not whitelisted. May set to {@code null} to use the server configured default
 +     */
-+    public void kickMessage(@Nullable Component kickMessage) {
++    public void kickMessage(final @Nullable Component kickMessage) {
 +        this.kickMessage = kickMessage;
 +    }
 +
 +    /**
 +     * @return The profile of the player trying to connect
 +     */
-+    @NotNull
 +    public PlayerProfile getPlayerProfile() {
 +        return this.profile;
 +    }
 +
 +    /**
-+     * @return Whether the player is whitelisted to play on this server (whitelist may be off is why its true)
++     * @return Whether the player is whitelisted to play on this server (whitelist may be off is why it's true)
 +     */
 +    public boolean isWhitelisted() {
 +        return this.whitelisted;
@@ -129,9 +127,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +    /**
 +     * Changes the players whitelisted state. {@code false} will deny the login
++     *
 +     * @param whitelisted The new whitelisted state
 +     */
-+    public void setWhitelisted(boolean whitelisted) {
++    public void setWhitelisted(final boolean whitelisted) {
 +        this.whitelisted = whitelisted;
 +    }
 +
@@ -149,13 +148,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        return this.whitelistEnabled;
 +    }
 +
-+    @NotNull
 +    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
 +
-+    @NotNull
 +    public static HandlerList getHandlerList() {
 +        return HANDLER_LIST;
 +    }
diff --git a/patches/api/RangedEntity-API.patch b/patches/api/RangedEntity-API.patch
index 746006b9de..f4982a9381 100644
--- a/patches/api/RangedEntity-API.patch
+++ b/patches/api/RangedEntity-API.patch
@@ -16,8 +16,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +import org.bukkit.entity.LivingEntity;
 +import org.bukkit.entity.Mob;
-+import org.jetbrains.annotations.NotNull;
++import org.jspecify.annotations.NullMarked;
 +
++@NullMarked
 +public interface RangedEntity extends Mob {
 +    /**
 +     * Attack the specified entity using a ranged attack.
@@ -26,7 +27,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * @param charge How "charged" the attack is (how far back the bow was pulled for Bow attacks).
 +     *               This should be a value between 0 and 1, represented as targetDistance/maxDistance.
 +     */
-+    void rangedAttack(@NotNull LivingEntity target, float charge);
++    void rangedAttack(LivingEntity target, float charge);
 +
 +    /**
 +     * Sets that the Entity is "charging" up an attack, by raising its hands
@@ -44,7 +45,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     */
 +    @Deprecated(since = "1.19.2")
 +    default boolean isChargingAttack() {
-+        return isHandRaised();
++        return this.isHandRaised();
 +    }
 +}
 diff --git a/src/main/java/org/bukkit/entity/AbstractSkeleton.java b/src/main/java/org/bukkit/entity/AbstractSkeleton.java
diff --git a/patches/api/Server-Tick-Events.patch b/patches/api/Server-Tick-Events.patch
index 5086dd3b38..ab6c97683e 100644
--- a/patches/api/Server-Tick-Events.patch
+++ b/patches/api/Server-Tick-Events.patch
@@ -64,6 +64,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        return this.timeEnd - System.nanoTime();
 +    }
 +
++    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
@@ -104,6 +105,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        return this.tickNumber;
 +    }
 +
++    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
diff --git a/patches/api/Slime-Pathfinder-Events.patch b/patches/api/Slime-Pathfinder-Events.patch
index 570f3433a0..8720815050 100644
--- a/patches/api/Slime-Pathfinder-Events.patch
+++ b/patches/api/Slime-Pathfinder-Events.patch
@@ -89,6 +89,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return The Slime that is pathfinding.
 +     */
++    @Override
 +    public Slime getEntity() {
 +        return (Slime) super.getEntity();
 +    }
@@ -103,6 +104,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        this.cancelled = cancel;
 +    }
 +
++    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
diff --git a/patches/api/Turtle-API.patch b/patches/api/Turtle-API.patch
index d49374b63f..9d04f77114 100644
--- a/patches/api/Turtle-API.patch
+++ b/patches/api/Turtle-API.patch
@@ -39,6 +39,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return The turtle
 +     */
++    @Override
 +    public Turtle getEntity() {
 +        return (Turtle) super.getEntity();
 +    }
@@ -53,6 +54,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        this.cancelled = cancel;
 +    }
 +
++    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
@@ -102,6 +104,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return The turtle
 +     */
++    @Override
 +    public Turtle getEntity() {
 +        return (Turtle) super.getEntity();
 +    }
@@ -147,6 +150,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        this.cancelled = cancel;
 +    }
 +
++    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
@@ -193,6 +197,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return The turtle
 +     */
++    @Override
 +    public Turtle getEntity() {
 +        return (Turtle) super.getEntity();
 +    }
@@ -216,6 +221,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        this.cancelled = cancel;
 +    }
 +
++    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
diff --git a/patches/api/Use-ASM-for-event-executors.patch b/patches/api/Use-ASM-for-event-executors.patch
index 81cf3961dd..1b68c017df 100644
--- a/patches/api/Use-ASM-for-event-executors.patch
+++ b/patches/api/Use-ASM-for-event-executors.patch
@@ -27,42 +27,46 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 @@ -0,0 +0,0 @@
 +package com.destroystokyo.paper.event.executor;
 +
++import com.destroystokyo.paper.util.SneakyThrow;
 +import java.lang.invoke.MethodHandle;
 +import java.lang.invoke.MethodHandles;
 +import java.lang.reflect.Method;
-+
-+import com.destroystokyo.paper.util.SneakyThrow;
 +import org.bukkit.event.Event;
 +import org.bukkit.event.EventException;
 +import org.bukkit.event.Listener;
 +import org.bukkit.plugin.EventExecutor;
-+import org.jetbrains.annotations.NotNull;
++import org.jetbrains.annotations.ApiStatus;
++import org.jspecify.annotations.NullMarked;
++import org.jspecify.annotations.Nullable;
 +
++@ApiStatus.Internal
++@NullMarked
 +public class MethodHandleEventExecutor implements EventExecutor {
++
 +    private final Class<? extends Event> eventClass;
 +    private final MethodHandle handle;
 +
-+    public MethodHandleEventExecutor(@NotNull Class<? extends Event> eventClass, @NotNull MethodHandle handle) {
++    public MethodHandleEventExecutor(final Class<? extends Event> eventClass, final MethodHandle handle) {
 +        this.eventClass = eventClass;
 +        this.handle = handle;
 +    }
 +
-+    public MethodHandleEventExecutor(@NotNull Class<? extends Event> eventClass, @NotNull Method m) {
++    public MethodHandleEventExecutor(final Class<? extends Event> eventClass, final Method m) {
 +        this.eventClass = eventClass;
 +        try {
 +            m.setAccessible(true);
 +            this.handle = MethodHandles.lookup().unreflect(m);
-+        } catch (IllegalAccessException e) {
++        } catch (final IllegalAccessException e) {
 +            throw new AssertionError("Unable to set accessible", e);
 +        }
 +    }
 +
 +    @Override
-+    public void execute(@NotNull Listener listener, @NotNull Event event) throws EventException {
-+        if (!eventClass.isInstance(event)) return;
++    public void execute(final Listener listener, final Event event) throws EventException {
++        if (!this.eventClass.isInstance(event)) return;
 +        try {
-+            handle.invoke(listener, event);
-+        } catch (Throwable t) {
++            this.handle.invoke(listener, event);
++        } catch (final Throwable t) {
 +            SneakyThrow.sneaky(t);
 +        }
 +    }
@@ -75,42 +79,44 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 @@ -0,0 +0,0 @@
 +package com.destroystokyo.paper.event.executor;
 +
++import com.destroystokyo.paper.util.SneakyThrow;
++import com.google.common.base.Preconditions;
 +import java.lang.invoke.MethodHandle;
 +import java.lang.invoke.MethodHandles;
 +import java.lang.reflect.Method;
 +import java.lang.reflect.Modifier;
-+
-+import com.destroystokyo.paper.util.SneakyThrow;
-+import com.google.common.base.Preconditions;
-+
 +import org.bukkit.event.Event;
 +import org.bukkit.event.EventException;
 +import org.bukkit.event.Listener;
 +import org.bukkit.plugin.EventExecutor;
-+import org.jetbrains.annotations.NotNull;
++import org.jetbrains.annotations.ApiStatus;
++import org.jspecify.annotations.NullMarked;
 +
++@ApiStatus.Internal
++@NullMarked
 +public class StaticMethodHandleEventExecutor implements EventExecutor {
++
 +    private final Class<? extends Event> eventClass;
 +    private final MethodHandle handle;
 +
-+    public StaticMethodHandleEventExecutor(@NotNull Class<? extends Event> eventClass, @NotNull Method m) {
++    public StaticMethodHandleEventExecutor(final Class<? extends Event> eventClass, final Method m) {
 +        Preconditions.checkArgument(Modifier.isStatic(m.getModifiers()), "Not a static method: %s", m);
 +        Preconditions.checkArgument(eventClass != null, "eventClass is null");
 +        this.eventClass = eventClass;
 +        try {
 +            m.setAccessible(true);
 +            this.handle = MethodHandles.lookup().unreflect(m);
-+        } catch (IllegalAccessException e) {
++        } catch (final IllegalAccessException e) {
 +            throw new AssertionError("Unable to set accessible", e);
 +        }
 +    }
 +
 +    @Override
-+    public void execute(@NotNull Listener listener, @NotNull Event event) throws EventException {
-+        if (!eventClass.isInstance(event)) return;
++    public void execute(final Listener listener, final Event event) throws EventException {
++        if (!this.eventClass.isInstance(event)) return;
 +        try {
-+            handle.invoke(event);
-+        } catch (Throwable throwable) {
++            this.handle.invoke(event);
++        } catch (final Throwable throwable) {
 +            SneakyThrow.sneaky(throwable);
 +        }
 +    }
@@ -125,23 +131,28 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +
 +import java.lang.reflect.Method;
 +import java.util.concurrent.atomic.AtomicInteger;
-+
 +import org.bukkit.plugin.EventExecutor;
-+import org.jetbrains.annotations.NotNull;
++import org.jetbrains.annotations.ApiStatus;
++import org.jspecify.annotations.NullMarked;
 +import org.objectweb.asm.ClassWriter;
 +import org.objectweb.asm.Type;
 +import org.objectweb.asm.commons.GeneratorAdapter;
 +
-+import static org.objectweb.asm.Opcodes.*;
++import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
++import static org.objectweb.asm.Opcodes.INVOKEINTERFACE;
++import static org.objectweb.asm.Opcodes.INVOKESPECIAL;
++import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL;
++import static org.objectweb.asm.Opcodes.V1_8;
 +
-+public class ASMEventExecutorGenerator {
++@ApiStatus.Internal
++@NullMarked
++public final class ASMEventExecutorGenerator {
 +
 +    private static final String EXECUTE_DESCRIPTOR = "(Lorg/bukkit/event/Listener;Lorg/bukkit/event/Event;)V";
 +
-+    @NotNull
-+    public static byte[] generateEventExecutor(@NotNull Method m, @NotNull String name) {
-+        ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
-+        writer.visit(V1_8, ACC_PUBLIC, name.replace('.', '/'), null, Type.getInternalName(Object.class), new String[] {Type.getInternalName(EventExecutor.class)});
++    public static byte[] generateEventExecutor(final Method m, final String name) {
++        final ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
++        writer.visit(V1_8, ACC_PUBLIC, name.replace('.', '/'), null, Type.getInternalName(Object.class), new String[]{Type.getInternalName(EventExecutor.class)});
 +        // Generate constructor
 +        GeneratorAdapter methodGenerator = new GeneratorAdapter(writer.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null), ACC_PUBLIC, "<init>", "()V");
 +        methodGenerator.loadThis();
@@ -169,9 +180,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
 +
 +    public static AtomicInteger NEXT_ID = new AtomicInteger(1);
-+    @NotNull
++
 +    public static String generateName() {
-+        int id = NEXT_ID.getAndIncrement();
++        final int id = NEXT_ID.getAndIncrement();
 +        return "com.destroystokyo.paper.event.executor.asm.generated.GeneratedEventExecutor" + id;
 +    }
 +}
@@ -183,8 +194,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 @@ -0,0 +0,0 @@
 +package com.destroystokyo.paper.event.executor.asm;
 +
-+import org.jetbrains.annotations.NotNull;
++import org.jetbrains.annotations.ApiStatus;
++import org.jspecify.annotations.NullMarked;
 +
++@ApiStatus.Internal
++@NullMarked
 +public interface ClassDefiner {
 +
 +    /**
@@ -192,7 +206,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return if classes bypass access checks
 +     */
-+    public default boolean isBypassAccessChecks() {
++    default boolean isBypassAccessChecks() {
 +        return false;
 +    }
 +
@@ -206,11 +220,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     * @throws ClassFormatError     if the class data is invalid
 +     * @throws NullPointerException if any of the arguments are null
 +     */
-+    @NotNull
-+    public Class<?> defineClass(@NotNull ClassLoader parentLoader, @NotNull String name, @NotNull byte[] data);
++    Class<?> defineClass(ClassLoader parentLoader, String name, byte[] data);
 +
-+    @NotNull
-+    public static ClassDefiner getInstance() {
++    static ClassDefiner getInstance() {
 +        return SafeClassDefiner.INSTANCE;
 +    }
 +
@@ -223,62 +235,64 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 @@ -0,0 +0,0 @@
 +package com.destroystokyo.paper.event.executor.asm;
 +
-+import java.util.concurrent.ConcurrentMap;
-+
 +import com.google.common.base.Preconditions;
-+
 +import com.google.common.collect.MapMaker;
-+import org.jetbrains.annotations.NotNull;
++import java.util.concurrent.ConcurrentMap;
++import org.jetbrains.annotations.ApiStatus;
++import org.jspecify.annotations.NullMarked;
 +
++@ApiStatus.Internal
++@NullMarked
 +public class SafeClassDefiner implements ClassDefiner {
++
 +    /* default */ static final SafeClassDefiner INSTANCE = new SafeClassDefiner();
 +
-+    private SafeClassDefiner() {}
++    private SafeClassDefiner() {
++    }
 +
 +    private final ConcurrentMap<ClassLoader, GeneratedClassLoader> loaders = new MapMaker().weakKeys().makeMap();
 +
-+    @NotNull
 +    @Override
-+    public Class<?> defineClass(@NotNull ClassLoader parentLoader, @NotNull String name, @NotNull byte[] data) {
-+        GeneratedClassLoader loader = loaders.computeIfAbsent(parentLoader, GeneratedClassLoader::new);
++    public Class<?> defineClass(final ClassLoader parentLoader, final String name, final byte[] data) {
++        final GeneratedClassLoader loader = this.loaders.computeIfAbsent(parentLoader, GeneratedClassLoader::new);
 +        synchronized (loader.getClassLoadingLock(name)) {
 +            Preconditions.checkState(!loader.hasClass(name), "%s already defined", name);
-+            Class<?> c = loader.define(name, data);
++            final Class<?> c = loader.define(name, data);
 +            assert c.getName().equals(name);
 +            return c;
 +        }
 +    }
 +
 +    private static class GeneratedClassLoader extends ClassLoader {
++
 +        static {
 +            ClassLoader.registerAsParallelCapable();
 +        }
 +
-+        protected GeneratedClassLoader(@NotNull ClassLoader parent) {
++        protected GeneratedClassLoader(final ClassLoader parent) {
 +            super(parent);
 +        }
 +
-+        private Class<?> define(@NotNull String name, byte[] data) {
-+            synchronized (getClassLoadingLock(name)) {
-+                assert !hasClass(name);
-+                Class<?> c = defineClass(name, data, 0, data.length);
-+                resolveClass(c);
++        private Class<?> define(final String name, final byte[] data) {
++            synchronized (this.getClassLoadingLock(name)) {
++                assert !this.hasClass(name);
++                final Class<?> c = this.defineClass(name, data, 0, data.length);
++                this.resolveClass(c);
 +                return c;
 +            }
 +        }
 +
 +        @Override
-+        @NotNull
-+        public Object getClassLoadingLock(@NotNull String name) {
++        public Object getClassLoadingLock(final String name) {
 +            return super.getClassLoadingLock(name);
 +        }
 +
-+        public boolean hasClass(@NotNull String name) {
-+            synchronized (getClassLoadingLock(name)) {
++        public boolean hasClass(final String name) {
++            synchronized (this.getClassLoadingLock(name)) {
 +                try {
 +                    Class.forName(name);
 +                    return true;
-+                } catch (ClassNotFoundException e) {
++                } catch (final ClassNotFoundException e) {
 +                    return false;
 +                }
 +            }
diff --git a/patches/api/WitchConsumePotionEvent.patch b/patches/api/WitchConsumePotionEvent.patch
index af55e97397..a008077315 100644
--- a/patches/api/WitchConsumePotionEvent.patch
+++ b/patches/api/WitchConsumePotionEvent.patch
@@ -73,6 +73,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +        this.cancelled = cancel;
 +    }
 +
++    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
diff --git a/patches/api/added-PlayerNameEntityEvent.patch b/patches/api/added-PlayerNameEntityEvent.patch
index 7619e3089b..ebfdf8acd3 100644
--- a/patches/api/added-PlayerNameEntityEvent.patch
+++ b/patches/api/added-PlayerNameEntityEvent.patch
@@ -19,24 +19,25 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import org.bukkit.event.HandlerList;
 +import org.bukkit.event.player.PlayerEvent;
 +import org.jetbrains.annotations.ApiStatus;
-+import org.jetbrains.annotations.NotNull;
-+import org.jetbrains.annotations.Nullable;
++import org.jspecify.annotations.NullMarked;
++import org.jspecify.annotations.Nullable;
 +
 +/**
 + * Called when the player is attempting to rename a mob
 + */
++@NullMarked
 +public class PlayerNameEntityEvent extends PlayerEvent implements Cancellable {
 +
 +    private static final HandlerList HANDLER_LIST = new HandlerList();
 +
 +    private LivingEntity entity;
-+    private Component name;
++    private @Nullable Component name;
 +    private boolean persistent;
 +
 +    private boolean cancelled;
 +
 +    @ApiStatus.Internal
-+    public PlayerNameEntityEvent(@NotNull Player player, @NotNull LivingEntity entity, @NotNull Component name, boolean persistent) {
++    public PlayerNameEntityEvent(final Player player, final LivingEntity entity, final Component name, final boolean persistent) {
 +        super(player);
 +        this.entity = entity;
 +        this.name = name;
@@ -48,8 +49,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return the name
 +     */
-+    @Nullable
-+    public Component getName() {
++    public @Nullable Component getName() {
 +        return this.name;
 +    }
 +
@@ -58,7 +58,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @param name the name
 +     */
-+    public void setName(@Nullable Component name) {
++    public void setName(final @Nullable Component name) {
 +        this.name = name;
 +    }
 +
@@ -67,7 +67,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @return the entity
 +     */
-+    @NotNull
 +    public LivingEntity getEntity() {
 +        return this.entity;
 +    }
@@ -77,7 +76,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @param entity the entity
 +     */
-+    public void setEntity(@NotNull LivingEntity entity) {
++    public void setEntity(final LivingEntity entity) {
 +        this.entity = entity;
 +    }
 +
@@ -95,7 +94,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +     *
 +     * @param persistent persistent
 +     */
-+    public void setPersistent(boolean persistent) {
++    public void setPersistent(final boolean persistent) {
 +        this.persistent = persistent;
 +    }
 +
@@ -105,17 +104,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +    }
 +
 +    @Override
-+    public void setCancelled(boolean cancel) {
++    public void setCancelled(final boolean cancel) {
 +        this.cancelled = cancel;
 +    }
 +
-+    @NotNull
 +    @Override
 +    public HandlerList getHandlers() {
 +        return HANDLER_LIST;
 +    }
 +
-+    @NotNull
 +    public static HandlerList getHandlerList() {
 +        return HANDLER_LIST;
 +    }
diff --git a/patches/server/Implement-Mob-Goal-API.patch b/patches/server/Implement-Mob-Goal-API.patch
index cc8002fe86..444378f3b8 100644
--- a/patches/server/Implement-Mob-Goal-API.patch
+++ b/patches/server/Implement-Mob-Goal-API.patch
@@ -476,7 +476,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
 +import net.minecraft.world.entity.ai.goal.WrappedGoal;
 +import org.bukkit.craftbukkit.entity.CraftMob;
 +import org.bukkit.entity.Mob;
++import org.jspecify.annotations.NullMarked;
 +
++@NullMarked
 +public class PaperMobGoals implements MobGoals {
 +
 +    @Override