shapeFilename = filename;
	public ShapefileDataset(String filename, String extras)		throws FileNotFoundException, IOException, MapyrusException	{		String shapeFilename, dbfFilename, prjFilename;		StringTokenizer st, st2;		String token, s;		HashSet extrasDBFFields;		double d, xMin, yMin, xMax, yMax;		/*		 * Set default options.  Then see if user wants to override any of them.		 */		extrasDBFFields = null;		xMin = yMin = -Float.MAX_VALUE;		xMax = yMax = Float.MAX_VALUE;		st = new StringTokenizer(extras);		while (st.hasMoreTokens())		{			token = st.nextToken();			if (token.startsWith("dbffields="))			{				/*				 * Parse list of comma separated field names that user wants				 * to fetch.				 */				extrasDBFFields = new HashSet();				st2 = new StringTokenizer(token.substring(10), ",");				while (st2.hasMoreTokens())				{					token = st2.nextToken();					extrasDBFFields.add(token);				}			}			else if (token.startsWith("xmin=") || token.startsWith("ymin=") ||				token.startsWith("xmax=") || token.startsWith("ymax="))			{				s = token.substring(5);				try				{					d = Double.parseDouble(s);				}				catch (NumberFormatException e)				{					throw new MapyrusException(MapyrusMessages.get(MapyrusMessages.INVALID_NUMBER) +						": " + s);				}				if (token.startsWith("xmin="))					xMin = d;				else if (token.startsWith("ymin="))					yMin = d;				else if (token.startsWith("xmax="))					xMax = d;				else					yMax = d;			}		}		mQueryExtents = new Rectangle2D.Double(xMin, yMin, xMax - xMin, yMax - yMin);		/*		 * Determine full names of .shp and .dbf files.		 */		if (filename.endsWith(".shp"))		{			shapeFilename = filename;			mFilename = filename.substring(0, filename.length() - 4);			dbfFilename = mFilename + ".dbf";			prjFilename = mFilename + ".prj";		}		else if (filename.endsWith(".SHP"))		{			shapeFilename = filename;			mFilename = filename.substring(0, filename.length() - 4);			dbfFilename = mFilename + ".DBF";			prjFilename = mFilename + ".PRJ";		}		else		{			mFilename = filename;			shapeFilename = filename + ".shp";			dbfFilename = filename + ".dbf";			prjFilename = filename + ".prj";		}					mShapeStream = new DataInputStream(new BufferedInputStream(new FileInputStream(shapeFilename)));		try		{			mDBFStream = new DataInputStream(new BufferedInputStream(new FileInputStream(dbfFilename)));		}		catch (FileNotFoundException e)		{			/*			 * If .dbf file does not exist then just continue without it.			 */			mDBFStream = null;		}		/*		 * If there is an accompanying .prj file with the projection then read it.		 */		BufferedReader prjReader = null;		try		{			prjReader = new BufferedReader(new FileReader(prjFilename));			mProjection = prjReader.readLine();		}		catch(FileNotFoundException e)		{			mProjection = "";		}		finally		{			if (prjReader != null)				prjReader.close();		}		try		{			/*			 * Read shape header, checking magic number and reading everything with			 * correct byte order.			 */			readShapeHeader();			/*			 * Read header from database file to get names and types of other fields.			 */			readDBFHeader(extrasDBFFields);			if (mQueryExtents.intersects(mExtents))			{				mBytesRead = 0;				mDBFRecord = new byte[mDBFRecordLength];			}			else			{				/*				 * Shape file does not overlap current extents.  Fetch will return nothing.				 */				mBytesRead = mShapeFileLength;			}		}		catch (IOException e1)		{			close();			throw e1;		}		catch (MapyrusException e2)		{			close();			throw e2;		}	}