private BufferedImage getCroppedImage( String innerPath, int x, int y, int w, int h) {
		Rectangle keyRect = new Rectangle( x, y, w, h );
		BufferedImage result = null;
		HashMap<Rectangle, BufferedImage> cacheMap = cachedImages.get(innerPath);
		if ( cacheMap != null ) result = cacheMap.get(keyRect);
		if (result != null) return result;
		log.trace( "Image not in cache, loading and cropping...: "+ innerPath );

		InputStream in = null;
		try {
			in = DataManager.get().getResourceInputStream( innerPath );
			BufferedImage bigImage = ImageIO.read(in);
			result = bigImage.getSubimage(x, y, w, h);

		} catch (RasterFormatException e) {
			log.error( "Failed to load and crop image: "+ innerPath, e );
		} catch (IOException e) {
			log.error( "Failed to load and crop image: "+ innerPath, e );
		} finally {
			try {if (in != null) in.close();}
			catch (IOException f) {}
		}

		if ( result == null ) {  // Guarantee a returned image, with a stand-in.
			result = gc.createCompatibleImage( w, h, Transparency.OPAQUE );
			Graphics2D g2d = (Graphics2D)result.createGraphics();
			g2d.setColor( new Color(150, 150, 200) );
			g2d.fillRect( 0, 0, w-1, h-1 );
			g2d.dispose();
		}

		if ( cacheMap == null ) {
			cacheMap = new HashMap<Rectangle, BufferedImage>();
			cachedImages.put( innerPath, cacheMap );
		}
		cacheMap.put( keyRect, result );

		return result;
	}