--- a/net/minecraft/world/level/chunk/ChunkStatus.java
+++ b/net/minecraft/world/level/chunk/ChunkStatus.java
@@ -29,144 +29,182 @@
 import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager;
 
 public class ChunkStatus {
+
+    // Paper start - rewrite chunk system
+    public boolean isParallelCapable; // Paper
+    public int writeRadius = -1;
+    public int loadRange = 0;
+
+    protected static final java.util.List<ChunkStatus> statuses = new java.util.ArrayList<>();
+
+    private ChunkStatus nextStatus;
+
+    public final ChunkStatus getNextStatus() {
+        return this.nextStatus;
+    }
+
+    public final boolean isEmptyLoadStatus() {
+        return this.loadingTask == PASSTHROUGH_LOAD_TASK;
+    }
+
+    public final boolean isEmptyGenStatus() {
+        return this == ChunkStatus.EMPTY || this == ChunkStatus.HEIGHTMAPS || this == ChunkStatus.LIQUID_CARVERS;
+    }
+
+    public final java.util.concurrent.atomic.AtomicBoolean warnedAboutNoImmediateComplete = new java.util.concurrent.atomic.AtomicBoolean();
+    // Paper end - rewrite chunk system
+
     public static final int MAX_STRUCTURE_DISTANCE = 8;
     private static final EnumSet<Heightmap.Types> PRE_FEATURES = EnumSet.of(Heightmap.Types.OCEAN_FLOOR_WG, Heightmap.Types.WORLD_SURFACE_WG);
     public static final EnumSet<Heightmap.Types> POST_FEATURES = EnumSet.of(Heightmap.Types.OCEAN_FLOOR, Heightmap.Types.WORLD_SURFACE, Heightmap.Types.MOTION_BLOCKING, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES);
-    private static final ChunkStatus.LoadingTask PASSTHROUGH_LOAD_TASK = (targetStatus, world, structureTemplateManager, lightingProvider, fullChunkConverter, chunk) -> {
-        if (chunk instanceof ProtoChunk protoChunk) {
-            if (!chunk.getStatus().isOrAfter(targetStatus)) {
-                protoChunk.setStatus(targetStatus);
+    private static final ChunkStatus.LoadingTask PASSTHROUGH_LOAD_TASK = (chunkstatus, worldserver, structuretemplatemanager, lightenginethreaded, function, ichunkaccess) -> {
+        if (ichunkaccess instanceof ProtoChunk) {
+            ProtoChunk protochunk = (ProtoChunk) ichunkaccess;
+
+            if (!ichunkaccess.getStatus().isOrAfter(chunkstatus)) {
+                protochunk.setStatus(chunkstatus);
             }
         }
 
-        return CompletableFuture.completedFuture(Either.left(chunk));
+        return CompletableFuture.completedFuture(Either.left(ichunkaccess));
     };
-    public static final ChunkStatus EMPTY = registerSimple("empty", (ChunkStatus)null, -1, PRE_FEATURES, ChunkStatus.ChunkType.PROTOCHUNK, (targetStatus, world, generator, chunks, chunk) -> {
+    public static final ChunkStatus EMPTY = ChunkStatus.registerSimple("empty", (ChunkStatus) null, -1, ChunkStatus.PRE_FEATURES, ChunkStatus.ChunkType.PROTOCHUNK, (chunkstatus, worldserver, chunkgenerator, list, ichunkaccess) -> {
     });
-    public static final ChunkStatus STRUCTURE_STARTS = register("structure_starts", EMPTY, 0, PRE_FEATURES, ChunkStatus.ChunkType.PROTOCHUNK, (targetStatus, executor, world, generator, structureTemplateManager, lightingProvider, fullChunkConverter, chunks, chunk, regenerate) -> {
-        if (!chunk.getStatus().isOrAfter(targetStatus)) {
-            if (world.getServer().getWorldData().worldGenOptions().generateStructures()) {
-                generator.createStructures(world.registryAccess(), world.getChunkSource().getGeneratorState(), world.structureManager(), chunk, structureTemplateManager);
+    public static final ChunkStatus STRUCTURE_STARTS = ChunkStatus.register("structure_starts", ChunkStatus.EMPTY, 0, ChunkStatus.PRE_FEATURES, ChunkStatus.ChunkType.PROTOCHUNK, (chunkstatus, executor, worldserver, chunkgenerator, structuretemplatemanager, lightenginethreaded, function, list, ichunkaccess, flag) -> {
+        if (!ichunkaccess.getStatus().isOrAfter(chunkstatus)) {
+            if (worldserver.serverLevelData.worldGenOptions().generateStructures()) { // CraftBukkit
+                chunkgenerator.createStructures(worldserver.registryAccess(), worldserver.getChunkSource().getGeneratorState(), worldserver.structureManager(), ichunkaccess, structuretemplatemanager);
             }
 
-            if (chunk instanceof ProtoChunk) {
-                ProtoChunk protoChunk = (ProtoChunk)chunk;
-                protoChunk.setStatus(targetStatus);
+            if (ichunkaccess instanceof ProtoChunk) {
+                ProtoChunk protochunk = (ProtoChunk) ichunkaccess;
+
+                protochunk.setStatus(chunkstatus);
             }
 
-            world.onStructureStartsAvailable(chunk);
+            worldserver.onStructureStartsAvailable(ichunkaccess);
         }
 
-        return CompletableFuture.completedFuture(Either.left(chunk));
-    }, (targetStatus, world, structureTemplateManager, lightingProvider, fullChunkConverter, chunk) -> {
-        if (!chunk.getStatus().isOrAfter(targetStatus)) {
-            if (chunk instanceof ProtoChunk) {
-                ProtoChunk protoChunk = (ProtoChunk)chunk;
-                protoChunk.setStatus(targetStatus);
+        return CompletableFuture.completedFuture(Either.left(ichunkaccess));
+    }, (chunkstatus, worldserver, structuretemplatemanager, lightenginethreaded, function, ichunkaccess) -> {
+        if (!ichunkaccess.getStatus().isOrAfter(chunkstatus)) {
+            if (ichunkaccess instanceof ProtoChunk) {
+                ProtoChunk protochunk = (ProtoChunk) ichunkaccess;
+
+                protochunk.setStatus(chunkstatus);
             }
 
-            world.onStructureStartsAvailable(chunk);
+            worldserver.onStructureStartsAvailable(ichunkaccess);
         }
 
-        return CompletableFuture.completedFuture(Either.left(chunk));
+        return CompletableFuture.completedFuture(Either.left(ichunkaccess));
     });
-    public static final ChunkStatus STRUCTURE_REFERENCES = registerSimple("structure_references", STRUCTURE_STARTS, 8, PRE_FEATURES, ChunkStatus.ChunkType.PROTOCHUNK, (targetStatus, world, generator, chunks, chunk) -> {
-        WorldGenRegion worldGenRegion = new WorldGenRegion(world, chunks, targetStatus, -1);
-        generator.createReferences(worldGenRegion, world.structureManager().forWorldGenRegion(worldGenRegion), chunk);
+    public static final ChunkStatus STRUCTURE_REFERENCES = ChunkStatus.registerSimple("structure_references", ChunkStatus.STRUCTURE_STARTS, 8, ChunkStatus.PRE_FEATURES, ChunkStatus.ChunkType.PROTOCHUNK, (chunkstatus, worldserver, chunkgenerator, list, ichunkaccess) -> {
+        WorldGenRegion regionlimitedworldaccess = new WorldGenRegion(worldserver, list, chunkstatus, -1);
+
+        chunkgenerator.createReferences(regionlimitedworldaccess, worldserver.structureManager().forWorldGenRegion(regionlimitedworldaccess), ichunkaccess);
     });
-    public static final ChunkStatus BIOMES = register("biomes", STRUCTURE_REFERENCES, 8, PRE_FEATURES, ChunkStatus.ChunkType.PROTOCHUNK, (targetStatus, executor, world, generator, structureTemplateManager, lightingProvider, fullChunkConverter, chunks, chunk, regenerate) -> {
-        if (!regenerate && chunk.getStatus().isOrAfter(targetStatus)) {
-            return CompletableFuture.completedFuture(Either.left(chunk));
+    public static final ChunkStatus BIOMES = ChunkStatus.register("biomes", ChunkStatus.STRUCTURE_REFERENCES, 8, ChunkStatus.PRE_FEATURES, ChunkStatus.ChunkType.PROTOCHUNK, (chunkstatus, executor, worldserver, chunkgenerator, structuretemplatemanager, lightenginethreaded, function, list, ichunkaccess, flag) -> {
+        if (!flag && ichunkaccess.getStatus().isOrAfter(chunkstatus)) {
+            return CompletableFuture.completedFuture(Either.left(ichunkaccess));
         } else {
-            WorldGenRegion worldGenRegion = new WorldGenRegion(world, chunks, targetStatus, -1);
-            return generator.createBiomes(executor, world.getChunkSource().randomState(), Blender.of(worldGenRegion), world.structureManager().forWorldGenRegion(worldGenRegion), chunk).thenApply((chunkx) -> {
-                if (chunkx instanceof ProtoChunk) {
-                    ((ProtoChunk)chunkx).setStatus(targetStatus);
+            WorldGenRegion regionlimitedworldaccess = new WorldGenRegion(worldserver, list, chunkstatus, -1);
+
+            return chunkgenerator.createBiomes(executor, worldserver.getChunkSource().randomState(), Blender.of(regionlimitedworldaccess), worldserver.structureManager().forWorldGenRegion(regionlimitedworldaccess), ichunkaccess).thenApply((ichunkaccess1) -> {
+                if (ichunkaccess1 instanceof ProtoChunk) {
+                    ((ProtoChunk) ichunkaccess1).setStatus(chunkstatus);
                 }
 
-                return Either.left(chunkx);
+                return Either.left(ichunkaccess1);
             });
         }
     });
-    public static final ChunkStatus NOISE = register("noise", BIOMES, 8, PRE_FEATURES, ChunkStatus.ChunkType.PROTOCHUNK, (targetStatus, executor, world, generator, structureTemplateManager, lightingProvider, fullChunkConverter, chunks, chunk, regenerate) -> {
-        if (!regenerate && chunk.getStatus().isOrAfter(targetStatus)) {
-            return CompletableFuture.completedFuture(Either.left(chunk));
+    public static final ChunkStatus NOISE = ChunkStatus.register("noise", ChunkStatus.BIOMES, 8, ChunkStatus.PRE_FEATURES, ChunkStatus.ChunkType.PROTOCHUNK, (chunkstatus, executor, worldserver, chunkgenerator, structuretemplatemanager, lightenginethreaded, function, list, ichunkaccess, flag) -> {
+        if (!flag && ichunkaccess.getStatus().isOrAfter(chunkstatus)) {
+            return CompletableFuture.completedFuture(Either.left(ichunkaccess));
         } else {
-            WorldGenRegion worldGenRegion = new WorldGenRegion(world, chunks, targetStatus, 0);
-            return generator.fillFromNoise(executor, Blender.of(worldGenRegion), world.getChunkSource().randomState(), world.structureManager().forWorldGenRegion(worldGenRegion), chunk).thenApply((chunkx) -> {
-                if (chunkx instanceof ProtoChunk protoChunk) {
-                    BelowZeroRetrogen belowZeroRetrogen = protoChunk.getBelowZeroRetrogen();
-                    if (belowZeroRetrogen != null) {
-                        BelowZeroRetrogen.replaceOldBedrock(protoChunk);
-                        if (belowZeroRetrogen.hasBedrockHoles()) {
-                            belowZeroRetrogen.applyBedrockMask(protoChunk);
+            WorldGenRegion regionlimitedworldaccess = new WorldGenRegion(worldserver, list, chunkstatus, 0);
+
+            return chunkgenerator.fillFromNoise(executor, Blender.of(regionlimitedworldaccess), worldserver.getChunkSource().randomState(), worldserver.structureManager().forWorldGenRegion(regionlimitedworldaccess), ichunkaccess).thenApply((ichunkaccess1) -> {
+                if (ichunkaccess1 instanceof ProtoChunk) {
+                    ProtoChunk protochunk = (ProtoChunk) ichunkaccess1;
+                    BelowZeroRetrogen belowzeroretrogen = protochunk.getBelowZeroRetrogen();
+
+                    if (belowzeroretrogen != null) {
+                        BelowZeroRetrogen.replaceOldBedrock(protochunk);
+                        if (belowzeroretrogen.hasBedrockHoles()) {
+                            belowzeroretrogen.applyBedrockMask(protochunk);
                         }
                     }
 
-                    protoChunk.setStatus(targetStatus);
+                    protochunk.setStatus(chunkstatus);
                 }
 
-                return Either.left(chunkx);
+                return Either.left(ichunkaccess1);
             });
         }
     });
-    public static final ChunkStatus SURFACE = registerSimple("surface", NOISE, 8, PRE_FEATURES, ChunkStatus.ChunkType.PROTOCHUNK, (targetStatus, world, generator, chunks, chunk) -> {
-        WorldGenRegion worldGenRegion = new WorldGenRegion(world, chunks, targetStatus, 0);
-        generator.buildSurface(worldGenRegion, world.structureManager().forWorldGenRegion(worldGenRegion), world.getChunkSource().randomState(), chunk);
+    public static final ChunkStatus SURFACE = ChunkStatus.registerSimple("surface", ChunkStatus.NOISE, 8, ChunkStatus.PRE_FEATURES, ChunkStatus.ChunkType.PROTOCHUNK, (chunkstatus, worldserver, chunkgenerator, list, ichunkaccess) -> {
+        WorldGenRegion regionlimitedworldaccess = new WorldGenRegion(worldserver, list, chunkstatus, 0);
+
+        chunkgenerator.buildSurface(regionlimitedworldaccess, worldserver.structureManager().forWorldGenRegion(regionlimitedworldaccess), worldserver.getChunkSource().randomState(), ichunkaccess);
     });
-    public static final ChunkStatus CARVERS = registerSimple("carvers", SURFACE, 8, PRE_FEATURES, ChunkStatus.ChunkType.PROTOCHUNK, (targetStatus, world, generator, chunks, chunk) -> {
-        WorldGenRegion worldGenRegion = new WorldGenRegion(world, chunks, targetStatus, 0);
-        if (chunk instanceof ProtoChunk protoChunk) {
-            Blender.addAroundOldChunksCarvingMaskFilter(worldGenRegion, protoChunk);
+    public static final ChunkStatus CARVERS = ChunkStatus.registerSimple("carvers", ChunkStatus.SURFACE, 8, ChunkStatus.PRE_FEATURES, ChunkStatus.ChunkType.PROTOCHUNK, (chunkstatus, worldserver, chunkgenerator, list, ichunkaccess) -> {
+        WorldGenRegion regionlimitedworldaccess = new WorldGenRegion(worldserver, list, chunkstatus, 0);
+
+        if (ichunkaccess instanceof ProtoChunk) {
+            ProtoChunk protochunk = (ProtoChunk) ichunkaccess;
+
+            Blender.addAroundOldChunksCarvingMaskFilter(regionlimitedworldaccess, protochunk);
         }
 
-        generator.applyCarvers(worldGenRegion, world.getSeed(), world.getChunkSource().randomState(), world.getBiomeManager(), world.structureManager().forWorldGenRegion(worldGenRegion), chunk, GenerationStep.Carving.AIR);
+        chunkgenerator.applyCarvers(regionlimitedworldaccess, worldserver.getSeed(), worldserver.getChunkSource().randomState(), worldserver.getBiomeManager(), worldserver.structureManager().forWorldGenRegion(regionlimitedworldaccess), ichunkaccess, GenerationStep.Carving.AIR);
     });
-    public static final ChunkStatus LIQUID_CARVERS = registerSimple("liquid_carvers", CARVERS, 8, POST_FEATURES, ChunkStatus.ChunkType.PROTOCHUNK, (targetStatus, world, generator, chunks, chunk) -> {
+    public static final ChunkStatus LIQUID_CARVERS = ChunkStatus.registerSimple("liquid_carvers", ChunkStatus.CARVERS, 8, ChunkStatus.POST_FEATURES, ChunkStatus.ChunkType.PROTOCHUNK, (chunkstatus, worldserver, chunkgenerator, list, ichunkaccess) -> {
     });
-    public static final ChunkStatus FEATURES = register("features", LIQUID_CARVERS, 8, POST_FEATURES, ChunkStatus.ChunkType.PROTOCHUNK, (targetStatus, executor, world, generator, structureTemplateManager, lightingProvider, fullChunkConverter, chunks, chunk, regenerate) -> {
-        ProtoChunk protoChunk = (ProtoChunk)chunk;
-        protoChunk.setLightEngine(lightingProvider);
-        if (regenerate || !chunk.getStatus().isOrAfter(targetStatus)) {
-            Heightmap.primeHeightmaps(chunk, EnumSet.of(Heightmap.Types.MOTION_BLOCKING, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, Heightmap.Types.OCEAN_FLOOR, Heightmap.Types.WORLD_SURFACE));
-            WorldGenRegion worldGenRegion = new WorldGenRegion(world, chunks, targetStatus, 1);
-            generator.applyBiomeDecoration(worldGenRegion, chunk, world.structureManager().forWorldGenRegion(worldGenRegion));
-            Blender.generateBorderTicks(worldGenRegion, chunk);
-            protoChunk.setStatus(targetStatus);
+    public static final ChunkStatus FEATURES = ChunkStatus.register("features", ChunkStatus.LIQUID_CARVERS, 8, ChunkStatus.POST_FEATURES, ChunkStatus.ChunkType.PROTOCHUNK, (chunkstatus, executor, worldserver, chunkgenerator, structuretemplatemanager, lightenginethreaded, function, list, ichunkaccess, flag) -> {
+        ProtoChunk protochunk = (ProtoChunk) ichunkaccess;
+
+        protochunk.setLightEngine(lightenginethreaded);
+        if (flag || !ichunkaccess.getStatus().isOrAfter(chunkstatus)) {
+            Heightmap.primeHeightmaps(ichunkaccess, EnumSet.of(Heightmap.Types.MOTION_BLOCKING, Heightmap.Types.MOTION_BLOCKING_NO_LEAVES, Heightmap.Types.OCEAN_FLOOR, Heightmap.Types.WORLD_SURFACE));
+            WorldGenRegion regionlimitedworldaccess = new WorldGenRegion(worldserver, list, chunkstatus, 1);
+
+            chunkgenerator.applyBiomeDecoration(regionlimitedworldaccess, ichunkaccess, worldserver.structureManager().forWorldGenRegion(regionlimitedworldaccess));
+            Blender.generateBorderTicks(regionlimitedworldaccess, ichunkaccess);
+            protochunk.setStatus(chunkstatus);
         }
 
-        return lightingProvider.retainData(chunk).thenApply(Either::left);
-    }, (status, world, structureTemplateManager, lightingProvider, fullChunkConverter, chunk) -> {
-        return lightingProvider.retainData(chunk).thenApply(Either::left);
-    });
-    public static final ChunkStatus LIGHT = register("light", FEATURES, 1, POST_FEATURES, ChunkStatus.ChunkType.PROTOCHUNK, (targetStatus, executor, world, generator, structureTemplateManager, lightingProvider, fullChunkConverter, chunks, chunk, regenerate) -> {
-        return lightChunk(targetStatus, lightingProvider, chunk);
-    }, (targetStatus, world, structureTemplateManager, lightingProvider, fullChunkConverter, chunk) -> {
-        return lightChunk(targetStatus, lightingProvider, chunk);
+        return CompletableFuture.completedFuture(Either.left(ichunkaccess)); // Paper - rewrite chunk system
+    }); // Paper - rewrite chunk system
+    public static final ChunkStatus LIGHT = ChunkStatus.register("light", ChunkStatus.FEATURES, 1, ChunkStatus.POST_FEATURES, ChunkStatus.ChunkType.PROTOCHUNK, (chunkstatus, executor, worldserver, chunkgenerator, structuretemplatemanager, lightenginethreaded, function, list, ichunkaccess, flag) -> {
+        return ChunkStatus.lightChunk(chunkstatus, lightenginethreaded, ichunkaccess);
+    }, (chunkstatus, worldserver, structuretemplatemanager, lightenginethreaded, function, ichunkaccess) -> {
+        return ChunkStatus.lightChunk(chunkstatus, lightenginethreaded, ichunkaccess);
     });
-    public static final ChunkStatus SPAWN = registerSimple("spawn", LIGHT, 0, POST_FEATURES, ChunkStatus.ChunkType.PROTOCHUNK, (targetStatus, world, generator, chunks, chunk) -> {
-        if (!chunk.isUpgrading()) {
-            generator.spawnOriginalMobs(new WorldGenRegion(world, chunks, targetStatus, -1));
+    public static final ChunkStatus SPAWN = ChunkStatus.registerSimple("spawn", ChunkStatus.LIGHT, 0, ChunkStatus.POST_FEATURES, ChunkStatus.ChunkType.PROTOCHUNK, (chunkstatus, worldserver, chunkgenerator, list, ichunkaccess) -> {
+        if (!ichunkaccess.isUpgrading()) {
+            chunkgenerator.spawnOriginalMobs(new WorldGenRegion(worldserver, list, chunkstatus, -1));
         }
 
     });
-    public static final ChunkStatus HEIGHTMAPS = registerSimple("heightmaps", SPAWN, 0, POST_FEATURES, ChunkStatus.ChunkType.PROTOCHUNK, (targetStatus, world, generator, chunks, chunk) -> {
+    public static final ChunkStatus HEIGHTMAPS = ChunkStatus.registerSimple("heightmaps", ChunkStatus.SPAWN, 0, ChunkStatus.POST_FEATURES, ChunkStatus.ChunkType.PROTOCHUNK, (chunkstatus, worldserver, chunkgenerator, list, ichunkaccess) -> {
     });
-    public static final ChunkStatus FULL = register("full", HEIGHTMAPS, 0, POST_FEATURES, ChunkStatus.ChunkType.LEVELCHUNK, (targetStatus, executor, world, generator, structureTemplateManager, lightingProvider, fullChunkConverter, chunks, chunk, regenerate) -> {
-        return fullChunkConverter.apply(chunk);
-    }, (targetStatus, world, structureTemplateManager, lightingProvider, fullChunkConverter, chunk) -> {
-        return fullChunkConverter.apply(chunk);
+    public static final ChunkStatus FULL = ChunkStatus.register("full", ChunkStatus.HEIGHTMAPS, 0, ChunkStatus.POST_FEATURES, ChunkStatus.ChunkType.LEVELCHUNK, (chunkstatus, executor, worldserver, chunkgenerator, structuretemplatemanager, lightenginethreaded, function, list, ichunkaccess, flag) -> {
+        return (CompletableFuture) function.apply(ichunkaccess);
+    }, (chunkstatus, worldserver, structuretemplatemanager, lightenginethreaded, function, ichunkaccess) -> {
+        return (CompletableFuture) function.apply(ichunkaccess);
     });
-    private static final List<ChunkStatus> STATUS_BY_RANGE = ImmutableList.of(FULL, FEATURES, LIQUID_CARVERS, BIOMES, STRUCTURE_STARTS, STRUCTURE_STARTS, STRUCTURE_STARTS, STRUCTURE_STARTS, STRUCTURE_STARTS, STRUCTURE_STARTS, STRUCTURE_STARTS, STRUCTURE_STARTS);
-    private static final IntList RANGE_BY_STATUS = Util.make(new IntArrayList(getStatusList().size()), (statusToDistance) -> {
+    private static final List<ChunkStatus> STATUS_BY_RANGE = ImmutableList.of(ChunkStatus.FULL, ChunkStatus.FEATURES, ChunkStatus.LIQUID_CARVERS, ChunkStatus.BIOMES, ChunkStatus.STRUCTURE_STARTS, ChunkStatus.STRUCTURE_STARTS, ChunkStatus.STRUCTURE_STARTS, ChunkStatus.STRUCTURE_STARTS, ChunkStatus.STRUCTURE_STARTS, ChunkStatus.STRUCTURE_STARTS, ChunkStatus.STRUCTURE_STARTS, ChunkStatus.STRUCTURE_STARTS, new ChunkStatus[0]);
+    private static final IntList RANGE_BY_STATUS = (IntList) Util.make(new IntArrayList(ChunkStatus.getStatusList().size()), (intarraylist) -> {
         int i = 0;
 
-        for(int j = getStatusList().size() - 1; j >= 0; --j) {
-            while(i + 1 < STATUS_BY_RANGE.size() && j <= STATUS_BY_RANGE.get(i + 1).getIndex()) {
+        for (int j = ChunkStatus.getStatusList().size() - 1; j >= 0; --j) {
+            while (i + 1 < ChunkStatus.STATUS_BY_RANGE.size() && j <= ((ChunkStatus) ChunkStatus.STATUS_BY_RANGE.get(i + 1)).getIndex()) {
                 ++i;
             }
 
-            statusToDistance.add(0, i);
+            intarraylist.add(0, i);
         }
 
     });
@@ -180,35 +218,37 @@
     private final EnumSet<Heightmap.Types> heightmapsAfter;
 
     private static CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> lightChunk(ChunkStatus status, ThreadedLevelLightEngine lightingProvider, ChunkAccess chunk) {
-        boolean bl = isLighted(status, chunk);
+        boolean flag = ChunkStatus.isLighted(status, chunk);
+
         if (!chunk.getStatus().isOrAfter(status)) {
-            ((ProtoChunk)chunk).setStatus(status);
+            ((ProtoChunk) chunk).setStatus(status);
         }
 
-        return lightingProvider.lightChunk(chunk, bl).thenApply(Either::left);
+        return lightingProvider.lightChunk(chunk, flag).thenApply(Either::left);
     }
 
     private static ChunkStatus registerSimple(String id, @Nullable ChunkStatus previous, int taskMargin, EnumSet<Heightmap.Types> heightMapTypes, ChunkStatus.ChunkType chunkType, ChunkStatus.SimpleGenerationTask task) {
-        return register(id, previous, taskMargin, heightMapTypes, chunkType, task);
+        return ChunkStatus.register(id, previous, taskMargin, heightMapTypes, chunkType, task);
     }
 
     private static ChunkStatus register(String id, @Nullable ChunkStatus previous, int taskMargin, EnumSet<Heightmap.Types> heightMapTypes, ChunkStatus.ChunkType chunkType, ChunkStatus.GenerationTask task) {
-        return register(id, previous, taskMargin, heightMapTypes, chunkType, task, PASSTHROUGH_LOAD_TASK);
+        return ChunkStatus.register(id, previous, taskMargin, heightMapTypes, chunkType, task, ChunkStatus.PASSTHROUGH_LOAD_TASK);
     }
 
     private static ChunkStatus register(String id, @Nullable ChunkStatus previous, int taskMargin, EnumSet<Heightmap.Types> heightMapTypes, ChunkStatus.ChunkType chunkType, ChunkStatus.GenerationTask task, ChunkStatus.LoadingTask loadTask) {
-        return Registry.register(BuiltInRegistries.CHUNK_STATUS, id, new ChunkStatus(id, previous, taskMargin, heightMapTypes, chunkType, task, loadTask));
+        return (ChunkStatus) Registry.register(BuiltInRegistries.CHUNK_STATUS, id, new ChunkStatus(id, previous, taskMargin, heightMapTypes, chunkType, task, loadTask));
     }
 
     public static List<ChunkStatus> getStatusList() {
         List<ChunkStatus> list = Lists.newArrayList();
 
-        ChunkStatus chunkStatus;
-        for(chunkStatus = FULL; chunkStatus.getParent() != chunkStatus; chunkStatus = chunkStatus.getParent()) {
-            list.add(chunkStatus);
+        ChunkStatus chunkstatus;
+
+        for (chunkstatus = ChunkStatus.FULL; chunkstatus.getParent() != chunkstatus; chunkstatus = chunkstatus.getParent()) {
+            list.add(chunkstatus);
         }
 
-        list.add(chunkStatus);
+        list.add(chunkstatus);
         Collections.reverse(list);
         return list;
     }
@@ -218,19 +258,15 @@
     }
 
     public static ChunkStatus getStatusAroundFullChunk(int level) {
-        if (level >= STATUS_BY_RANGE.size()) {
-            return EMPTY;
-        } else {
-            return level < 0 ? FULL : STATUS_BY_RANGE.get(level);
-        }
+        return level >= ChunkStatus.STATUS_BY_RANGE.size() ? ChunkStatus.EMPTY : (level < 0 ? ChunkStatus.FULL : (ChunkStatus) ChunkStatus.STATUS_BY_RANGE.get(level));
     }
 
     public static int maxDistance() {
-        return STATUS_BY_RANGE.size();
+        return ChunkStatus.STATUS_BY_RANGE.size();
     }
 
     public static int getDistance(ChunkStatus status) {
-        return RANGE_BY_STATUS.getInt(status.getIndex());
+        return ChunkStatus.RANGE_BY_STATUS.getInt(status.getIndex());
     }
 
     ChunkStatus(String id, @Nullable ChunkStatus previous, int taskMargin, EnumSet<Heightmap.Types> heightMapTypes, ChunkStatus.ChunkType chunkType, ChunkStatus.GenerationTask generationTask, ChunkStatus.LoadingTask loadTask) {
@@ -242,6 +278,13 @@
         this.chunkType = chunkType;
         this.heightmapsAfter = heightMapTypes;
         this.index = previous == null ? 0 : previous.getIndex() + 1;
+        // Paper start
+        this.nextStatus = this;
+        if (statuses.size() > 0) {
+            statuses.get(statuses.size() - 1).nextStatus = this;
+        }
+        statuses.add(this);
+        // Paper end
     }
 
     public int getIndex() {
@@ -257,13 +300,14 @@
     }
 
     public CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> generate(Executor executor, ServerLevel world, ChunkGenerator generator, StructureTemplateManager structureTemplateManager, ThreadedLevelLightEngine lightingProvider, Function<ChunkAccess, CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>>> fullChunkConverter, List<ChunkAccess> chunks, boolean regenerate) {
-        ChunkAccess chunkAccess = chunks.get(chunks.size() / 2);
-        ProfiledDuration profiledDuration = JvmProfiler.INSTANCE.onChunkGenerate(chunkAccess.getPos(), world.dimension(), this.name);
-        CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> completableFuture = this.generationTask.doWork(this, executor, world, generator, structureTemplateManager, lightingProvider, fullChunkConverter, chunks, chunkAccess, regenerate);
-        return profiledDuration != null ? completableFuture.thenApply((either) -> {
-            profiledDuration.finish();
+        ChunkAccess ichunkaccess = (ChunkAccess) chunks.get(chunks.size() / 2);
+        ProfiledDuration profiledduration = JvmProfiler.INSTANCE.onChunkGenerate(ichunkaccess.getPos(), world.dimension(), this.name);
+        CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> completablefuture = this.generationTask.doWork(this, executor, world, generator, structureTemplateManager, lightingProvider, fullChunkConverter, chunks, ichunkaccess, regenerate);
+
+        return profiledduration != null ? completablefuture.thenApply((either) -> {
+            profiledduration.finish();
             return either;
-        }) : completableFuture;
+        }) : completablefuture;
     }
 
     public CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> load(ServerLevel world, StructureTemplateManager structureTemplateManager, ThreadedLevelLightEngine lightingProvider, Function<ChunkAccess, CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>>> fullChunkConverter, ChunkAccess chunk) {
@@ -278,8 +322,19 @@
         return this.chunkType;
     }
 
+    // Paper start
+    public static ChunkStatus getStatus(String name) {
+        try {
+            // We need this otherwise we return EMPTY for invalid names
+            ResourceLocation key = new ResourceLocation(name);
+            return BuiltInRegistries.CHUNK_STATUS.getOptional(key).orElse(null);
+        } catch (Exception ex) {
+            return null; // invalid name
+        }
+    }
+    // Paper end
     public static ChunkStatus byName(String id) {
-        return BuiltInRegistries.CHUNK_STATUS.get(ResourceLocation.tryParse(id));
+        return (ChunkStatus) BuiltInRegistries.CHUNK_STATUS.get(ResourceLocation.tryParse(id));
     }
 
     public EnumSet<Heightmap.Types> heightmapsAfter() {
@@ -290,32 +345,37 @@
         return this.getIndex() >= chunkStatus.getIndex();
     }
 
-    @Override
     public String toString() {
         return BuiltInRegistries.CHUNK_STATUS.getKey(this).toString();
     }
 
     public static enum ChunkType {
-        PROTOCHUNK,
-        LEVELCHUNK;
+
+        PROTOCHUNK, LEVELCHUNK;
+
+        private ChunkType() {}
     }
 
-    interface GenerationTask {
+    private interface GenerationTask {
+
         CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> doWork(ChunkStatus targetStatus, Executor executor, ServerLevel world, ChunkGenerator generator, StructureTemplateManager structureTemplateManager, ThreadedLevelLightEngine lightingProvider, Function<ChunkAccess, CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>>> fullChunkConverter, List<ChunkAccess> chunks, ChunkAccess chunk, boolean regenerate);
     }
 
-    interface LoadingTask {
+    private interface LoadingTask {
+
         CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> doWork(ChunkStatus targetStatus, ServerLevel world, StructureTemplateManager structureTemplateManager, ThreadedLevelLightEngine lightingProvider, Function<ChunkAccess, CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>>> fullChunkConverter, ChunkAccess chunk);
     }
 
-    interface SimpleGenerationTask extends ChunkStatus.GenerationTask {
+    private interface SimpleGenerationTask extends ChunkStatus.GenerationTask {
+
         @Override
         default CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>> doWork(ChunkStatus targetStatus, Executor executor, ServerLevel world, ChunkGenerator generator, StructureTemplateManager structureTemplateManager, ThreadedLevelLightEngine lightingProvider, Function<ChunkAccess, CompletableFuture<Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure>>> fullChunkConverter, List<ChunkAccess> chunks, ChunkAccess chunk, boolean regenerate) {
             if (regenerate || !chunk.getStatus().isOrAfter(targetStatus)) {
                 this.doWork(targetStatus, world, generator, chunks, chunk);
                 if (chunk instanceof ProtoChunk) {
-                    ProtoChunk protoChunk = (ProtoChunk)chunk;
-                    protoChunk.setStatus(targetStatus);
+                    ProtoChunk protochunk = (ProtoChunk) chunk;
+
+                    protochunk.setStatus(targetStatus);
                 }
             }
 
