docs: private void readHeader() throws IOException {
  		final RandomAccessFile baseFile = mFiles.get(0);
  
  		// Get file sizes
  		for (final RandomAccessFile file : mFiles) {
  			mFileSizes.add(file.length());
  		}
  
  		// Version
  		final int version = baseFile.readInt();
  		if (version != VERSION) {
  			throw new IOException("Bad file version: " + version);
  		}
  
  		// Tile Size
  		final int tile_size = baseFile.readInt();
  		if (tile_size != TILE_SIZE) {
  			throw new IOException("Bad tile size: " + tile_size);
  		}
  
  		// Read Source List
  		final int sourceCount = baseFile.readInt();
  
  		for (int i=0;i<sourceCount;i++) {
  			final int sourceIndex = baseFile.readInt();
  			final int sourceNameLength = baseFile.readInt();
  			final byte[] nameData = new byte[sourceNameLength];
  			baseFile.read(nameData, 0, sourceNameLength);
  
  			final String sourceName = new String(nameData);
  			mSources.put(new Integer(sourceIndex), sourceName);
  		}
  
  		// Read Ranges
  		final int num_ranges = baseFile.readInt();
  		for (int i=0;i<num_ranges;i++) {
  			final GEMFRange rs = new GEMFRange();
  			rs.zoom = baseFile.readInt();
  			rs.xMin = baseFile.readInt();
  			rs.xMax = baseFile.readInt();
  			rs.yMin = baseFile.readInt();
  			rs.yMax = baseFile.readInt();
  			rs.sourceIndex = baseFile.readInt();
  			rs.offset = baseFile.readLong();
  			mRangeData.add(rs);
  		}
  	}