--- a/net/minecraft/world/level/portal/PortalTravelAgent.java
+++ b/net/minecraft/world/level/portal/PortalTravelAgent.java
@@ -42,15 +42,21 @@
     }
 
     public Optional<BlockUtil.Rectangle> findPortalAround(BlockPosition blockposition, boolean flag, WorldBorder worldborder) {
+        // CraftBukkit start
+        return findPortalAround(blockposition, worldborder, flag ? 16 : 128); // Search Radius
+    }
+
+    public Optional<BlockUtil.Rectangle> findPortalAround(BlockPosition blockposition, WorldBorder worldborder, int i) {
         VillagePlace villageplace = this.level.getPoiManager();
-        int i = flag ? 16 : 128;
+        // int i = flag ? 16 : 128;
+        // CraftBukkit end
 
         villageplace.ensureLoadedAndValid(this.level, blockposition, i);
         Optional<VillagePlaceRecord> optional = villageplace.getInSquare((holder) -> {
             return holder.is(PoiTypes.NETHER_PORTAL);
         }, blockposition, i, VillagePlace.Occupancy.ANY).filter((villageplacerecord) -> {
             return worldborder.isWithinBounds(villageplacerecord.getPos());
-        }).sorted(Comparator.comparingDouble((villageplacerecord) -> {
+        }).sorted(Comparator.comparingDouble((VillagePlaceRecord villageplacerecord) -> { // CraftBukkit - decompile error
             return villageplacerecord.getPos().distSqr(blockposition);
         }).thenComparingInt((villageplacerecord) -> {
             return villageplacerecord.getPos().getY();
@@ -71,6 +77,12 @@
     }
 
     public Optional<BlockUtil.Rectangle> createPortal(BlockPosition blockposition, EnumDirection.EnumAxis enumdirection_enumaxis) {
+        // CraftBukkit start
+        return this.createPortal(blockposition, enumdirection_enumaxis, null, 16);
+    }
+
+    public Optional<BlockUtil.Rectangle> createPortal(BlockPosition blockposition, EnumDirection.EnumAxis enumdirection_enumaxis, net.minecraft.world.entity.Entity entity, int createRadius) {
+        // CraftBukkit end
         EnumDirection enumdirection = EnumDirection.get(EnumDirection.EnumAxisDirection.POSITIVE, enumdirection_enumaxis);
         double d0 = -1.0D;
         BlockPosition blockposition1 = null;
@@ -79,7 +91,7 @@
         WorldBorder worldborder = this.level.getWorldBorder();
         int i = Math.min(this.level.getMaxBuildHeight(), this.level.getMinBuildHeight() + this.level.getLogicalHeight()) - 1;
         BlockPosition.MutableBlockPosition blockposition_mutableblockposition = blockposition.mutable();
-        Iterator iterator = BlockPosition.spiralAround(blockposition, 16, EnumDirection.EAST, EnumDirection.SOUTH).iterator();
+        Iterator iterator = BlockPosition.spiralAround(blockposition, createRadius, EnumDirection.EAST, EnumDirection.SOUTH).iterator(); // CraftBukkit
 
         int j;
         int k;
@@ -134,6 +146,7 @@
         int j1;
         int k1;
 
+        org.bukkit.craftbukkit.util.BlockStateListPopulator blockList = new org.bukkit.craftbukkit.util.BlockStateListPopulator(this.level); // CraftBukkit - Use BlockStateListPopulator
         if (d0 == -1.0D) {
             j1 = Math.max(this.level.getMinBuildHeight() - -1, 70);
             k1 = i - 9;
@@ -154,7 +167,7 @@
                         IBlockData iblockdata = l < 0 ? Blocks.OBSIDIAN.defaultBlockState() : Blocks.AIR.defaultBlockState();
 
                         blockposition_mutableblockposition.setWithOffset(blockposition1, k * enumdirection.getStepX() + l1 * enumdirection1.getStepX(), l, k * enumdirection.getStepZ() + l1 * enumdirection1.getStepZ());
-                        this.level.setBlockAndUpdate(blockposition_mutableblockposition, iblockdata);
+                        blockList.setBlock(blockposition_mutableblockposition, iblockdata, 3); // CraftBukkit
                     }
                 }
             }
@@ -164,7 +177,7 @@
             for (k1 = -1; k1 < 4; ++k1) {
                 if (j1 == -1 || j1 == 2 || k1 == -1 || k1 == 3) {
                     blockposition_mutableblockposition.setWithOffset(blockposition1, j1 * enumdirection.getStepX(), k1, j1 * enumdirection.getStepZ());
-                    this.level.setBlock(blockposition_mutableblockposition, Blocks.OBSIDIAN.defaultBlockState(), 3);
+                    blockList.setBlock(blockposition_mutableblockposition, Blocks.OBSIDIAN.defaultBlockState(), 3); // CraftBukkit
                 }
             }
         }
@@ -174,10 +187,20 @@
         for (k1 = 0; k1 < 2; ++k1) {
             for (j = 0; j < 3; ++j) {
                 blockposition_mutableblockposition.setWithOffset(blockposition1, k1 * enumdirection.getStepX(), j, k1 * enumdirection.getStepZ());
-                this.level.setBlock(blockposition_mutableblockposition, iblockdata1, 18);
+                blockList.setBlock(blockposition_mutableblockposition, iblockdata1, 18); // CraftBukkit
             }
         }
 
+        // CraftBukkit start
+        org.bukkit.World bworld = this.level.getWorld();
+        org.bukkit.event.world.PortalCreateEvent event = new org.bukkit.event.world.PortalCreateEvent((java.util.List<org.bukkit.block.BlockState>) (java.util.List) blockList.getList(), bworld, (entity == null) ? null : entity.getBukkitEntity(), org.bukkit.event.world.PortalCreateEvent.CreateReason.NETHER_PAIR);
+
+        this.level.getCraftServer().getPluginManager().callEvent(event);
+        if (event.isCancelled()) {
+            return Optional.empty();
+        }
+        blockList.updateList();
+        // CraftBukkit end
         return Optional.of(new BlockUtil.Rectangle(blockposition1.immutable(), 2, 3));
     }
 
