@SubscribeEvent
  public void onWorldTick(WorldTickEvent event) {
    if (event.phase == Phase.START) {
      final WorldServer world = (WorldServer) event.world;

      CopyOnWriteArrayList<ScheduledBlockChange> changeList =
          TickHandlerServer.scheduledBlockChanges.get(world.provider.dimensionId);

      if (changeList != null && !changeList.isEmpty()) {
        int blockCount = 0;
        int blockCountMax = Math.max(this.MAX_BLOCKS_PER_TICK, changeList.size() / 4);
        List<ScheduledBlockChange> newList =
            new ArrayList<ScheduledBlockChange>(Math.max(0, changeList.size() - blockCountMax));

        for (ScheduledBlockChange change : changeList) {
          if (++blockCount > blockCountMax) {
            newList.add(change);
          } else {
            if (change != null) {
              BlockVec3 changePosition = change.getChangePosition();
              Block block = world.getBlock(changePosition.x, changePosition.y, changePosition.z);
              // Only replace blocks of type BlockAir or fire - this is to prevent accidents where
              // other mods have moved blocks
              if (changePosition != null && (block instanceof BlockAir || block == Blocks.fire)) {
                world.setBlock(
                    changePosition.x,
                    changePosition.y,
                    changePosition.z,
                    change.getChangeID(),
                    change.getChangeMeta(),
                    change.getChangeUpdateFlag());
              }
            }
          }
        }

        changeList.clear();
        TickHandlerServer.scheduledBlockChanges.remove(world.provider.dimensionId);
        if (newList.size() > 0)
          TickHandlerServer.scheduledBlockChanges.put(
              world.provider.dimensionId, new CopyOnWriteArrayList<ScheduledBlockChange>(newList));
      }

      CopyOnWriteArrayList<BlockVec3> torchList =
          TickHandlerServer.scheduledTorchUpdates.get(world.provider.dimensionId);

      if (torchList != null && !torchList.isEmpty()) {
        for (BlockVec3 torch : torchList) {
          if (torch != null) {
            Block b = world.getBlock(torch.x, torch.y, torch.z);
            if (b instanceof BlockUnlitTorch) {
              world.scheduleBlockUpdateWithPriority(
                  torch.x, torch.y, torch.z, b, 2 + world.rand.nextInt(30), 0);
            }
          }
        }

        torchList.clear();
        TickHandlerServer.scheduledTorchUpdates.remove(world.provider.dimensionId);
      }

      if (world.provider instanceof IOrbitDimension) {
        final Object[] entityList = world.loadedEntityList.toArray();

        for (final Object o : entityList) {
          if (o instanceof Entity) {
            final Entity e = (Entity) o;

            if (e.worldObj.provider instanceof IOrbitDimension) {
              final IOrbitDimension dimension = (IOrbitDimension) e.worldObj.provider;

              if (e.posY <= dimension.getYCoordToTeleportToPlanet()) {
                final Integer dim =
                    WorldUtil.getProviderForName(dimension.getPlanetToOrbit()).dimensionId;

                WorldUtil.transferEntityToDimension(e, dim, world, false, null);
              }
            }
          }
        }
      }
    } else if (event.phase == Phase.END) {
      final WorldServer world = (WorldServer) event.world;

      List<BlockVec3> edgesList = TickHandlerServer.edgeChecks.get(world.provider.dimensionId);
      final HashSet<BlockVec3> checkedThisTick = new HashSet();

      if (edgesList != null && !edgesList.isEmpty()) {
        List<BlockVec3> edgesListCopy = new ArrayList();
        edgesListCopy.addAll(edgesList);
        for (BlockVec3 edgeBlock : edgesListCopy) {
          if (edgeBlock != null && !checkedThisTick.contains(edgeBlock)) {
            if (TickHandlerServer.scheduledForChange(world.provider.dimensionId, edgeBlock)) {
              continue;
            }

            ThreadFindSeal done =
                new ThreadFindSeal(world, edgeBlock, 2000, new ArrayList<TileEntityOxygenSealer>());
            checkedThisTick.addAll(done.checked);
          }
        }

        TickHandlerServer.edgeChecks.remove(world.provider.dimensionId);
      }
    }
  }
  @SubscribeEvent
  public void onWorldTick(WorldTickEvent event) {
    if (event.phase == Phase.START) {
      final WorldServer world = (WorldServer) event.world;

      CopyOnWriteArrayList<ScheduledBlockChange> changeList =
          TickHandlerServer.scheduledBlockChanges.get(world.provider.dimensionId);

      if (changeList != null && !changeList.isEmpty()) {
        for (ScheduledBlockChange change : changeList) {
          if (change != null) {
            BlockVec3 changePosition = change.getChangePosition();
            if (changePosition != null) {
              world.setBlock(
                  changePosition.x,
                  changePosition.y,
                  changePosition.z,
                  change.getChangeID(),
                  change.getChangeMeta(),
                  2);
            }
          }
        }

        changeList.clear();
        TickHandlerServer.scheduledBlockChanges.remove(world.provider.dimensionId);
      }

      CopyOnWriteArrayList<BlockVec3> torchList =
          TickHandlerServer.scheduledTorchUpdates.get(world.provider.dimensionId);

      if (torchList != null && !torchList.isEmpty()) {
        for (BlockVec3 torch : torchList) {
          if (torch != null) {
            if (world.getBlock(torch.x, torch.y, torch.z) == GCBlocks.unlitTorch) {
              world.scheduleBlockUpdateWithPriority(
                  torch.x, torch.y, torch.z, GCBlocks.unlitTorch, 2 + world.rand.nextInt(30), 0);
            } else if (world.getBlock(torch.x, torch.y, torch.z) == GCBlocks.unlitTorchLit) {
              world.scheduleBlockUpdateWithPriority(
                  torch.x, torch.y, torch.z, GCBlocks.unlitTorchLit, 2 + world.rand.nextInt(30), 0);
            }
          }
        }

        torchList.clear();
        TickHandlerServer.scheduledTorchUpdates.remove(world.provider.dimensionId);
      }

      if (world.provider instanceof IOrbitDimension) {
        final Object[] entityList = world.loadedEntityList.toArray();

        for (final Object o : entityList) {
          if (o instanceof Entity) {
            final Entity e = (Entity) o;

            if (e.worldObj.provider instanceof IOrbitDimension) {
              final IOrbitDimension dimension = (IOrbitDimension) e.worldObj.provider;

              if (e.posY <= dimension.getYCoordToTeleportToPlanet()) {
                final Integer dim =
                    WorldUtil.getProviderForName(dimension.getPlanetToOrbit()).dimensionId;

                WorldUtil.transferEntityToDimension(e, dim, world, false, null);
              }
            }
          }
        }
      }
    } else if (event.phase == Phase.END) {
      final WorldServer world = (WorldServer) event.world;

      List<BlockVec3> edgesList = TickHandlerServer.edgeChecks.get(world.provider.dimensionId);
      final HashSet<BlockVec3> checkedThisTick = new HashSet();

      if (edgesList != null && !edgesList.isEmpty()) {
        List<BlockVec3> edgesListCopy = new ArrayList();
        edgesListCopy.addAll(edgesList);
        for (BlockVec3 edgeBlock : edgesListCopy) {
          if (edgeBlock != null && !checkedThisTick.contains(edgeBlock)) {
            if (TickHandlerServer.scheduledForChange(world.provider.dimensionId, edgeBlock)) {
              continue;
            }

            ThreadFindSeal done =
                new ThreadFindSeal(world, edgeBlock, 2000, new ArrayList<TileEntityOxygenSealer>());
            checkedThisTick.addAll(done.checked);
          }
        }

        TickHandlerServer.edgeChecks.remove(world.provider.dimensionId);
      }
    }
  }