--- a/net/minecraft/world/entity/monster/piglin/PiglinAi.java
+++ b/net/minecraft/world/entity/monster/piglin/PiglinAi.java
@@ -4,7 +4,9 @@
 import com.google.common.collect.ImmutableSet;
 import com.mojang.datafixers.util.Pair;
 import java.util.Collections;
+import java.util.Iterator;
 import java.util.List;
+import java.util.Objects;
 import java.util.Optional;
 import net.minecraft.server.level.ServerLevel;
 import net.minecraft.sounds.SoundEvent;
@@ -52,7 +54,6 @@
 import net.minecraft.world.entity.ai.behavior.StopBeingAngryIfTargetDead;
 import net.minecraft.world.entity.ai.behavior.TriggerGate;
 import net.minecraft.world.entity.ai.behavior.declarative.BehaviorBuilder;
-import net.minecraft.world.entity.ai.behavior.declarative.Trigger;
 import net.minecraft.world.entity.ai.memory.MemoryModuleType;
 import net.minecraft.world.entity.ai.sensing.Sensor;
 import net.minecraft.world.entity.ai.util.LandRandomPos;
@@ -72,8 +73,16 @@
 import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets;
 import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
 import net.minecraft.world.phys.Vec3;
+// CraftBukkit start
+import java.util.stream.Collectors;
+import org.bukkit.craftbukkit.event.CraftEventFactory;
+import org.bukkit.craftbukkit.inventory.CraftItemStack;
+import org.bukkit.event.entity.EntityRemoveEvent;
+import org.bukkit.event.entity.PiglinBarterEvent;
+// CraftBukkit end
 
 public class PiglinAi {
+
     public static final int REPELLENT_DETECTION_RANGE_HORIZONTAL = 8;
     public static final int REPELLENT_DETECTION_RANGE_VERTICAL = 4;
     public static final Item BARTERING_ITEM = Items.GOLD_INGOT;
@@ -111,14 +120,16 @@
     private static final float SPEED_MULTIPLIER_WHEN_DANCING = 0.6F;
     private static final float SPEED_MULTIPLIER_WHEN_IDLING = 0.6F;
 
+    public PiglinAi() {}
+
     protected static Brain<?> makeBrain(Piglin piglin, Brain<Piglin> brain) {
-        initCoreActivity(brain);
-        initIdleActivity(brain);
-        initAdmireItemActivity(brain);
-        initFightActivity(piglin, brain);
-        initCelebrateActivity(brain);
-        initRetreatActivity(brain);
-        initRideHoglinActivity(brain);
+        PiglinAi.initCoreActivity(brain);
+        PiglinAi.initIdleActivity(brain);
+        PiglinAi.initAdmireItemActivity(brain);
+        PiglinAi.initFightActivity(piglin, brain);
+        PiglinAi.initCelebrateActivity(brain);
+        PiglinAi.initRetreatActivity(brain);
+        PiglinAi.initRideHoglinActivity(brain);
         brain.setCoreActivities(ImmutableSet.of(Activity.CORE));
         brain.setDefaultActivity(Activity.IDLE);
         brain.useDefaultActivity();
@@ -126,159 +137,56 @@
     }
 
     protected static void initMemories(Piglin piglin, RandomSource random) {
-        int i = TIME_BETWEEN_HUNTS.sample(random);
-        piglin.getBrain().setMemoryWithExpiry(MemoryModuleType.HUNTED_RECENTLY, true, (long)i);
+        int i = PiglinAi.TIME_BETWEEN_HUNTS.sample(random);
+
+        piglin.getBrain().setMemoryWithExpiry(MemoryModuleType.HUNTED_RECENTLY, true, (long) i);
     }
 
     private static void initCoreActivity(Brain<Piglin> piglin) {
-        piglin.addActivity(
-            Activity.CORE,
-            0,
-            ImmutableList.of(
-                new LookAtTargetSink(45, 90),
-                new MoveToTargetSink(),
-                InteractWithDoor.create(),
-                babyAvoidNemesis(),
-                avoidZombified(),
-                StopHoldingItemIfNoLongerAdmiring.create(),
-                StartAdmiringItemIfSeen.create(119),
-                StartCelebratingIfTargetDead.create(300, PiglinAi::wantsToDance),
-                StopBeingAngryIfTargetDead.create()
-            )
-        );
+        piglin.addActivity(Activity.CORE, 0, ImmutableList.of(new LookAtTargetSink(45, 90), new MoveToTargetSink(), InteractWithDoor.create(), PiglinAi.babyAvoidNemesis(), PiglinAi.avoidZombified(), StopHoldingItemIfNoLongerAdmiring.create(), StartAdmiringItemIfSeen.create(119), StartCelebratingIfTargetDead.create(300, PiglinAi::wantsToDance), StopBeingAngryIfTargetDead.create()));
     }
 
     private static void initIdleActivity(Brain<Piglin> piglin) {
-        piglin.addActivity(
-            Activity.IDLE,
-            10,
-            ImmutableList.of(
-                SetEntityLookTarget.create(PiglinAi::isPlayerHoldingLovedItem, 14.0F),
-                StartAttacking.<Piglin>create(AbstractPiglin::isAdult, PiglinAi::findNearestValidAttackTarget),
-                BehaviorBuilder.triggerIf(Piglin::canHunt, StartHuntingHoglin.create()),
-                avoidRepellent(),
-                babySometimesRideBabyHoglin(),
-                createIdleLookBehaviors(),
-                createIdleMovementBehaviors(),
-                SetLookAndInteract.create(EntityType.PLAYER, 4)
-            )
-        );
+        piglin.addActivity(Activity.IDLE, 10, ImmutableList.of(SetEntityLookTarget.create(PiglinAi::isPlayerHoldingLovedItem, 14.0F), StartAttacking.create(AbstractPiglin::isAdult, PiglinAi::findNearestValidAttackTarget), BehaviorBuilder.triggerIf(Piglin::canHunt, StartHuntingHoglin.create()), PiglinAi.avoidRepellent(), PiglinAi.babySometimesRideBabyHoglin(), PiglinAi.createIdleLookBehaviors(), PiglinAi.createIdleMovementBehaviors(), SetLookAndInteract.create(EntityType.PLAYER, 4)));
     }
 
     private static void initFightActivity(Piglin piglin, Brain<Piglin> brain) {
-        brain.addActivityAndRemoveMemoryWhenStopped(
-            Activity.FIGHT,
-            10,
-            ImmutableList.of(
-                StopAttackingIfTargetInvalid.create(target -> !isNearestValidAttackTarget(piglin, target)),
-                BehaviorBuilder.triggerIf(PiglinAi::hasCrossbow, BackUpIfTooClose.create(5, 0.75F)),
-                SetWalkTargetFromAttackTargetIfTargetOutOfReach.create(1.0F),
-                MeleeAttack.create(20),
-                new CrossbowAttack(),
-                RememberIfHoglinWasKilled.create(),
-                EraseMemoryIf.create(PiglinAi::isNearZombified, MemoryModuleType.ATTACK_TARGET)
-            ),
-            MemoryModuleType.ATTACK_TARGET
-        );
+        brain.addActivityAndRemoveMemoryWhenStopped(Activity.FIGHT, 10, ImmutableList.of(StopAttackingIfTargetInvalid.create((entityliving) -> {
+            return !PiglinAi.isNearestValidAttackTarget(piglin, entityliving);
+        }), BehaviorBuilder.triggerIf(PiglinAi::hasCrossbow, BackUpIfTooClose.create(5, 0.75F)), SetWalkTargetFromAttackTargetIfTargetOutOfReach.create(1.0F), MeleeAttack.create(20), new CrossbowAttack<>(), RememberIfHoglinWasKilled.create(), EraseMemoryIf.create(PiglinAi::isNearZombified, MemoryModuleType.ATTACK_TARGET)), MemoryModuleType.ATTACK_TARGET);
     }
 
     private static void initCelebrateActivity(Brain<Piglin> brain) {
-        brain.addActivityAndRemoveMemoryWhenStopped(
-            Activity.CELEBRATE,
-            10,
-            ImmutableList.of(
-                avoidRepellent(),
-                SetEntityLookTarget.create(PiglinAi::isPlayerHoldingLovedItem, 14.0F),
-                StartAttacking.<Piglin>create(AbstractPiglin::isAdult, PiglinAi::findNearestValidAttackTarget),
-                BehaviorBuilder.triggerIf(piglin -> !piglin.isDancing(), GoToTargetLocation.create(MemoryModuleType.CELEBRATE_LOCATION, 2, 1.0F)),
-                BehaviorBuilder.triggerIf(Piglin::isDancing, GoToTargetLocation.create(MemoryModuleType.CELEBRATE_LOCATION, 4, 0.6F)),
-                new RunOne<LivingEntity>(
-                    ImmutableList.of(
-                        Pair.of(SetEntityLookTarget.create(EntityType.PIGLIN, 8.0F), 1),
-                        Pair.of(RandomStroll.stroll(0.6F, 2, 1), 1),
-                        Pair.of(new DoNothing(10, 20), 1)
-                    )
-                )
-            ),
-            MemoryModuleType.CELEBRATE_LOCATION
-        );
+        brain.addActivityAndRemoveMemoryWhenStopped(Activity.CELEBRATE, 10, ImmutableList.of(PiglinAi.avoidRepellent(), SetEntityLookTarget.create(PiglinAi::isPlayerHoldingLovedItem, 14.0F), StartAttacking.create(AbstractPiglin::isAdult, PiglinAi::findNearestValidAttackTarget), BehaviorBuilder.triggerIf((entitypiglin) -> {
+            return !entitypiglin.isDancing();
+        }, GoToTargetLocation.create(MemoryModuleType.CELEBRATE_LOCATION, 2, 1.0F)), BehaviorBuilder.triggerIf(Piglin::isDancing, GoToTargetLocation.create(MemoryModuleType.CELEBRATE_LOCATION, 4, 0.6F)), new RunOne<>(ImmutableList.of(Pair.of(SetEntityLookTarget.create(EntityType.PIGLIN, 8.0F), 1), Pair.of(RandomStroll.stroll(0.6F, 2, 1), 1), Pair.of(new DoNothing(10, 20), 1)))), MemoryModuleType.CELEBRATE_LOCATION);
     }
 
     private static void initAdmireItemActivity(Brain<Piglin> brain) {
-        brain.addActivityAndRemoveMemoryWhenStopped(
-            Activity.ADMIRE_ITEM,
-            10,
-            ImmutableList.of(
-                GoToWantedItem.create(PiglinAi::isNotHoldingLovedItemInOffHand, 1.0F, true, 9),
-                StopAdmiringIfItemTooFarAway.create(9),
-                StopAdmiringIfTiredOfTryingToReachItem.create(200, 200)
-            ),
-            MemoryModuleType.ADMIRING_ITEM
-        );
+        brain.addActivityAndRemoveMemoryWhenStopped(Activity.ADMIRE_ITEM, 10, ImmutableList.of(GoToWantedItem.create(PiglinAi::isNotHoldingLovedItemInOffHand, 1.0F, true, 9), StopAdmiringIfItemTooFarAway.create(9), StopAdmiringIfTiredOfTryingToReachItem.create(200, 200)), MemoryModuleType.ADMIRING_ITEM);
     }
 
     private static void initRetreatActivity(Brain<Piglin> brain) {
-        brain.addActivityAndRemoveMemoryWhenStopped(
-            Activity.AVOID,
-            10,
-            ImmutableList.of(
-                SetWalkTargetAwayFrom.entity(MemoryModuleType.AVOID_TARGET, 1.0F, 12, true),
-                createIdleLookBehaviors(),
-                createIdleMovementBehaviors(),
-                EraseMemoryIf.<PathfinderMob>create(PiglinAi::wantsToStopFleeing, MemoryModuleType.AVOID_TARGET)
-            ),
-            MemoryModuleType.AVOID_TARGET
-        );
+        brain.addActivityAndRemoveMemoryWhenStopped(Activity.AVOID, 10, ImmutableList.of(SetWalkTargetAwayFrom.entity(MemoryModuleType.AVOID_TARGET, 1.0F, 12, true), PiglinAi.createIdleLookBehaviors(), PiglinAi.createIdleMovementBehaviors(), EraseMemoryIf.create(PiglinAi::wantsToStopFleeing, MemoryModuleType.AVOID_TARGET)), MemoryModuleType.AVOID_TARGET);
     }
 
     private static void initRideHoglinActivity(Brain<Piglin> brain) {
-        brain.addActivityAndRemoveMemoryWhenStopped(
-            Activity.RIDE,
-            10,
-            ImmutableList.of(
-                Mount.create(0.8F),
-                SetEntityLookTarget.create(PiglinAi::isPlayerHoldingLovedItem, 8.0F),
-                BehaviorBuilder.sequence(
-                    BehaviorBuilder.triggerIf(Entity::isPassenger),
-                    TriggerGate.triggerOneShuffled(
-                        ImmutableList.<Pair<? extends Trigger<? super LivingEntity>, Integer>>builder()
-                            .addAll(createLookBehaviors())
-                            .add(Pair.of(BehaviorBuilder.triggerIf(piglin -> true), 1))
-                            .build()
-                    )
-                ),
-                DismountOrSkipMounting.<LivingEntity>create(8, PiglinAi::wantsToStopRiding)
-            ),
-            MemoryModuleType.RIDE_TARGET
-        );
+        // CraftBukkit - decompile error
+        brain.addActivityAndRemoveMemoryWhenStopped(Activity.RIDE, 10, ImmutableList.of(Mount.create(0.8F), SetEntityLookTarget.create(PiglinAi::isPlayerHoldingLovedItem, 8.0F), BehaviorBuilder.sequence(BehaviorBuilder.triggerIf(Entity::isPassenger), TriggerGate.triggerOneShuffled(ImmutableList.<Pair<? extends net.minecraft.world.entity.ai.behavior.declarative.Trigger<? super LivingEntity>, Integer>>builder().addAll(PiglinAi.createLookBehaviors()).add(Pair.of(BehaviorBuilder.triggerIf((entitypiglin) -> {
+            return true;
+        }), 1)).build())), DismountOrSkipMounting.create(8, PiglinAi::wantsToStopRiding)), MemoryModuleType.RIDE_TARGET);
     }
 
     private static ImmutableList<Pair<OneShot<LivingEntity>, Integer>> createLookBehaviors() {
-        return ImmutableList.of(
-            Pair.of(SetEntityLookTarget.create(EntityType.PLAYER, 8.0F), 1),
-            Pair.of(SetEntityLookTarget.create(EntityType.PIGLIN, 8.0F), 1),
-            Pair.of(SetEntityLookTarget.create(8.0F), 1)
-        );
+        return ImmutableList.of(Pair.of(SetEntityLookTarget.create(EntityType.PLAYER, 8.0F), 1), Pair.of(SetEntityLookTarget.create(EntityType.PIGLIN, 8.0F), 1), Pair.of(SetEntityLookTarget.create(8.0F), 1));
     }
 
     private static RunOne<LivingEntity> createIdleLookBehaviors() {
-        return new RunOne<>(
-            ImmutableList.<Pair<? extends BehaviorControl<? super LivingEntity>, Integer>>builder()
-                .addAll(createLookBehaviors())
-                .add(Pair.of(new DoNothing(30, 60), 1))
-                .build()
-        );
+        return new RunOne<>(ImmutableList.<Pair<? extends BehaviorControl<? super LivingEntity>, Integer>>builder().addAll(PiglinAi.createLookBehaviors()).add(Pair.of(new DoNothing(30, 60), 1)).build()); // CraftBukkit - decompile error
     }
 
     private static RunOne<Piglin> createIdleMovementBehaviors() {
-        return new RunOne<>(
-            ImmutableList.of(
-                Pair.of(RandomStroll.stroll(0.6F), 2),
-                Pair.of(InteractWith.of(EntityType.PIGLIN, 8, MemoryModuleType.INTERACTION_TARGET, 0.6F, 2), 2),
-                Pair.of(BehaviorBuilder.triggerIf(PiglinAi::doesntSeeAnyPlayerHoldingLovedItem, SetWalkTargetFromLookTarget.create(0.6F, 3)), 2),
-                Pair.of(new DoNothing(30, 60), 1)
-            )
-        );
+        return new RunOne<>(ImmutableList.of(Pair.of(RandomStroll.stroll(0.6F), 2), Pair.of(InteractWith.of(EntityType.PIGLIN, 8, MemoryModuleType.INTERACTION_TARGET, 0.6F, 2), 2), Pair.of(BehaviorBuilder.triggerIf(PiglinAi::doesntSeeAnyPlayerHoldingLovedItem, SetWalkTargetFromLookTarget.create(0.6F, 3)), 2), Pair.of(new DoNothing(30, 60), 1)));
     }
 
     private static BehaviorControl<PathfinderMob> avoidRepellent() {
@@ -286,36 +194,37 @@
     }
 
     private static BehaviorControl<Piglin> babyAvoidNemesis() {
-        return CopyMemoryWithExpiry.create(Piglin::isBaby, MemoryModuleType.NEAREST_VISIBLE_NEMESIS, MemoryModuleType.AVOID_TARGET, BABY_AVOID_NEMESIS_DURATION);
+        return CopyMemoryWithExpiry.create(Piglin::isBaby, MemoryModuleType.NEAREST_VISIBLE_NEMESIS, MemoryModuleType.AVOID_TARGET, PiglinAi.BABY_AVOID_NEMESIS_DURATION);
     }
 
     private static BehaviorControl<Piglin> avoidZombified() {
-        return CopyMemoryWithExpiry.create(
-            PiglinAi::isNearZombified, MemoryModuleType.NEAREST_VISIBLE_ZOMBIFIED, MemoryModuleType.AVOID_TARGET, AVOID_ZOMBIFIED_DURATION
-        );
+        return CopyMemoryWithExpiry.create(PiglinAi::isNearZombified, MemoryModuleType.NEAREST_VISIBLE_ZOMBIFIED, MemoryModuleType.AVOID_TARGET, PiglinAi.AVOID_ZOMBIFIED_DURATION);
     }
 
     protected static void updateActivity(Piglin piglin) {
-        Brain<Piglin> brain = piglin.getBrain();
-        Activity activity = brain.getActiveNonCoreActivity().orElse(null);
-        brain.setActiveActivityToFirstValid(
-            ImmutableList.of(Activity.ADMIRE_ITEM, Activity.FIGHT, Activity.AVOID, Activity.CELEBRATE, Activity.RIDE, Activity.IDLE)
-        );
-        Activity activity2 = brain.getActiveNonCoreActivity().orElse(null);
-        if (activity != activity2) {
-            getSoundForCurrentActivity(piglin).ifPresent(piglin::makeSound);
+        Brain<Piglin> behaviorcontroller = piglin.getBrain();
+        Activity activity = (Activity) behaviorcontroller.getActiveNonCoreActivity().orElse(null); // CraftBukkit - decompile error
+
+        behaviorcontroller.setActiveActivityToFirstValid(ImmutableList.of(Activity.ADMIRE_ITEM, Activity.FIGHT, Activity.AVOID, Activity.CELEBRATE, Activity.RIDE, Activity.IDLE));
+        Activity activity1 = (Activity) behaviorcontroller.getActiveNonCoreActivity().orElse(null); // CraftBukkit - decompile error
+
+        if (activity != activity1) {
+            Optional<SoundEvent> optional = PiglinAi.getSoundForCurrentActivity(piglin); // CraftBukkit - decompile error
+
+            Objects.requireNonNull(piglin);
+            optional.ifPresent(piglin::makeSound);
         }
 
-        piglin.setAggressive(brain.hasMemoryValue(MemoryModuleType.ATTACK_TARGET));
-        if (!brain.hasMemoryValue(MemoryModuleType.RIDE_TARGET) && isBabyRidingBaby(piglin)) {
+        piglin.setAggressive(behaviorcontroller.hasMemoryValue(MemoryModuleType.ATTACK_TARGET));
+        if (!behaviorcontroller.hasMemoryValue(MemoryModuleType.RIDE_TARGET) && PiglinAi.isBabyRidingBaby(piglin)) {
             piglin.stopRiding();
         }
 
-        if (!brain.hasMemoryValue(MemoryModuleType.CELEBRATE_LOCATION)) {
-            brain.eraseMemory(MemoryModuleType.DANCING);
+        if (!behaviorcontroller.hasMemoryValue(MemoryModuleType.CELEBRATE_LOCATION)) {
+            behaviorcontroller.eraseMemory(MemoryModuleType.DANCING);
         }
 
-        piglin.setDancing(brain.hasMemoryValue(MemoryModuleType.DANCING));
+        piglin.setDancing(behaviorcontroller.hasMemoryValue(MemoryModuleType.DANCING));
     }
 
     private static boolean isBabyRidingBaby(Piglin piglin) {
@@ -323,133 +232,168 @@
             return false;
         } else {
             Entity entity = piglin.getVehicle();
-            return entity instanceof Piglin && ((Piglin)entity).isBaby() || entity instanceof Hoglin && ((Hoglin)entity).isBaby();
+
+            return entity instanceof Piglin && ((Piglin) entity).isBaby() || entity instanceof Hoglin && ((Hoglin) entity).isBaby();
         }
     }
 
     protected static void pickUpItem(Piglin piglin, ItemEntity drop) {
-        stopWalking(piglin);
-        ItemStack itemStack;
-        if (drop.getItem().is(Items.GOLD_NUGGET)) {
+        PiglinAi.stopWalking(piglin);
+        ItemStack itemstack;
+
+        // CraftBukkit start
+        // Paper start - EntityPickupItemEvent fixes; fix event firing twice
+        if (drop.getItem().is(Items.GOLD_NUGGET) /* && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPickupItemEvent(piglin, drop, 0, false).isCancelled() */) {
+            if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPickupItemEvent(piglin, drop, 0, false).isCancelled()) return;
+            piglin.onItemPickup(drop); // Paper - moved from Piglin#pickUpItem - call prior to item entity modification
+            // Paper end - EntityPickupItemEvent fixes
             piglin.take(drop, drop.getItem().getCount());
-            itemStack = drop.getItem();
-            drop.discard();
-        } else {
+            itemstack = drop.getItem();
+            drop.discard(EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause
+        } else if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityPickupItemEvent(piglin, drop, drop.getItem().getCount() - 1, false).isCancelled()) {
+            piglin.onItemPickup(drop); // Paper - EntityPickupItemEvent fixes; moved from Piglin#pickUpItem - call prior to item entity modification
             piglin.take(drop, 1);
-            itemStack = removeOneItemFromItemEntity(drop);
+            itemstack = PiglinAi.removeOneItemFromItemEntity(drop);
+        } else {
+            return;
         }
+        // CraftBukkit end
 
-        if (isLovedItem(itemStack)) {
+        if (PiglinAi.isLovedItem(itemstack, piglin)) { // CraftBukkit - Changes to allow for custom payment in bartering
             piglin.getBrain().eraseMemory(MemoryModuleType.TIME_TRYING_TO_REACH_ADMIRE_ITEM);
-            holdInOffhand(piglin, itemStack);
-            admireGoldItem(piglin);
-        } else if (isFood(itemStack) && !hasEatenRecently(piglin)) {
-            eat(piglin);
+            PiglinAi.holdInOffhand(piglin, itemstack);
+            PiglinAi.admireGoldItem(piglin);
+        } else if (PiglinAi.isFood(itemstack) && !PiglinAi.hasEatenRecently(piglin)) {
+            PiglinAi.eat(piglin);
         } else {
-            boolean bl = !piglin.equipItemIfPossible(itemStack).equals(ItemStack.EMPTY);
-            if (!bl) {
-                putInInventory(piglin, itemStack);
+            boolean flag = !piglin.equipItemIfPossible(itemstack, drop).equals(ItemStack.EMPTY); // CraftBukkit
+
+            if (!flag) {
+                PiglinAi.putInInventory(piglin, itemstack);
             }
         }
     }
 
     private static void holdInOffhand(Piglin piglin, ItemStack stack) {
-        if (isHoldingItemInOffHand(piglin)) {
+        if (PiglinAi.isHoldingItemInOffHand(piglin)) {
+            piglin.forceDrops = true; // Paper - Add missing forceDrop toggles
             piglin.spawnAtLocation(piglin.getItemInHand(InteractionHand.OFF_HAND));
+            piglin.forceDrops = false; // Paper - Add missing forceDrop toggles
         }
 
         piglin.holdInOffHand(stack);
     }
 
     private static ItemStack removeOneItemFromItemEntity(ItemEntity stack) {
-        ItemStack itemStack = stack.getItem();
-        ItemStack itemStack2 = itemStack.split(1);
-        if (itemStack.isEmpty()) {
-            stack.discard();
+        ItemStack itemstack = stack.getItem();
+        ItemStack itemstack1 = itemstack.split(1);
+
+        if (itemstack.isEmpty()) {
+            stack.discard(EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause
         } else {
-            stack.setItem(itemStack);
+            stack.setItem(itemstack);
         }
 
-        return itemStack2;
+        return itemstack1;
     }
 
     protected static void stopHoldingOffHandItem(Piglin piglin, boolean barter) {
-        ItemStack itemStack = piglin.getItemInHand(InteractionHand.OFF_HAND);
+        ItemStack itemstack = piglin.getItemInHand(InteractionHand.OFF_HAND);
+
         piglin.setItemInHand(InteractionHand.OFF_HAND, ItemStack.EMPTY);
+        boolean flag1;
+
         if (piglin.isAdult()) {
-            boolean bl = isBarterCurrency(itemStack);
-            if (barter && bl) {
-                throwItems(piglin, getBarterResponseItems(piglin));
-            } else if (!bl) {
-                boolean bl2 = !piglin.equipItemIfPossible(itemStack).isEmpty();
-                if (!bl2) {
-                    putInInventory(piglin, itemStack);
+            flag1 = PiglinAi.isBarterCurrency(itemstack, piglin); // CraftBukkit - Changes to allow custom payment for bartering
+            if (barter && flag1) {
+                // CraftBukkit start
+                PiglinBarterEvent event = CraftEventFactory.callPiglinBarterEvent(piglin, PiglinAi.getBarterResponseItems(piglin), itemstack);
+                if (!event.isCancelled()) {
+                    PiglinAi.throwItems(piglin, event.getOutcome().stream().map(CraftItemStack::asNMSCopy).collect(Collectors.toList()));
+                }
+                // CraftBukkit end
+            } else if (!flag1) {
+                boolean flag2 = !piglin.equipItemIfPossible(itemstack).isEmpty();
+
+                if (!flag2) {
+                    PiglinAi.putInInventory(piglin, itemstack);
                 }
             }
         } else {
-            boolean bl3 = !piglin.equipItemIfPossible(itemStack).isEmpty();
-            if (!bl3) {
-                ItemStack itemStack2 = piglin.getMainHandItem();
-                if (isLovedItem(itemStack2)) {
-                    putInInventory(piglin, itemStack2);
+            flag1 = !piglin.equipItemIfPossible(itemstack).isEmpty();
+            if (!flag1) {
+                ItemStack itemstack1 = piglin.getMainHandItem();
+
+                if (PiglinAi.isLovedItem(itemstack1, piglin)) { // CraftBukkit - Changes to allow for custom payment in bartering
+                    PiglinAi.putInInventory(piglin, itemstack1);
                 } else {
-                    throwItems(piglin, Collections.singletonList(itemStack2));
+                    PiglinAi.throwItems(piglin, Collections.singletonList(itemstack1));
                 }
 
-                piglin.holdInMainHand(itemStack);
+                piglin.holdInMainHand(itemstack);
             }
         }
+
     }
 
     protected static void cancelAdmiring(Piglin piglin) {
-        if (isAdmiringItem(piglin) && !piglin.getOffhandItem().isEmpty()) {
+        if (PiglinAi.isAdmiringItem(piglin) && !piglin.getOffhandItem().isEmpty()) {
+            piglin.forceDrops = true; // Paper - Add missing forceDrop toggles
             piglin.spawnAtLocation(piglin.getOffhandItem());
+            piglin.forceDrops = false; // Paper - Add missing forceDrop toggles
             piglin.setItemInHand(InteractionHand.OFF_HAND, ItemStack.EMPTY);
         }
+
     }
 
     private static void putInInventory(Piglin piglin, ItemStack stack) {
-        ItemStack itemStack = piglin.addToInventory(stack);
-        throwItemsTowardRandomPos(piglin, Collections.singletonList(itemStack));
+        ItemStack itemstack1 = piglin.addToInventory(stack);
+
+        PiglinAi.throwItemsTowardRandomPos(piglin, Collections.singletonList(itemstack1));
     }
 
     private static void throwItems(Piglin piglin, List<ItemStack> items) {
         Optional<Player> optional = piglin.getBrain().getMemory(MemoryModuleType.NEAREST_VISIBLE_PLAYER);
+
         if (optional.isPresent()) {
-            throwItemsTowardPlayer(piglin, optional.get(), items);
+            PiglinAi.throwItemsTowardPlayer(piglin, (Player) optional.get(), items);
         } else {
-            throwItemsTowardRandomPos(piglin, items);
+            PiglinAi.throwItemsTowardRandomPos(piglin, items);
         }
+
     }
 
     private static void throwItemsTowardRandomPos(Piglin piglin, List<ItemStack> items) {
-        throwItemsTowardPos(piglin, items, getRandomNearbyPos(piglin));
+        PiglinAi.throwItemsTowardPos(piglin, items, PiglinAi.getRandomNearbyPos(piglin));
     }
 
     private static void throwItemsTowardPlayer(Piglin piglin, Player player, List<ItemStack> items) {
-        throwItemsTowardPos(piglin, items, player.position());
+        PiglinAi.throwItemsTowardPos(piglin, items, player.position());
     }
 
     private static void throwItemsTowardPos(Piglin piglin, List<ItemStack> items, Vec3 pos) {
         if (!items.isEmpty()) {
             piglin.swing(InteractionHand.OFF_HAND);
+            Iterator iterator = items.iterator();
 
-            for (ItemStack itemStack : items) {
-                BehaviorUtils.throwItem(piglin, itemStack, pos.add(0.0, 1.0, 0.0));
+            while (iterator.hasNext()) {
+                ItemStack itemstack = (ItemStack) iterator.next();
+
+                BehaviorUtils.throwItem(piglin, itemstack, pos.add(0.0D, 1.0D, 0.0D));
             }
         }
+
     }
 
     private static List<ItemStack> getBarterResponseItems(Piglin piglin) {
-        LootTable lootTable = piglin.level().getServer().reloadableRegistries().getLootTable(BuiltInLootTables.PIGLIN_BARTERING);
-        List<ItemStack> list = lootTable.getRandomItems(
-            new LootParams.Builder((ServerLevel)piglin.level()).withParameter(LootContextParams.THIS_ENTITY, piglin).create(LootContextParamSets.PIGLIN_BARTER)
-        );
+        LootTable loottable = piglin.level().getServer().reloadableRegistries().getLootTable(BuiltInLootTables.PIGLIN_BARTERING);
+        List<ItemStack> list = loottable.getRandomItems((new LootParams.Builder((ServerLevel) piglin.level())).withParameter(LootContextParams.THIS_ENTITY, piglin).create(LootContextParamSets.PIGLIN_BARTER));
+
         return list;
     }
 
     private static boolean wantsToDance(LivingEntity piglin, LivingEntity target) {
-        return target.getType() == EntityType.HOGLIN && RandomSource.create(piglin.level().getGameTime()).nextFloat() < 0.1F;
+        return target.getType() != EntityType.HOGLIN ? false : RandomSource.create(piglin.level().getGameTime()).nextFloat() < 0.1F;
     }
 
     protected static boolean wantsToPickup(Piglin piglin, ItemStack stack) {
@@ -457,90 +401,110 @@
             return false;
         } else if (stack.is(ItemTags.PIGLIN_REPELLENTS)) {
             return false;
-        } else if (isAdmiringDisabled(piglin) && piglin.getBrain().hasMemoryValue(MemoryModuleType.ATTACK_TARGET)) {
+        } else if (PiglinAi.isAdmiringDisabled(piglin) && piglin.getBrain().hasMemoryValue(MemoryModuleType.ATTACK_TARGET)) {
             return false;
-        } else if (isBarterCurrency(stack)) {
-            return isNotHoldingLovedItemInOffHand(piglin);
+        } else if (PiglinAi.isBarterCurrency(stack, piglin)) { // CraftBukkit
+            return PiglinAi.isNotHoldingLovedItemInOffHand(piglin);
         } else {
-            boolean bl = piglin.canAddToInventory(stack);
-            if (stack.is(Items.GOLD_NUGGET)) {
-                return bl;
-            } else if (isFood(stack)) {
-                return !hasEatenRecently(piglin) && bl;
-            } else {
-                return !isLovedItem(stack) ? piglin.canReplaceCurrentItem(stack) : isNotHoldingLovedItemInOffHand(piglin) && bl;
-            }
+            boolean flag = piglin.canAddToInventory(stack);
+
+            return stack.is(Items.GOLD_NUGGET) ? flag : (PiglinAi.isFood(stack) ? !PiglinAi.hasEatenRecently(piglin) && flag : (!PiglinAi.isLovedItem(stack, piglin) ? piglin.canReplaceCurrentItem(stack) : PiglinAi.isNotHoldingLovedItemInOffHand(piglin) && flag)); // Paper - upstream missed isLovedItem check
         }
     }
 
+    // CraftBukkit start - Added method to allow checking for custom payment items
+    protected static boolean isLovedItem(ItemStack itemstack, Piglin piglin) {
+        return PiglinAi.isLovedItem(itemstack) || (piglin.interestItems.contains(itemstack.getItem()) || piglin.allowedBarterItems.contains(itemstack.getItem()));
+    }
+    // CraftBukkit end
+
     protected static boolean isLovedItem(ItemStack stack) {
         return stack.is(ItemTags.PIGLIN_LOVED);
     }
 
     private static boolean wantsToStopRiding(Piglin piglin, Entity ridden) {
-        return ridden instanceof Mob mob
-            && (!mob.isBaby() || !mob.isAlive() || wasHurtRecently(piglin) || wasHurtRecently(mob) || mob instanceof Piglin && mob.getVehicle() == null);
+        if (!(ridden instanceof Mob entityinsentient)) {
+            return false;
+        } else {
+            return !entityinsentient.isBaby() || !entityinsentient.isAlive() || PiglinAi.wasHurtRecently(piglin) || PiglinAi.wasHurtRecently(entityinsentient) || entityinsentient instanceof Piglin && entityinsentient.getVehicle() == null;
+        }
     }
 
     private static boolean isNearestValidAttackTarget(Piglin piglin, LivingEntity target) {
-        return findNearestValidAttackTarget(piglin).filter(preferredTarget -> preferredTarget == target).isPresent();
+        return PiglinAi.findNearestValidAttackTarget(piglin).filter((entityliving1) -> {
+            return entityliving1 == target;
+        }).isPresent();
     }
 
     private static boolean isNearZombified(Piglin piglin) {
-        Brain<Piglin> brain = piglin.getBrain();
-        if (brain.hasMemoryValue(MemoryModuleType.NEAREST_VISIBLE_ZOMBIFIED)) {
-            LivingEntity livingEntity = brain.getMemory(MemoryModuleType.NEAREST_VISIBLE_ZOMBIFIED).get();
-            return piglin.closerThan(livingEntity, 6.0);
+        Brain<Piglin> behaviorcontroller = piglin.getBrain();
+
+        if (behaviorcontroller.hasMemoryValue(MemoryModuleType.NEAREST_VISIBLE_ZOMBIFIED)) {
+            LivingEntity entityliving = (LivingEntity) behaviorcontroller.getMemory(MemoryModuleType.NEAREST_VISIBLE_ZOMBIFIED).get();
+
+            return piglin.closerThan(entityliving, 6.0D);
         } else {
             return false;
         }
     }
 
     private static Optional<? extends LivingEntity> findNearestValidAttackTarget(Piglin piglin) {
-        Brain<Piglin> brain = piglin.getBrain();
-        if (isNearZombified(piglin)) {
+        Brain<Piglin> behaviorcontroller = piglin.getBrain();
+
+        if (PiglinAi.isNearZombified(piglin)) {
             return Optional.empty();
         } else {
             Optional<LivingEntity> optional = BehaviorUtils.getLivingEntityFromUUIDMemory(piglin, MemoryModuleType.ANGRY_AT);
-            if (optional.isPresent() && Sensor.isEntityAttackableIgnoringLineOfSight(piglin, optional.get())) {
+
+            if (optional.isPresent() && Sensor.isEntityAttackableIgnoringLineOfSight(piglin, (LivingEntity) optional.get())) {
                 return optional;
             } else {
-                if (brain.hasMemoryValue(MemoryModuleType.UNIVERSAL_ANGER)) {
-                    Optional<Player> optional2 = brain.getMemory(MemoryModuleType.NEAREST_VISIBLE_ATTACKABLE_PLAYER);
-                    if (optional2.isPresent()) {
-                        return optional2;
+                Optional optional1;
+
+                if (behaviorcontroller.hasMemoryValue(MemoryModuleType.UNIVERSAL_ANGER)) {
+                    optional1 = behaviorcontroller.getMemory(MemoryModuleType.NEAREST_VISIBLE_ATTACKABLE_PLAYER);
+                    if (optional1.isPresent()) {
+                        return optional1;
                     }
                 }
 
-                Optional<Mob> optional3 = brain.getMemory(MemoryModuleType.NEAREST_VISIBLE_NEMESIS);
-                if (optional3.isPresent()) {
-                    return optional3;
+                optional1 = behaviorcontroller.getMemory(MemoryModuleType.NEAREST_VISIBLE_NEMESIS);
+                if (optional1.isPresent()) {
+                    return optional1;
                 } else {
-                    Optional<Player> optional4 = brain.getMemory(MemoryModuleType.NEAREST_TARGETABLE_PLAYER_NOT_WEARING_GOLD);
-                    return optional4.isPresent() && Sensor.isEntityAttackable(piglin, optional4.get()) ? optional4 : Optional.empty();
+                    Optional<Player> optional2 = behaviorcontroller.getMemory(MemoryModuleType.NEAREST_TARGETABLE_PLAYER_NOT_WEARING_GOLD);
+
+                    return optional2.isPresent() && Sensor.isEntityAttackable(piglin, (LivingEntity) optional2.get()) ? optional2 : Optional.empty();
                 }
             }
         }
     }
 
     public static void angerNearbyPiglins(Player player, boolean blockOpen) {
-        List<Piglin> list = player.level().getEntitiesOfClass(Piglin.class, player.getBoundingBox().inflate(16.0));
-        list.stream().filter(PiglinAi::isIdle).filter(piglin -> !blockOpen || BehaviorUtils.canSee(piglin, player)).forEach(piglin -> {
-            if (piglin.level().getGameRules().getBoolean(GameRules.RULE_UNIVERSAL_ANGER)) {
-                setAngerTargetToNearestTargetablePlayerIfFound(piglin, player);
+        if (!player.level().paperConfig().entities.behavior.piglinsGuardChests) return; // Paper - Config option for Piglins guarding chests
+        List<Piglin> list = player.level().getEntitiesOfClass(Piglin.class, player.getBoundingBox().inflate(16.0D));
+
+        list.stream().filter(PiglinAi::isIdle).filter((entitypiglin) -> {
+            return !blockOpen || BehaviorUtils.canSee(entitypiglin, player);
+        }).forEach((entitypiglin) -> {
+            if (entitypiglin.level().getGameRules().getBoolean(GameRules.RULE_UNIVERSAL_ANGER)) {
+                PiglinAi.setAngerTargetToNearestTargetablePlayerIfFound(entitypiglin, player);
             } else {
-                setAngerTarget(piglin, player);
+                PiglinAi.setAngerTarget(entitypiglin, player);
             }
+
         });
     }
 
     public static InteractionResult mobInteract(Piglin piglin, Player player, InteractionHand hand) {
-        ItemStack itemStack = player.getItemInHand(hand);
-        if (canAdmire(piglin, itemStack)) {
-            ItemStack itemStack2 = itemStack.split(1);
-            holdInOffhand(piglin, itemStack2);
-            admireGoldItem(piglin);
-            stopWalking(piglin);
+        ItemStack itemstack = player.getItemInHand(hand);
+
+        if (PiglinAi.canAdmire(piglin, itemstack)) {
+            ItemStack itemstack1 = itemstack.split(1);
+
+            PiglinAi.holdInOffhand(piglin, itemstack1);
+            PiglinAi.admireGoldItem(piglin);
+            PiglinAi.stopWalking(piglin);
             return InteractionResult.CONSUME;
         } else {
             return InteractionResult.PASS;
@@ -548,38 +512,41 @@
     }
 
     protected static boolean canAdmire(Piglin piglin, ItemStack nearbyItems) {
-        return !isAdmiringDisabled(piglin) && !isAdmiringItem(piglin) && piglin.isAdult() && isBarterCurrency(nearbyItems);
+        return !PiglinAi.isAdmiringDisabled(piglin) && !PiglinAi.isAdmiringItem(piglin) && piglin.isAdult() && PiglinAi.isBarterCurrency(nearbyItems, piglin); // CraftBukkit
     }
 
     protected static void wasHurtBy(Piglin piglin, LivingEntity attacker) {
         if (!(attacker instanceof Piglin)) {
-            if (isHoldingItemInOffHand(piglin)) {
-                stopHoldingOffHandItem(piglin, false);
+            if (PiglinAi.isHoldingItemInOffHand(piglin)) {
+                PiglinAi.stopHoldingOffHandItem(piglin, false);
             }
 
-            Brain<Piglin> brain = piglin.getBrain();
-            brain.eraseMemory(MemoryModuleType.CELEBRATE_LOCATION);
-            brain.eraseMemory(MemoryModuleType.DANCING);
-            brain.eraseMemory(MemoryModuleType.ADMIRING_ITEM);
+            Brain<Piglin> behaviorcontroller = piglin.getBrain();
+
+            behaviorcontroller.eraseMemory(MemoryModuleType.CELEBRATE_LOCATION);
+            behaviorcontroller.eraseMemory(MemoryModuleType.DANCING);
+            behaviorcontroller.eraseMemory(MemoryModuleType.ADMIRING_ITEM);
             if (attacker instanceof Player) {
-                brain.setMemoryWithExpiry(MemoryModuleType.ADMIRING_DISABLED, true, 400L);
+                behaviorcontroller.setMemoryWithExpiry(MemoryModuleType.ADMIRING_DISABLED, true, 400L);
             }
 
-            getAvoidTarget(piglin).ifPresent(avoiding -> {
-                if (avoiding.getType() != attacker.getType()) {
-                    brain.eraseMemory(MemoryModuleType.AVOID_TARGET);
+            PiglinAi.getAvoidTarget(piglin).ifPresent((entityliving1) -> {
+                if (entityliving1.getType() != attacker.getType()) {
+                    behaviorcontroller.eraseMemory(MemoryModuleType.AVOID_TARGET);
                 }
+
             });
             if (piglin.isBaby()) {
-                brain.setMemoryWithExpiry(MemoryModuleType.AVOID_TARGET, attacker, 100L);
+                behaviorcontroller.setMemoryWithExpiry(MemoryModuleType.AVOID_TARGET, attacker, 100L);
                 if (Sensor.isEntityAttackableIgnoringLineOfSight(piglin, attacker)) {
-                    broadcastAngerTarget(piglin, attacker);
+                    PiglinAi.broadcastAngerTarget(piglin, attacker);
                 }
-            } else if (attacker.getType() == EntityType.HOGLIN && hoglinsOutnumberPiglins(piglin)) {
-                setAvoidTargetAndDontHuntForAWhile(piglin, attacker);
-                broadcastRetreat(piglin, attacker);
+
+            } else if (attacker.getType() == EntityType.HOGLIN && PiglinAi.hoglinsOutnumberPiglins(piglin)) {
+                PiglinAi.setAvoidTargetAndDontHuntForAWhile(piglin, attacker);
+                PiglinAi.broadcastRetreat(piglin, attacker);
             } else {
-                maybeRetaliate(piglin, attacker);
+                PiglinAi.maybeRetaliate(piglin, attacker);
             }
         }
     }
@@ -587,63 +554,61 @@
     protected static void maybeRetaliate(AbstractPiglin piglin, LivingEntity target) {
         if (!piglin.getBrain().isActive(Activity.AVOID)) {
             if (Sensor.isEntityAttackableIgnoringLineOfSight(piglin, target)) {
-                if (!BehaviorUtils.isOtherTargetMuchFurtherAwayThanCurrentAttackTarget(piglin, target, 4.0)) {
+                if (!BehaviorUtils.isOtherTargetMuchFurtherAwayThanCurrentAttackTarget(piglin, target, 4.0D)) {
                     if (target.getType() == EntityType.PLAYER && piglin.level().getGameRules().getBoolean(GameRules.RULE_UNIVERSAL_ANGER)) {
-                        setAngerTargetToNearestTargetablePlayerIfFound(piglin, target);
-                        broadcastUniversalAnger(piglin);
+                        PiglinAi.setAngerTargetToNearestTargetablePlayerIfFound(piglin, target);
+                        PiglinAi.broadcastUniversalAnger(piglin);
                     } else {
-                        setAngerTarget(piglin, target);
-                        broadcastAngerTarget(piglin, target);
+                        PiglinAi.setAngerTarget(piglin, target);
+                        PiglinAi.broadcastAngerTarget(piglin, target);
                     }
+
                 }
             }
         }
     }
 
     public static Optional<SoundEvent> getSoundForCurrentActivity(Piglin piglin) {
-        return piglin.getBrain().getActiveNonCoreActivity().map(activity -> getSoundForActivity(piglin, activity));
+        return piglin.getBrain().getActiveNonCoreActivity().map((activity) -> {
+            return PiglinAi.getSoundForActivity(piglin, activity);
+        });
     }
 
     private static SoundEvent getSoundForActivity(Piglin piglin, Activity activity) {
-        if (activity == Activity.FIGHT) {
-            return SoundEvents.PIGLIN_ANGRY;
-        } else if (piglin.isConverting()) {
-            return SoundEvents.PIGLIN_RETREAT;
-        } else if (activity == Activity.AVOID && isNearAvoidTarget(piglin)) {
-            return SoundEvents.PIGLIN_RETREAT;
-        } else if (activity == Activity.ADMIRE_ITEM) {
-            return SoundEvents.PIGLIN_ADMIRING_ITEM;
-        } else if (activity == Activity.CELEBRATE) {
-            return SoundEvents.PIGLIN_CELEBRATE;
-        } else if (seesPlayerHoldingLovedItem(piglin)) {
-            return SoundEvents.PIGLIN_JEALOUS;
-        } else {
-            return isNearRepellent(piglin) ? SoundEvents.PIGLIN_RETREAT : SoundEvents.PIGLIN_AMBIENT;
-        }
+        return activity == Activity.FIGHT ? SoundEvents.PIGLIN_ANGRY : (piglin.isConverting() ? SoundEvents.PIGLIN_RETREAT : (activity == Activity.AVOID && PiglinAi.isNearAvoidTarget(piglin) ? SoundEvents.PIGLIN_RETREAT : (activity == Activity.ADMIRE_ITEM ? SoundEvents.PIGLIN_ADMIRING_ITEM : (activity == Activity.CELEBRATE ? SoundEvents.PIGLIN_CELEBRATE : (PiglinAi.seesPlayerHoldingLovedItem(piglin) ? SoundEvents.PIGLIN_JEALOUS : (PiglinAi.isNearRepellent(piglin) ? SoundEvents.PIGLIN_RETREAT : SoundEvents.PIGLIN_AMBIENT))))));
     }
 
     private static boolean isNearAvoidTarget(Piglin piglin) {
-        Brain<Piglin> brain = piglin.getBrain();
-        return brain.hasMemoryValue(MemoryModuleType.AVOID_TARGET) && brain.getMemory(MemoryModuleType.AVOID_TARGET).get().closerThan(piglin, 12.0);
+        Brain<Piglin> behaviorcontroller = piglin.getBrain();
+
+        return !behaviorcontroller.hasMemoryValue(MemoryModuleType.AVOID_TARGET) ? false : ((LivingEntity) behaviorcontroller.getMemory(MemoryModuleType.AVOID_TARGET).get()).closerThan(piglin, 12.0D);
     }
 
     protected static List<AbstractPiglin> getVisibleAdultPiglins(Piglin piglin) {
-        return piglin.getBrain().getMemory(MemoryModuleType.NEAREST_VISIBLE_ADULT_PIGLINS).orElse(ImmutableList.of());
+        return (List) piglin.getBrain().getMemory(MemoryModuleType.NEAREST_VISIBLE_ADULT_PIGLINS).orElse(ImmutableList.of());
     }
 
     private static List<AbstractPiglin> getAdultPiglins(AbstractPiglin piglin) {
-        return piglin.getBrain().getMemory(MemoryModuleType.NEARBY_ADULT_PIGLINS).orElse(ImmutableList.of());
+        return (List) piglin.getBrain().getMemory(MemoryModuleType.NEARBY_ADULT_PIGLINS).orElse(ImmutableList.of());
     }
 
     public static boolean isWearingGold(LivingEntity entity) {
-        for (ItemStack itemStack : entity.getArmorAndBodyArmorSlots()) {
-            Item item = itemStack.getItem();
-            if (item instanceof ArmorItem && ((ArmorItem)item).getMaterial().is(ArmorMaterials.GOLD)) {
-                return true;
+        Iterable<ItemStack> iterable = entity.getArmorAndBodyArmorSlots();
+        Iterator iterator = iterable.iterator();
+
+        Item item;
+
+        do {
+            if (!iterator.hasNext()) {
+                return false;
             }
-        }
 
-        return false;
+            ItemStack itemstack = (ItemStack) iterator.next();
+
+            item = itemstack.getItem();
+        } while (!(item instanceof ArmorItem) || !((ArmorItem) item).getMaterial().is(ArmorMaterials.GOLD));
+
+        return true;
     }
 
     private static void stopWalking(Piglin piglin) {
@@ -652,26 +617,27 @@
     }
 
     private static BehaviorControl<LivingEntity> babySometimesRideBabyHoglin() {
-        SetEntityLookTargetSometimes.Ticker ticker = new SetEntityLookTargetSometimes.Ticker(RIDE_START_INTERVAL);
-        return CopyMemoryWithExpiry.create(
-            entity -> entity.isBaby() && ticker.tickDownAndCheck(entity.level().random),
-            MemoryModuleType.NEAREST_VISIBLE_BABY_HOGLIN,
-            MemoryModuleType.RIDE_TARGET,
-            RIDE_DURATION
-        );
+        SetEntityLookTargetSometimes.Ticker setentitylooktargetsometimes_a = new SetEntityLookTargetSometimes.Ticker(PiglinAi.RIDE_START_INTERVAL);
+
+        return CopyMemoryWithExpiry.create((entityliving) -> {
+            return entityliving.isBaby() && setentitylooktargetsometimes_a.tickDownAndCheck(entityliving.level().random);
+        }, MemoryModuleType.NEAREST_VISIBLE_BABY_HOGLIN, MemoryModuleType.RIDE_TARGET, PiglinAi.RIDE_DURATION);
     }
 
     protected static void broadcastAngerTarget(AbstractPiglin piglin, LivingEntity target) {
-        getAdultPiglins(piglin).forEach(nearbyPiglin -> {
-            if (target.getType() != EntityType.HOGLIN || nearbyPiglin.canHunt() && ((Hoglin)target).canBeHunted()) {
-                setAngerTargetIfCloserThanCurrent(nearbyPiglin, target);
+        PiglinAi.getAdultPiglins(piglin).forEach((entitypiglinabstract1) -> {
+            if (target.getType() != EntityType.HOGLIN || entitypiglinabstract1.canHunt() && ((Hoglin) target).canBeHunted()) {
+                PiglinAi.setAngerTargetIfCloserThanCurrent(entitypiglinabstract1, target);
             }
         });
     }
 
     protected static void broadcastUniversalAnger(AbstractPiglin piglin) {
-        getAdultPiglins(piglin)
-            .forEach(nearbyPiglin -> getNearestVisibleTargetablePlayer(nearbyPiglin).ifPresent(player -> setAngerTarget(nearbyPiglin, player)));
+        PiglinAi.getAdultPiglins(piglin).forEach((entitypiglinabstract1) -> {
+            PiglinAi.getNearestVisibleTargetablePlayer(entitypiglinabstract1).ifPresent((entityhuman) -> {
+                PiglinAi.setAngerTarget(entitypiglinabstract1, entityhuman);
+            });
+        });
     }
 
     protected static void setAngerTarget(AbstractPiglin piglin, LivingEntity target) {
@@ -679,29 +645,33 @@
             piglin.getBrain().eraseMemory(MemoryModuleType.CANT_REACH_WALK_TARGET_SINCE);
             piglin.getBrain().setMemoryWithExpiry(MemoryModuleType.ANGRY_AT, target.getUUID(), 600L);
             if (target.getType() == EntityType.HOGLIN && piglin.canHunt()) {
-                dontKillAnyMoreHoglinsForAWhile(piglin);
+                PiglinAi.dontKillAnyMoreHoglinsForAWhile(piglin);
             }
 
             if (target.getType() == EntityType.PLAYER && piglin.level().getGameRules().getBoolean(GameRules.RULE_UNIVERSAL_ANGER)) {
                 piglin.getBrain().setMemoryWithExpiry(MemoryModuleType.UNIVERSAL_ANGER, true, 600L);
             }
+
         }
     }
 
     private static void setAngerTargetToNearestTargetablePlayerIfFound(AbstractPiglin piglin, LivingEntity player) {
-        Optional<Player> optional = getNearestVisibleTargetablePlayer(piglin);
+        Optional<Player> optional = PiglinAi.getNearestVisibleTargetablePlayer(piglin);
+
         if (optional.isPresent()) {
-            setAngerTarget(piglin, optional.get());
+            PiglinAi.setAngerTarget(piglin, (LivingEntity) optional.get());
         } else {
-            setAngerTarget(piglin, player);
+            PiglinAi.setAngerTarget(piglin, player);
         }
+
     }
 
     private static void setAngerTargetIfCloserThanCurrent(AbstractPiglin piglin, LivingEntity target) {
-        Optional<LivingEntity> optional = getAngerTarget(piglin);
-        LivingEntity livingEntity = BehaviorUtils.getNearestTarget(piglin, optional, target);
-        if (!optional.isPresent() || optional.get() != livingEntity) {
-            setAngerTarget(piglin, livingEntity);
+        Optional<LivingEntity> optional = PiglinAi.getAngerTarget(piglin);
+        LivingEntity entityliving1 = BehaviorUtils.getNearestTarget(piglin, optional, target);
+
+        if (!optional.isPresent() || optional.get() != entityliving1) {
+            PiglinAi.setAngerTarget(piglin, entityliving1);
         }
     }
 
@@ -714,45 +684,46 @@
     }
 
     public static Optional<Player> getNearestVisibleTargetablePlayer(AbstractPiglin piglin) {
-        return piglin.getBrain().hasMemoryValue(MemoryModuleType.NEAREST_VISIBLE_ATTACKABLE_PLAYER)
-            ? piglin.getBrain().getMemory(MemoryModuleType.NEAREST_VISIBLE_ATTACKABLE_PLAYER)
-            : Optional.empty();
+        return piglin.getBrain().hasMemoryValue(MemoryModuleType.NEAREST_VISIBLE_ATTACKABLE_PLAYER) ? piglin.getBrain().getMemory(MemoryModuleType.NEAREST_VISIBLE_ATTACKABLE_PLAYER) : Optional.empty();
     }
 
     private static void broadcastRetreat(Piglin piglin, LivingEntity target) {
-        getVisibleAdultPiglins(piglin)
-            .stream()
-            .filter(nearbyVisiblePiglin -> nearbyVisiblePiglin instanceof Piglin)
-            .forEach(piglinx -> retreatFromNearestTarget((Piglin)piglinx, target));
+        PiglinAi.getVisibleAdultPiglins(piglin).stream().filter((entitypiglinabstract) -> {
+            return entitypiglinabstract instanceof Piglin;
+        }).forEach((entitypiglinabstract) -> {
+            PiglinAi.retreatFromNearestTarget((Piglin) entitypiglinabstract, target);
+        });
     }
 
     private static void retreatFromNearestTarget(Piglin piglin, LivingEntity target) {
-        Brain<Piglin> brain = piglin.getBrain();
-        LivingEntity livingEntity = BehaviorUtils.getNearestTarget(piglin, brain.getMemory(MemoryModuleType.AVOID_TARGET), target);
-        livingEntity = BehaviorUtils.getNearestTarget(piglin, brain.getMemory(MemoryModuleType.ATTACK_TARGET), livingEntity);
-        setAvoidTargetAndDontHuntForAWhile(piglin, livingEntity);
+        Brain<Piglin> behaviorcontroller = piglin.getBrain();
+        LivingEntity entityliving1 = BehaviorUtils.getNearestTarget(piglin, behaviorcontroller.getMemory(MemoryModuleType.AVOID_TARGET), target);
+
+        entityliving1 = BehaviorUtils.getNearestTarget(piglin, behaviorcontroller.getMemory(MemoryModuleType.ATTACK_TARGET), entityliving1);
+        PiglinAi.setAvoidTargetAndDontHuntForAWhile(piglin, entityliving1);
     }
 
     private static boolean wantsToStopFleeing(Piglin piglin) {
-        Brain<Piglin> brain = piglin.getBrain();
-        if (!brain.hasMemoryValue(MemoryModuleType.AVOID_TARGET)) {
+        Brain<Piglin> behaviorcontroller = piglin.getBrain();
+
+        if (!behaviorcontroller.hasMemoryValue(MemoryModuleType.AVOID_TARGET)) {
             return true;
         } else {
-            LivingEntity livingEntity = brain.getMemory(MemoryModuleType.AVOID_TARGET).get();
-            EntityType<?> entityType = livingEntity.getType();
-            return entityType == EntityType.HOGLIN
-                ? piglinsEqualOrOutnumberHoglins(piglin)
-                : isZombified(entityType) && !brain.isMemoryValue(MemoryModuleType.NEAREST_VISIBLE_ZOMBIFIED, livingEntity);
+            LivingEntity entityliving = (LivingEntity) behaviorcontroller.getMemory(MemoryModuleType.AVOID_TARGET).get();
+            EntityType<?> entitytypes = entityliving.getType();
+
+            return entitytypes == EntityType.HOGLIN ? PiglinAi.piglinsEqualOrOutnumberHoglins(piglin) : (PiglinAi.isZombified(entitytypes) ? !behaviorcontroller.isMemoryValue(MemoryModuleType.NEAREST_VISIBLE_ZOMBIFIED, entityliving) : false);
         }
     }
 
     private static boolean piglinsEqualOrOutnumberHoglins(Piglin piglin) {
-        return !hoglinsOutnumberPiglins(piglin);
+        return !PiglinAi.hoglinsOutnumberPiglins(piglin);
     }
 
     private static boolean hoglinsOutnumberPiglins(Piglin piglins) {
-        int i = piglins.getBrain().getMemory(MemoryModuleType.VISIBLE_ADULT_PIGLIN_COUNT).orElse(0) + 1;
-        int j = piglins.getBrain().getMemory(MemoryModuleType.VISIBLE_ADULT_HOGLIN_COUNT).orElse(0);
+        int i = (Integer) piglins.getBrain().getMemory(MemoryModuleType.VISIBLE_ADULT_PIGLIN_COUNT).orElse(0) + 1;
+        int j = (Integer) piglins.getBrain().getMemory(MemoryModuleType.VISIBLE_ADULT_HOGLIN_COUNT).orElse(0);
+
         return j > i;
     }
 
@@ -760,12 +731,12 @@
         piglin.getBrain().eraseMemory(MemoryModuleType.ANGRY_AT);
         piglin.getBrain().eraseMemory(MemoryModuleType.ATTACK_TARGET);
         piglin.getBrain().eraseMemory(MemoryModuleType.WALK_TARGET);
-        piglin.getBrain().setMemoryWithExpiry(MemoryModuleType.AVOID_TARGET, target, (long)RETREAT_DURATION.sample(piglin.level().random));
-        dontKillAnyMoreHoglinsForAWhile(piglin);
+        piglin.getBrain().setMemoryWithExpiry(MemoryModuleType.AVOID_TARGET, target, (long) PiglinAi.RETREAT_DURATION.sample(piglin.level().random));
+        PiglinAi.dontKillAnyMoreHoglinsForAWhile(piglin);
     }
 
     protected static void dontKillAnyMoreHoglinsForAWhile(AbstractPiglin piglin) {
-        piglin.getBrain().setMemoryWithExpiry(MemoryModuleType.HUNTED_RECENTLY, true, (long)TIME_BETWEEN_HUNTS.sample(piglin.level().random));
+        piglin.getBrain().setMemoryWithExpiry(MemoryModuleType.HUNTED_RECENTLY, true, (long) PiglinAi.TIME_BETWEEN_HUNTS.sample(piglin.level().random));
     }
 
     private static void eat(Piglin piglin) {
@@ -773,8 +744,9 @@
     }
 
     private static Vec3 getRandomNearbyPos(Piglin piglin) {
-        Vec3 vec3 = LandRandomPos.getPos(piglin, 4, 2);
-        return vec3 == null ? piglin.position() : vec3;
+        Vec3 vec3d = LandRandomPos.getPos(piglin, 4, 2);
+
+        return vec3d == null ? piglin.position() : vec3d;
     }
 
     private static boolean hasEatenRecently(Piglin piglin) {
@@ -797,8 +769,14 @@
         return entity.getBrain().hasMemoryValue(MemoryModuleType.ADMIRING_ITEM);
     }
 
+    // CraftBukkit start - Changes to allow custom payment for bartering
+    private static boolean isBarterCurrency(ItemStack itemstack, Piglin piglin) {
+        return PiglinAi.isBarterCurrency(itemstack) || piglin.allowedBarterItems.contains(itemstack.getItem());
+    }
+    // CraftBukkit end
+
     private static boolean isBarterCurrency(ItemStack stack) {
-        return stack.is(BARTERING_ITEM);
+        return stack.is(PiglinAi.BARTERING_ITEM);
     }
 
     private static boolean isFood(ItemStack stack) {
@@ -814,7 +792,7 @@
     }
 
     private static boolean doesntSeeAnyPlayerHoldingLovedItem(LivingEntity piglin) {
-        return !seesPlayerHoldingLovedItem(piglin);
+        return !PiglinAi.seesPlayerHoldingLovedItem(piglin);
     }
 
     public static boolean isPlayerHoldingLovedItem(LivingEntity target) {
@@ -834,7 +812,7 @@
     }
 
     private static boolean isNotHoldingLovedItemInOffHand(Piglin piglin) {
-        return piglin.getOffhandItem().isEmpty() || !isLovedItem(piglin.getOffhandItem());
+        return piglin.getOffhandItem().isEmpty() || !PiglinAi.isLovedItem(piglin.getOffhandItem(), piglin); // CraftBukkit - Changes to allow custom payment for bartering
     }
 
     public static boolean isZombified(EntityType<?> entityType) {
