public Chunk getOrCreateChunk(int x, int z) {
    random.setSeed((long) x * 341873128712L + (long) z * 132897987541L);

    Chunk chunk;

    // Get default biome data for chunk
    CustomBiomeGrid biomegrid = new CustomBiomeGrid();
    biomegrid.biome = new BiomeGenBase[256];
    world.getWorldChunkManager().getBiomeGenAt(biomegrid.biome, x << 4, z << 4, 16, 16, false);

    // Try extended block method (1.2+)
    short[][] xbtypes =
        generator.generateExtBlockSections(
            CraftServer.instance().getWorld(world.provider.dimensionId),
            this.random,
            x,
            z,
            biomegrid);
    if (xbtypes != null) {
      chunk = new Chunk(this.world, x, z);

      ExtendedBlockStorage[] csect = chunk.getBlockStorageArray();
      int scnt = Math.min(csect.length, xbtypes.length);

      // Loop through returned sections
      for (int sec = 0; sec < scnt; sec++) {
        if (xbtypes[sec] == null) {
          continue;
        }
        byte[] secBlkID = new byte[4096]; // Allocate blk ID bytes
        byte[] secExtBlkID = (byte[]) null; // Delay getting extended ID nibbles
        short[] bdata = xbtypes[sec];
        // Loop through data, 2 blocks at a time
        for (int i = 0, j = 0; i < bdata.length; i += 2, j++) {
          short b1 = bdata[i];
          short b2 = bdata[i + 1];
          byte extb = (byte) ((b1 >> 8) | ((b2 >> 4) & 0xF0));

          secBlkID[i] = (byte) b1;
          secBlkID[(i + 1)] = (byte) b2;

          if (extb != 0) { // If extended block ID data
            if (secExtBlkID == null) { // Allocate if needed
              secExtBlkID = new byte[2048];
            }
            secExtBlkID[j] = extb;
          }
        }
        // Build chunk section
        csect[sec] = new ExtendedBlockStorage(sec << 4, false); // , secBlkID, secExtBlkID);
      }
    } else { // Else check for byte-per-block section data
      byte[][] btypes =
          generator.generateBlockSections(getWorld(world), this.random, x, z, biomegrid);

      if (btypes != null) {
        chunk = new Chunk(this.world, x, z);

        ExtendedBlockStorage[] csect = chunk.getBlockStorageArray();
        int scnt = Math.min(csect.length, btypes.length);

        for (int sec = 0; sec < scnt; sec++) {
          if (btypes[sec] == null) {
            continue;
          }
          csect[sec] = new ExtendedBlockStorage(sec << 4, false); // , btypes[sec], null);
        }
      } else { // Else, fall back to pre 1.2 method
        @SuppressWarnings("deprecation")
        byte[] types = generator.generate(getWorld(world), this.random, x, z);
        int ydim = types.length / 256;
        int scnt = ydim / 16;

        chunk = new Chunk(this.world, x, z); // Create empty chunk

        ExtendedBlockStorage[] csect = chunk.getBlockStorageArray();

        scnt = Math.min(scnt, csect.length);
        // Loop through sections
        for (int sec = 0; sec < scnt; sec++) {
          ExtendedBlockStorage cs = null; // Add sections when needed
          byte[] csbytes = (byte[]) null;

          for (int cy = 0; cy < 16; cy++) {
            int cyoff = cy | (sec << 4);

            for (int cx = 0; cx < 16; cx++) {
              int cxyoff = (cx * ydim * 16) + cyoff;

              for (int cz = 0; cz < 16; cz++) {
                byte blk = types[cxyoff + (cz * ydim)];

                if (blk != 0) { // If non-empty
                  if (cs == null) { // If no section yet, get one
                    cs = csect[sec] = new ExtendedBlockStorage(sec << 4, true);
                    csbytes = cs.getBlockLSBArray();
                  }
                  csbytes[(cy << 8) | (cz << 4) | cx] = blk;
                }
              }
            }
          }
          // If section built, finish prepping its state
          if (cs != null) {
            cs.getYLocation();
          }
        }
      }
    }
    // Set biome grid
    byte[] biomeIndex = chunk.getBiomeArray();
    for (int i = 0; i < biomeIndex.length; i++) {
      biomeIndex[i] = (byte) (biomegrid.biome[i].biomeID & 0xFF);
    }
    // Initialize lighting
    chunk.generateSkylightMap();

    return chunk;
  }