private void writeIFDs(List<TiffIFDEntry> ifds) throws IOException {
    long offset = this.theChannel.position();

    // This is supposed to start on a word boundary, via decree of the spec.
    long adjust = offset % 4L;
    offset += (adjust == 0) ? 0 : (4L - adjust);

    this.theChannel.position(offset);

    Collections.sort(ifds);

    ByteBuffer dataBuff = ByteBuffer.allocateDirect(ifds.size() * 12);

    // The IFD directory is preceeded by a SHORT count of the number of entries...
    putUnsignedShort(dataBuff, ifds.size());
    dataBuff.flip();
    this.theChannel.write(dataBuff);

    dataBuff.clear();
    for (TiffIFDEntry ifd : ifds) {
      putUnsignedShort(dataBuff, ifd.tag);
      putUnsignedShort(dataBuff, ifd.type);
      putUnsignedInt(dataBuff, ifd.count);
      if (ifd.type == Tiff.Type.SHORT && ifd.count == 1) {
        // these get packed in the first few bytes...
        putUnsignedShort(dataBuff, (int) ifd.valOffset);
        dataBuff.putShort((short) 0);
      } else putUnsignedInt(dataBuff, ifd.valOffset);
    }
    dataBuff.flip();
    this.theChannel.write(dataBuff);

    // The spec requires 4 bytes of zeros at the end...
    dataBuff.clear();
    dataBuff.putInt(0);
    dataBuff.flip();
    this.theChannel.write(dataBuff);

    // go back and patch up the ifd offset in header...
    this.theChannel.position(4);
    dataBuff.clear();
    putUnsignedInt(dataBuff, offset);
    dataBuff.flip();
    this.theChannel.write(dataBuff);
  }
  private void addTileOrDescendands(MeshTile tile, List<MeshTile> tileList) {
    if (!tile.getSector().intersects(this.levelSet.getSector())) return;

    if (tile.getLevelNumber() == this.visibleLevel) {
      tileList.add(tile);
      return;
    }

    if (this.levelSet.isFinalLevel(tile.getLevelNumber())) {
      return;
    }

    MeshTile[] subTiles = tile.subdivide(this.levelSet.getLevel(tile.getLevelNumber() + 1));
    for (MeshTile subTile : subTiles) {
      addTileOrDescendands(subTile, tileList);
    }
  }