--- a/net/minecraft/world/entity/ai/behavior/BehaviorUtils.java
+++ b/net/minecraft/world/entity/ai/behavior/BehaviorUtils.java
@@ -1,9 +1,11 @@
 package net.minecraft.world.entity.ai.behavior;
 
 import java.util.Comparator;
+import java.util.Objects;
 import java.util.Optional;
 import java.util.UUID;
 import java.util.function.Predicate;
+import java.util.stream.Stream;
 import javax.annotation.Nullable;
 import net.minecraft.core.BlockPos;
 import net.minecraft.core.SectionPos;
@@ -19,89 +21,114 @@
 import net.minecraft.world.entity.ai.memory.WalkTarget;
 import net.minecraft.world.entity.ai.util.DefaultRandomPos;
 import net.minecraft.world.entity.item.ItemEntity;
+import net.minecraft.world.item.Item;
 import net.minecraft.world.item.ItemStack;
 import net.minecraft.world.item.ProjectileWeaponItem;
 import net.minecraft.world.level.pathfinder.PathComputationType;
 import net.minecraft.world.phys.Vec3;
 
 public class BehaviorUtils {
-    private BehaviorUtils() {
-    }
+
+    private BehaviorUtils() {}
 
     public static void lockGazeAndWalkToEachOther(LivingEntity first, LivingEntity second, float speed, int walkCompletionRange) {
-        lookAtEachOther(first, second);
-        setWalkAndLookTargetMemoriesToEachOther(first, second, speed, walkCompletionRange);
+        BehaviorUtils.lookAtEachOther(first, second);
+        BehaviorUtils.setWalkAndLookTargetMemoriesToEachOther(first, second, speed, walkCompletionRange);
     }
 
     public static boolean entityIsVisible(Brain<?> brain, LivingEntity target) {
         Optional<NearestVisibleLivingEntities> optional = brain.getMemory(MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES);
-        return optional.isPresent() && optional.get().contains(target);
+
+        return optional.isPresent() && ((NearestVisibleLivingEntities) optional.get()).contains(target);
     }
 
     public static boolean targetIsValid(Brain<?> brain, MemoryModuleType<? extends LivingEntity> memoryModuleType, EntityType<?> entityType) {
-        return targetIsValid(brain, memoryModuleType, entity -> entity.getType() == entityType);
+        return BehaviorUtils.targetIsValid(brain, memoryModuleType, (entityliving) -> {
+            return entityliving.getType() == entityType;
+        });
     }
 
     private static boolean targetIsValid(Brain<?> brain, MemoryModuleType<? extends LivingEntity> memoryType, Predicate<LivingEntity> filter) {
-        return brain.getMemory(memoryType).filter(filter).filter(LivingEntity::isAlive).filter(target -> entityIsVisible(brain, target)).isPresent();
+        return brain.getMemory(memoryType).filter(filter).filter(LivingEntity::isAlive).filter((entityliving) -> {
+            return BehaviorUtils.entityIsVisible(brain, entityliving);
+        }).isPresent();
     }
 
     private static void lookAtEachOther(LivingEntity first, LivingEntity second) {
-        lookAtEntity(first, second);
-        lookAtEntity(second, first);
+        BehaviorUtils.lookAtEntity(first, second);
+        BehaviorUtils.lookAtEntity(second, first);
     }
 
     public static void lookAtEntity(LivingEntity entity, LivingEntity target) {
-        entity.getBrain().setMemory(MemoryModuleType.LOOK_TARGET, new EntityTracker(target, true));
+        entity.getBrain().setMemory(MemoryModuleType.LOOK_TARGET, (new EntityTracker(target, true))); // CraftBukkit - decompile error
     }
 
     private static void setWalkAndLookTargetMemoriesToEachOther(LivingEntity first, LivingEntity second, float speed, int completionRange) {
-        setWalkAndLookTargetMemories(first, second, speed, completionRange);
-        setWalkAndLookTargetMemories(second, first, speed, completionRange);
+        BehaviorUtils.setWalkAndLookTargetMemories(first, (Entity) second, speed, completionRange);
+        BehaviorUtils.setWalkAndLookTargetMemories(second, (Entity) first, speed, completionRange);
     }
 
     public static void setWalkAndLookTargetMemories(LivingEntity entity, Entity target, float speed, int completionRange) {
-        setWalkAndLookTargetMemories(entity, new EntityTracker(target, true), speed, completionRange);
+        BehaviorUtils.setWalkAndLookTargetMemories(entity, (PositionTracker) (new EntityTracker(target, true)), speed, completionRange);
     }
 
     public static void setWalkAndLookTargetMemories(LivingEntity entity, BlockPos target, float speed, int completionRange) {
-        setWalkAndLookTargetMemories(entity, new BlockPosTracker(target), speed, completionRange);
+        BehaviorUtils.setWalkAndLookTargetMemories(entity, (PositionTracker) (new BlockPosTracker(target)), speed, completionRange);
     }
 
     public static void setWalkAndLookTargetMemories(LivingEntity entity, PositionTracker target, float speed, int completionRange) {
-        WalkTarget walkTarget = new WalkTarget(target, speed, completionRange);
-        entity.getBrain().setMemory(MemoryModuleType.LOOK_TARGET, target);
-        entity.getBrain().setMemory(MemoryModuleType.WALK_TARGET, walkTarget);
+        WalkTarget memorytarget = new WalkTarget(target, speed, completionRange);
+
+        entity.getBrain().setMemory(MemoryModuleType.LOOK_TARGET, target); // CraftBukkit - decompile error
+        entity.getBrain().setMemory(MemoryModuleType.WALK_TARGET, memorytarget); // CraftBukkit - decompile error
     }
 
     public static void throwItem(LivingEntity entity, ItemStack stack, Vec3 targetLocation) {
-        Vec3 vec3 = new Vec3(0.3F, 0.3F, 0.3F);
-        throwItem(entity, stack, targetLocation, vec3, 0.3F);
+        Vec3 vec3d1 = new Vec3(0.30000001192092896D, 0.30000001192092896D, 0.30000001192092896D);
+
+        BehaviorUtils.throwItem(entity, stack, targetLocation, vec3d1, 0.3F);
     }
 
     public static void throwItem(LivingEntity entity, ItemStack stack, Vec3 targetLocation, Vec3 velocityFactor, float yOffset) {
-        double d = entity.getEyeY() - (double)yOffset;
-        ItemEntity itemEntity = new ItemEntity(entity.level(), entity.getX(), d, entity.getZ(), stack);
-        itemEntity.setThrower(entity);
-        Vec3 vec3 = targetLocation.subtract(entity.position());
-        vec3 = vec3.normalize().multiply(velocityFactor.x, velocityFactor.y, velocityFactor.z);
-        itemEntity.setDeltaMovement(vec3);
-        itemEntity.setDefaultPickUpDelay();
-        entity.level().addFreshEntity(itemEntity);
+        if (stack.isEmpty()) return; // CraftBukkit - SPIGOT-4940: no empty loot
+        double d0 = entity.getEyeY() - (double) yOffset;
+        ItemEntity entityitem = new ItemEntity(entity.level(), entity.getX(), d0, entity.getZ(), stack);
+
+        entityitem.setThrower(entity);
+        Vec3 vec3d2 = targetLocation.subtract(entity.position());
+
+        vec3d2 = vec3d2.normalize().multiply(velocityFactor.x, velocityFactor.y, velocityFactor.z);
+        entityitem.setDeltaMovement(vec3d2);
+        entityitem.setDefaultPickUpDelay();
+        // CraftBukkit start
+        org.bukkit.event.entity.EntityDropItemEvent event = new org.bukkit.event.entity.EntityDropItemEvent(entity.getBukkitEntity(), (org.bukkit.entity.Item) entityitem.getBukkitEntity());
+        entityitem.level().getCraftServer().getPluginManager().callEvent(event);
+        if (event.isCancelled()) {
+            return;
+        }
+        // CraftBukkit end
+        entity.level().addFreshEntity(entityitem);
     }
 
     public static SectionPos findSectionClosestToVillage(ServerLevel world, SectionPos center, int radius) {
-        int i = world.sectionsToVillage(center);
-        return SectionPos.cube(center, radius)
-            .filter(sectionPos -> world.sectionsToVillage(sectionPos) < i)
-            .min(Comparator.comparingInt(world::sectionsToVillage))
-            .orElse(center);
+        int j = world.sectionsToVillage(center);
+        Stream<SectionPos> stream = SectionPos.cube(center, radius).filter((sectionposition1) -> { // CraftBukkit - decompile error
+            return world.sectionsToVillage(sectionposition1) < j;
+        });
+
+        Objects.requireNonNull(world);
+        return (SectionPos) stream.min(Comparator.comparingInt(world::sectionsToVillage)).orElse(center);
     }
 
     public static boolean isWithinAttackRange(Mob mob, LivingEntity target, int rangedWeaponReachReduction) {
-        if (mob.getMainHandItem().getItem() instanceof ProjectileWeaponItem projectileWeaponItem && mob.canFireProjectileWeapon(projectileWeaponItem)) {
-            int i = projectileWeaponItem.getDefaultProjectileRange() - rangedWeaponReachReduction;
-            return mob.closerThan(target, (double)i);
+        Item item = mob.getMainHandItem().getItem();
+
+        if (item instanceof ProjectileWeaponItem itemprojectileweapon) {
+            if (mob.canFireProjectileWeapon(itemprojectileweapon)) {
+                int j = itemprojectileweapon.getDefaultProjectileRange() - rangedWeaponReachReduction;
+
+                return mob.closerThan(target, (double) j);
+            }
         }
 
         return mob.isWithinMeleeAttackRange(target);
@@ -109,47 +136,61 @@
 
     public static boolean isOtherTargetMuchFurtherAwayThanCurrentAttackTarget(LivingEntity source, LivingEntity target, double extraDistance) {
         Optional<LivingEntity> optional = source.getBrain().getMemory(MemoryModuleType.ATTACK_TARGET);
+
         if (optional.isEmpty()) {
             return false;
         } else {
-            double d = source.distanceToSqr(optional.get().position());
-            double e = source.distanceToSqr(target.position());
-            return e > d + extraDistance * extraDistance;
+            double d1 = source.distanceToSqr(((LivingEntity) optional.get()).position());
+            double d2 = source.distanceToSqr(target.position());
+
+            return d2 > d1 + extraDistance * extraDistance;
         }
     }
 
     public static boolean canSee(LivingEntity source, LivingEntity target) {
-        Brain<?> brain = source.getBrain();
-        return brain.hasMemoryValue(MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES)
-            && brain.getMemory(MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES).get().contains(target);
+        Brain<?> behaviorcontroller = source.getBrain();
+
+        return !behaviorcontroller.hasMemoryValue(MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES) ? false : ((NearestVisibleLivingEntities) behaviorcontroller.getMemory(MemoryModuleType.NEAREST_VISIBLE_LIVING_ENTITIES).get()).contains(target);
     }
 
     public static LivingEntity getNearestTarget(LivingEntity source, Optional<LivingEntity> first, LivingEntity second) {
-        return first.isEmpty() ? second : getTargetNearestMe(source, first.get(), second);
+        return first.isEmpty() ? second : BehaviorUtils.getTargetNearestMe(source, (LivingEntity) first.get(), second);
     }
 
     public static LivingEntity getTargetNearestMe(LivingEntity source, LivingEntity first, LivingEntity second) {
-        Vec3 vec3 = first.position();
-        Vec3 vec32 = second.position();
-        return source.distanceToSqr(vec3) < source.distanceToSqr(vec32) ? first : second;
+        Vec3 vec3d = first.position();
+        Vec3 vec3d1 = second.position();
+
+        return source.distanceToSqr(vec3d) < source.distanceToSqr(vec3d1) ? first : second;
     }
 
     public static Optional<LivingEntity> getLivingEntityFromUUIDMemory(LivingEntity entity, MemoryModuleType<UUID> uuidMemoryModule) {
         Optional<UUID> optional = entity.getBrain().getMemory(uuidMemoryModule);
-        return optional.<Entity>map(uuid -> ((ServerLevel)entity.level()).getEntity(uuid))
-            .map(target -> target instanceof LivingEntity livingEntity ? livingEntity : null);
+
+        return optional.map((uuid) -> {
+            return ((ServerLevel) entity.level()).getEntity(uuid);
+        }).map((entity1) -> { // Paper - remap fix
+            LivingEntity entityliving1;
+
+            if (entity1 instanceof LivingEntity entityliving2) { // Paper - remap fix
+                entityliving1 = entityliving2;
+            } else {
+                entityliving1 = null;
+            }
+
+            return entityliving1;
+        });
     }
 
     @Nullable
     public static Vec3 getRandomSwimmablePos(PathfinderMob entity, int horizontalRange, int verticalRange) {
-        Vec3 vec3 = DefaultRandomPos.getPos(entity, horizontalRange, verticalRange);
-        int i = 0;
+        Vec3 vec3d = DefaultRandomPos.getPos(entity, horizontalRange, verticalRange);
 
-        while (vec3 != null && !entity.level().getBlockState(BlockPos.containing(vec3)).isPathfindable(PathComputationType.WATER) && i++ < 10) {
-            vec3 = DefaultRandomPos.getPos(entity, horizontalRange, verticalRange);
+        for (int k = 0; vec3d != null && !entity.level().getBlockState(BlockPos.containing(vec3d)).isPathfindable(PathComputationType.WATER) && k++ < 10; vec3d = DefaultRandomPos.getPos(entity, horizontalRange, verticalRange)) {
+            ;
         }
 
-        return vec3;
+        return vec3d;
     }
 
     public static boolean isBreeding(LivingEntity entity) {
