--- a/net/minecraft/world/level/block/WitherSkullBlock.java
+++ b/net/minecraft/world/level/block/WitherSkullBlock.java
@@ -1,5 +1,6 @@
 package net.minecraft.world.level.block;
 
+import java.util.Iterator;
 import javax.annotation.Nullable;
 import net.minecraft.advancements.CriteriaTriggers;
 import net.minecraft.core.BlockPos;
@@ -7,6 +8,7 @@
 import net.minecraft.server.level.ServerPlayer;
 import net.minecraft.tags.BlockTags;
 import net.minecraft.world.Difficulty;
+import net.minecraft.world.entity.Entity;
 import net.minecraft.world.entity.EntityType;
 import net.minecraft.world.entity.LivingEntity;
 import net.minecraft.world.entity.boss.wither.WitherBoss;
@@ -24,7 +26,12 @@
 import net.minecraft.world.level.block.state.predicate.BlockStatePredicate;
 import net.minecraft.world.level.material.Material;
 
+// CraftBukkit start
+import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
+// CraftBukkit end
+
 public class WitherSkullBlock extends SkullBlock {
+
     @Nullable
     private static BlockPattern witherPatternFull;
     @Nullable
@@ -37,34 +44,49 @@
     @Override
     public void setPlacedBy(Level world, BlockPos pos, BlockState state, @Nullable LivingEntity placer, ItemStack itemStack) {
         super.setPlacedBy(world, pos, state, placer, itemStack);
-        BlockEntity blockEntity = world.getBlockEntity(pos);
-        if (blockEntity instanceof SkullBlockEntity) {
-            checkSpawn(world, pos, (SkullBlockEntity)blockEntity);
+        BlockEntity tileentity = world.getBlockEntity(pos);
+
+        if (tileentity instanceof SkullBlockEntity) {
+            WitherSkullBlock.checkSpawn(world, pos, (SkullBlockEntity) tileentity);
         }
 
     }
 
     public static void checkSpawn(Level world, BlockPos pos, SkullBlockEntity blockEntity) {
+        if (world.captureBlockStates) return; // CraftBukkit
         if (!world.isClientSide) {
-            BlockState blockState = blockEntity.getBlockState();
-            boolean bl = blockState.is(Blocks.WITHER_SKELETON_SKULL) || blockState.is(Blocks.WITHER_SKELETON_WALL_SKULL);
-            if (bl && pos.getY() >= world.getMinBuildHeight() && world.getDifficulty() != Difficulty.PEACEFUL) {
-                BlockPattern.BlockPatternMatch blockPatternMatch = getOrCreateWitherFull().find(world, pos);
-                if (blockPatternMatch != null) {
-                    WitherBoss witherBoss = EntityType.WITHER.create(world);
-                    if (witherBoss != null) {
-                        CarvedPumpkinBlock.clearPatternBlocks(world, blockPatternMatch);
-                        BlockPos blockPos = blockPatternMatch.getBlock(1, 2, 0).getPos();
-                        witherBoss.moveTo((double)blockPos.getX() + 0.5D, (double)blockPos.getY() + 0.55D, (double)blockPos.getZ() + 0.5D, blockPatternMatch.getForwards().getAxis() == Direction.Axis.X ? 0.0F : 90.0F, 0.0F);
-                        witherBoss.yBodyRot = blockPatternMatch.getForwards().getAxis() == Direction.Axis.X ? 0.0F : 90.0F;
-                        witherBoss.makeInvulnerable();
+            BlockState iblockdata = blockEntity.getBlockState();
+            boolean flag = iblockdata.is(Blocks.WITHER_SKELETON_SKULL) || iblockdata.is(Blocks.WITHER_SKELETON_WALL_SKULL);
 
-                        for(ServerPlayer serverPlayer : world.getEntitiesOfClass(ServerPlayer.class, witherBoss.getBoundingBox().inflate(50.0D))) {
-                            CriteriaTriggers.SUMMONED_ENTITY.trigger(serverPlayer, witherBoss);
+            if (flag && pos.getY() >= world.getMinBuildHeight() && world.getDifficulty() != Difficulty.PEACEFUL) {
+                BlockPattern.BlockPatternMatch shapedetector_shapedetectorcollection = WitherSkullBlock.getOrCreateWitherFull().find(world, pos);
+
+                if (shapedetector_shapedetectorcollection != null) {
+                    WitherBoss entitywither = (WitherBoss) EntityType.WITHER.create(world);
+
+                    if (entitywither != null) {
+                        // BlockPumpkinCarved.clearPatternBlocks(world, shapedetector_shapedetectorcollection); // CraftBukkit - move down
+                        BlockPos blockposition1 = shapedetector_shapedetectorcollection.getBlock(1, 2, 0).getPos();
+
+                        entitywither.moveTo((double) blockposition1.getX() + 0.5D, (double) blockposition1.getY() + 0.55D, (double) blockposition1.getZ() + 0.5D, shapedetector_shapedetectorcollection.getForwards().getAxis() == Direction.Axis.X ? 0.0F : 90.0F, 0.0F);
+                        entitywither.yBodyRot = shapedetector_shapedetectorcollection.getForwards().getAxis() == Direction.Axis.X ? 0.0F : 90.0F;
+                        entitywither.makeInvulnerable();
+                        // CraftBukkit start
+                        if (!world.addFreshEntity(entitywither, SpawnReason.BUILD_WITHER)) {
+                            return;
                         }
+                        CarvedPumpkinBlock.clearPatternBlocks(world, shapedetector_shapedetectorcollection); // CraftBukkit - from above
+                        // CraftBukkit end
+                        Iterator iterator = world.getEntitiesOfClass(ServerPlayer.class, entitywither.getBoundingBox().inflate(50.0D)).iterator();
 
-                        world.addFreshEntity(witherBoss);
-                        CarvedPumpkinBlock.updatePatternBlocks(world, blockPatternMatch);
+                        while (iterator.hasNext()) {
+                            ServerPlayer entityplayer = (ServerPlayer) iterator.next();
+
+                            CriteriaTriggers.SUMMONED_ENTITY.trigger(entityplayer, (Entity) entitywither);
+                        }
+
+                        // world.addFreshEntity(entitywither); // CraftBukkit - moved up
+                        CarvedPumpkinBlock.updatePatternBlocks(world, shapedetector_shapedetectorcollection);
                     }
 
                 }
@@ -73,30 +95,26 @@
     }
 
     public static boolean canSpawnMob(Level world, BlockPos pos, ItemStack stack) {
-        if (stack.is(Items.WITHER_SKELETON_SKULL) && pos.getY() >= world.getMinBuildHeight() + 2 && world.getDifficulty() != Difficulty.PEACEFUL && !world.isClientSide) {
-            return getOrCreateWitherBase().find(world, pos) != null;
-        } else {
-            return false;
-        }
+        return stack.is(Items.WITHER_SKELETON_SKULL) && pos.getY() >= world.getMinBuildHeight() + 2 && world.getDifficulty() != Difficulty.PEACEFUL && !world.isClientSide ? WitherSkullBlock.getOrCreateWitherBase().find(world, pos) != null : false;
     }
 
     private static BlockPattern getOrCreateWitherFull() {
-        if (witherPatternFull == null) {
-            witherPatternFull = BlockPatternBuilder.start().aisle("^^^", "###", "~#~").where('#', (pos) -> {
-                return pos.getState().is(BlockTags.WITHER_SUMMON_BASE_BLOCKS);
+        if (WitherSkullBlock.witherPatternFull == null) {
+            WitherSkullBlock.witherPatternFull = BlockPatternBuilder.start().aisle("^^^", "###", "~#~").where('#', (shapedetectorblock) -> {
+                return shapedetectorblock.getState().is(BlockTags.WITHER_SUMMON_BASE_BLOCKS);
             }).where('^', BlockInWorld.hasState(BlockStatePredicate.forBlock(Blocks.WITHER_SKELETON_SKULL).or(BlockStatePredicate.forBlock(Blocks.WITHER_SKELETON_WALL_SKULL)))).where('~', BlockInWorld.hasState(BlockMaterialPredicate.forMaterial(Material.AIR))).build();
         }
 
-        return witherPatternFull;
+        return WitherSkullBlock.witherPatternFull;
     }
 
     private static BlockPattern getOrCreateWitherBase() {
-        if (witherPatternBase == null) {
-            witherPatternBase = BlockPatternBuilder.start().aisle("   ", "###", "~#~").where('#', (pos) -> {
-                return pos.getState().is(BlockTags.WITHER_SUMMON_BASE_BLOCKS);
+        if (WitherSkullBlock.witherPatternBase == null) {
+            WitherSkullBlock.witherPatternBase = BlockPatternBuilder.start().aisle("   ", "###", "~#~").where('#', (shapedetectorblock) -> {
+                return shapedetectorblock.getState().is(BlockTags.WITHER_SUMMON_BASE_BLOCKS);
             }).where('~', BlockInWorld.hasState(BlockMaterialPredicate.forMaterial(Material.AIR))).build();
         }
 
-        return witherPatternBase;
+        return WitherSkullBlock.witherPatternBase;
     }
 }
