Index: trunk/src/org/openstreetmap/josm/Main.java
===================================================================
--- trunk/src/org/openstreetmap/josm/Main.java	(revision 527)
+++ trunk/src/org/openstreetmap/josm/Main.java	(revision 529)
@@ -122,4 +122,13 @@
 	public final MainMenu menu;
 
+	/**
+	 * Print a debug message if debugging is on.
+	 */
+	static public int debug_level = 1;
+	static public final void debug(String msg) {
+		if (debug_level <= 0)
+			return;
+		System.out.println(msg);
+	}
 
 	/**
Index: trunk/src/org/openstreetmap/josm/actions/CombineWayAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/CombineWayAction.java	(revision 527)
+++ trunk/src/org/openstreetmap/josm/actions/CombineWayAction.java	(revision 529)
@@ -38,4 +38,5 @@
 import org.openstreetmap.josm.data.osm.Way;
 import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.TigerUtils;
 import org.openstreetmap.josm.tools.Pair;
 import org.openstreetmap.josm.tools.GBC;
@@ -158,5 +159,8 @@
 		JPanel p = new JPanel(new GridBagLayout());
 		for (Entry<String, Set<String>> e : props.entrySet()) {
-			if (e.getValue().size() > 1) {
+			if (TigerUtils.isTigerTag(e.getKey())) {
+				String combined = TigerUtils.combineTags(e.getKey(), e.getValue());
+				newWay.put(e.getKey(), combined);
+			} else if (e.getValue().size() > 1) {
 				JComboBox c = new JComboBox(e.getValue().toArray());
 				c.setEditable(true);
@@ -219,22 +223,7 @@
 
 		HashSet<Pair<Node,Node>> chunkSet = new HashSet<Pair<Node,Node>>();
-		for (Way w : ways) {
-			if (w.nodes.size() == 0) continue;
-			Node lastN = null;
-			for (Node n : w.nodes) {
-				if (lastN == null) {
-					lastN = n;
-					continue;
-				}
-
-				Pair<Node,Node> np = new Pair<Node,Node>(lastN, n);
-				if (ignoreDirection) {
-					Pair.sort(np);
-				}
-				chunkSet.add(np);
-
-				lastN = n;
-			}
-		}
+		for (Way w : ways)
+			chunkSet.addAll(w.getNodePairs(ignoreDirection));
+
 		LinkedList<Pair<Node,Node>> chunks = new LinkedList<Pair<Node,Node>>(chunkSet);
 
Index: trunk/src/org/openstreetmap/josm/actions/MergeNodesAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/MergeNodesAction.java	(revision 527)
+++ trunk/src/org/openstreetmap/josm/actions/MergeNodesAction.java	(revision 529)
@@ -38,4 +38,5 @@
 import org.openstreetmap.josm.data.osm.Way;
 import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.data.osm.TigerUtils;
 import org.openstreetmap.josm.tools.Pair;
 import org.openstreetmap.josm.data.osm.visitor.CollectBackReferencesVisitor;
@@ -170,5 +171,8 @@
 		JPanel p = new JPanel(new GridBagLayout());
 		for (Entry<String, Set<String>> e : props.entrySet()) {
-			if (e.getValue().size() > 1) {
+			if (TigerUtils.isTigerTag(e.getKey())) {
+				String combined = TigerUtils.combineTags(e.getKey(), e.getValue());
+				newNode.put(e.getKey(), combined);
+			} else if (e.getValue().size() > 1) {
 				JComboBox c = new JComboBox(e.getValue().toArray());
 				c.setEditable(true);
Index: trunk/src/org/openstreetmap/josm/actions/OpenAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/OpenAction.java	(revision 527)
+++ trunk/src/org/openstreetmap/josm/actions/OpenAction.java	(revision 529)
@@ -10,8 +10,5 @@
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
-import java.io.FileReader;
 import java.io.IOException;
-import java.util.Collection;
-import java.util.LinkedList;
 import java.util.zip.GZIPInputStream;
 
@@ -23,5 +20,4 @@
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
 import org.openstreetmap.josm.gui.layer.GpxLayer;
-import org.openstreetmap.josm.gui.layer.markerlayer.Marker;
 import org.openstreetmap.josm.gui.layer.markerlayer.MarkerLayer;
 import org.openstreetmap.josm.io.OsmReader;
Index: trunk/src/org/openstreetmap/josm/actions/SplitWayAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/SplitWayAction.java	(revision 527)
+++ trunk/src/org/openstreetmap/josm/actions/SplitWayAction.java	(revision 529)
@@ -217,4 +217,6 @@
 			return;
 		}
+		Main.debug("wayChunks.size(): " + wayChunks.size());
+		Main.debug("way id: " + selectedWay.id);
 
 		// build a list of commands, and also a new selection list
@@ -240,4 +242,5 @@
 			wayToAdd.nodes.addAll(chunkIt.next());
 			commandList.add(new AddCommand(wayToAdd));
+			Main.debug("wayToAdd: " + wayToAdd);
 			newSelection.add(wayToAdd);
 		}
Index: trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadGpsTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadGpsTask.java	(revision 527)
+++ trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadGpsTask.java	(revision 529)
@@ -5,5 +5,4 @@
 
 import java.io.IOException;
-import java.util.Collection;
 
 import javax.swing.JCheckBox;
Index: trunk/src/org/openstreetmap/josm/actions/mapmode/DeleteAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/mapmode/DeleteAction.java	(revision 527)
+++ trunk/src/org/openstreetmap/josm/actions/mapmode/DeleteAction.java	(revision 529)
@@ -8,5 +8,4 @@
 import java.awt.event.MouseEvent;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
@@ -15,14 +14,9 @@
 import java.util.LinkedList;
 import java.util.List;
-import java.util.Map.Entry;
 
 import javax.swing.JOptionPane;
 
 import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.command.AddCommand;
-import org.openstreetmap.josm.command.ChangeCommand;
-import org.openstreetmap.josm.command.Command;
-import org.openstreetmap.josm.command.DeleteCommand;
-import org.openstreetmap.josm.command.SequenceCommand;
+import org.openstreetmap.josm.command.*;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
@@ -32,5 +26,5 @@
 import org.openstreetmap.josm.data.osm.visitor.CollectBackReferencesVisitor;
 import org.openstreetmap.josm.gui.MapFrame;
-import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.*;
 
 /**
Index: trunk/src/org/openstreetmap/josm/data/Bounds.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/Bounds.java	(revision 527)
+++ trunk/src/org/openstreetmap/josm/data/Bounds.java	(revision 529)
@@ -59,3 +59,13 @@
 			max = new LatLon(Math.max(ll.lat(), max.lat()), Math.max(ll.lon(), max.lon()));
 	}
+	/**
+	 * Is the given point within this bounds?
+	 */
+	public boolean contains(LatLon ll) {
+		if (ll.lat() < min.lat() || ll.lon() < min.lon())
+			return false;
+		if (ll.lat() > max.lat() || ll.lon() > max.lon())
+			return false;
+		return true;
+	}
 }
Index: trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(revision 527)
+++ trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(revision 529)
@@ -4,5 +4,4 @@
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
-import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
Index: trunk/src/org/openstreetmap/josm/data/osm/TigerUtils.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/TigerUtils.java	(revision 529)
+++ trunk/src/org/openstreetmap/josm/data/osm/TigerUtils.java	(revision 529)
@@ -0,0 +1,51 @@
+// License: GPL. Copyright 2007 by Dave Hansen and others
+package org.openstreetmap.josm.data.osm;
+
+import java.util.Set;
+import java.util.TreeSet;
+
+/** 
+ * A simple class to keep helper functions for merging TIGER data
+ * 
+ * @author daveh
+ *
+ */
+public class TigerUtils {
+	public static boolean isTigerTag(String tag)
+	{	
+		if (tag.indexOf("tiger:") == -1)
+			return false;
+		return true;
+	}
+	public static boolean tagIsInt(String name) {
+		if (name.equals("tiger:tlid"))
+			return true;
+		return false;
+	}
+	public static Object tagObj(String name) {
+		if (tagIsInt(name))
+			return new Integer(name);
+		return name;
+	}
+	public static String combineTags(String name, Set<String> values) {
+        TreeSet resultSet = new TreeSet();
+        for (String value: values) {
+        	for (String part: value.split(":")) {
+               resultSet.add(tagObj(part));
+            }
+        }
+        String combined = "";
+        for (Object part : resultSet) {
+            if (combined.length() > 0)
+        		combined += ":";
+        	combined += part;
+        }
+		return combined;
+	}
+	public static String combineTags(String name, String t1, String t2) {
+		Set<String> set = new TreeSet<String>();
+		set.add(t1);
+		set.add(t2);
+		return TigerUtils.combineTags(name, set);
+	}
+}
Index: trunk/src/org/openstreetmap/josm/data/osm/Way.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/Way.java	(revision 527)
+++ trunk/src/org/openstreetmap/josm/data/osm/Way.java	(revision 529)
@@ -7,4 +7,5 @@
 
 import org.openstreetmap.josm.data.osm.visitor.Visitor;
+import org.openstreetmap.josm.tools.Pair;
 
 /**
@@ -19,4 +20,28 @@
 	 */
 	public final List<Node> nodes = new ArrayList<Node>();
+
+	public void visitNodes(Visitor v) {
+		for (Node n : this.nodes)
+			v.visit(n);
+	}
+
+	public ArrayList<Pair<Node,Node>> getNodePairs(boolean sort) {
+		ArrayList<Pair<Node,Node>> chunkSet = new ArrayList<Pair<Node,Node>>();
+		Node lastN = null;
+		for (Node n : this.nodes) {
+            if (lastN == null) {
+        	    lastN = n;
+           		continue;
+	   	    }
+			Pair<Node,Node> np = new Pair<Node,Node>(lastN, n);
+           	if (sort) {
+           		Pair.sort(np);
+           	}
+           	chunkSet.add(np);
+	        lastN = n;
+		}
+		return chunkSet;
+	}
+
 
 	@Override public void visit(Visitor visitor) {
Index: trunk/src/org/openstreetmap/josm/data/osm/visitor/AllNodesVisitor.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/visitor/AllNodesVisitor.java	(revision 527)
+++ trunk/src/org/openstreetmap/josm/data/osm/visitor/AllNodesVisitor.java	(revision 529)
@@ -34,6 +34,5 @@
 	 */
 	public void visit(Way w) {
-		for (Node n : w.nodes)
-			visit(n);
+		w.visitNodes(this);
 	}
 
Index: trunk/src/org/openstreetmap/josm/data/osm/visitor/BoundingXYVisitor.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/visitor/BoundingXYVisitor.java	(revision 527)
+++ trunk/src/org/openstreetmap/josm/data/osm/visitor/BoundingXYVisitor.java	(revision 529)
@@ -23,6 +23,5 @@
 
 	public void visit(Way w) {
-		for (Node n : w.nodes)
-			visit(n);
+		w.visitNodes(this);
 	}
 
Index: trunk/src/org/openstreetmap/josm/gui/ConflictResolver.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/ConflictResolver.java	(revision 527)
+++ trunk/src/org/openstreetmap/josm/gui/ConflictResolver.java	(revision 529)
@@ -23,5 +23,4 @@
 import javax.swing.JButton;
 import javax.swing.JLabel;
-import javax.swing.JOptionPane;
 import javax.swing.JPanel;
 import javax.swing.JScrollPane;
@@ -35,5 +34,4 @@
 import javax.swing.table.TableModel;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.conflict.ConflictItem;
 import org.openstreetmap.josm.data.conflict.DeleteConflict;
Index: trunk/src/org/openstreetmap/josm/gui/MainApplet.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/MainApplet.java	(revision 527)
+++ trunk/src/org/openstreetmap/josm/gui/MainApplet.java	(revision 529)
@@ -128,5 +128,5 @@
 		applet.setStub(new AppletStub() {
 			public void appletResize(int w, int h) {
-				frame.resize(w, h);
+				frame.setSize(w, h);
 			}
 
Index: trunk/src/org/openstreetmap/josm/gui/MainMenu.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/MainMenu.java	(revision 527)
+++ trunk/src/org/openstreetmap/josm/gui/MainMenu.java	(revision 529)
@@ -6,8 +6,5 @@
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
-import java.awt.event.InputEvent;
-import java.awt.event.KeyEvent;
-
-import javax.swing.Action;
+
 import javax.swing.JCheckBoxMenuItem;
 import javax.swing.JMenu;
@@ -46,5 +43,4 @@
 import org.openstreetmap.josm.actions.search.SearchAction;
 import org.openstreetmap.josm.data.DataSetChecker;
-import org.openstreetmap.josm.data.Preferences;
 
 /**
Index: trunk/src/org/openstreetmap/josm/gui/layer/RawGpsLayer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/RawGpsLayer.java	(revision 527)
+++ trunk/src/org/openstreetmap/josm/gui/layer/RawGpsLayer.java	(revision 529)
@@ -5,5 +5,4 @@
 import static org.openstreetmap.josm.tools.I18n.trn;
 
-import java.awt.CheckboxGroup;
 import java.awt.Color;
 import java.awt.Component;
@@ -14,15 +13,10 @@
 import java.awt.event.ActionListener;
 import java.io.BufferedReader;
-import java.io.ByteArrayOutputStream;
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.net.HttpURLConnection;
 import java.net.URL;
 import java.net.URLConnection;
 import java.net.UnknownHostException;
 import java.util.Collection;
-import java.util.LinkedList;
 
 import javax.swing.AbstractAction;
@@ -32,5 +26,4 @@
 import javax.swing.JCheckBox;
 import javax.swing.JColorChooser;
-import javax.swing.JFileChooser;
 import javax.swing.JLabel;
 import javax.swing.JMenuItem;
@@ -40,5 +33,4 @@
 import javax.swing.JSeparator;
 import javax.swing.JTextField;
-import javax.swing.filechooser.FileFilter;
 
 import org.openstreetmap.josm.Main;
@@ -56,5 +48,4 @@
 import org.openstreetmap.josm.gui.dialogs.LayerListPopup;
 import org.openstreetmap.josm.io.MultiPartFormOutputStream;
-import org.openstreetmap.josm.io.OsmWriter;
 import org.openstreetmap.josm.tools.ColorHelper;
 import org.openstreetmap.josm.tools.DontShowAgainInfo;
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/MapPaintStyles.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/MapPaintStyles.java	(revision 527)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/MapPaintStyles.java	(revision 529)
@@ -11,5 +11,4 @@
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.gui.MapFrame;
-import org.openstreetmap.josm.gui.MapView.LayerChangeListener;
 import org.openstreetmap.josm.gui.layer.Layer;
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
Index: trunk/src/org/openstreetmap/josm/io/OsmServerWriter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OsmServerWriter.java	(revision 527)
+++ trunk/src/org/openstreetmap/josm/io/OsmServerWriter.java	(revision 529)
@@ -13,4 +13,5 @@
 import java.net.URL;
 import java.net.UnknownHostException;
+import java.net.SocketTimeoutException;
 import java.util.Collection;
 import java.util.LinkedList;
@@ -57,4 +58,25 @@
 	 * does not want to send the data.
 	 */
+	private static final int MSECS_PER_SECOND = 1000;
+	private static final int SECONDS_PER_MINUTE = 60;
+	private static final int MSECS_PER_MINUTE = MSECS_PER_SECOND * SECONDS_PER_MINUTE;
+
+	long uploadStartTime;
+	public String timeLeft(int progress, int list_size) {
+		long now = System.currentTimeMillis();
+		long elapsed = now - uploadStartTime;
+		if (elapsed == 0)
+			elapsed = 1;
+		float uploads_per_ms = (float)progress / elapsed;
+		float uploads_left = list_size - progress;
+		int ms_left = (int)(uploads_left / uploads_per_ms);
+		int minutes_left = ms_left / MSECS_PER_MINUTE;
+		int seconds_left = (ms_left / MSECS_PER_SECOND) % SECONDS_PER_MINUTE ;
+		String time_left_str = Integer.toString(minutes_left) + ":";
+		if (seconds_left < 10)
+			time_left_str += "0";
+		time_left_str += Integer.toString(seconds_left);
+		return time_left_str;
+	}	
 	public void uploadOsm(Collection<OsmPrimitive> list) throws SAXException {
 		processed = new LinkedList<OsmPrimitive>();
@@ -66,11 +88,16 @@
 		NameVisitor v = new NameVisitor();
 		try {
+			uploadStartTime = System.currentTimeMillis();
 			for (OsmPrimitive osm : list) {
 				if (cancel)
 					return;
 				osm.visit(v);
-				Main.pleaseWaitDlg.currentAction.setText(tr("Upload {0} {1} ({2})...", tr(v.className), v.name, osm.id));
+				int progress = Main.pleaseWaitDlg.progress.getValue();
+				String time_left_str = timeLeft(progress, list.size());
+				Main.pleaseWaitDlg.currentAction.setText(tr("Upload {0} {1} (id: {2}) {3}% {4}/{5} ({6} left)...",
+					tr(v.className), v.name, osm.id, 100.0*progress/list.size(), progress, list.size(), time_left_str));
 				osm.visit(this);
 				Main.pleaseWaitDlg.progress.setValue(Main.pleaseWaitDlg.progress.getValue()+1);
+				Main.pleaseWaitDlg.progress.setValue(progress+1);
 			}
 		} catch (RuntimeException e) {
@@ -150,7 +177,9 @@
 	 * 		<code>false</code>, if only the id is encoded.
 	 */
-	private void sendRequest(String requestMethod, String urlSuffix,
-			OsmPrimitive osm, boolean addBody) {
+	private void sendRequestRetry(String requestMethod, String urlSuffix,
+			OsmPrimitive osm, boolean addBody, int retries) {
 		try {
+			if (cancel)
+				return; // assume cancel
 			String version = Main.pref.get("osm-server.version", "0.5");
 			URL url = new URL(
@@ -159,5 +188,5 @@
 					"/" + urlSuffix + 
 					"/" + (osm.id==0 ? "create" : osm.id));
-			System.out.println("upload to: "+url);
+			System.out.print("upload to: "+url+ "..." );
 			activeConnection = (HttpURLConnection)url.openConnection();
 			activeConnection.setConnectTimeout(15000);
@@ -166,5 +195,5 @@
 				activeConnection.setDoOutput(true);
 			activeConnection.connect();
-
+			System.out.println("connected");
 			if (addBody) {
 				OutputStream out = activeConnection.getOutputStream();
@@ -181,17 +210,33 @@
 			if (retCode == 410 && requestMethod.equals("DELETE"))
 				return; // everything fine.. was already deleted.
-			if (retCode != 200) {
-				// Look for a detailed error message from the server
-				if (activeConnection.getHeaderField("Error") != null)
-					retMsg += "\n" + activeConnection.getHeaderField("Error");
-
-				// Report our error
-				ByteArrayOutputStream o = new ByteArrayOutputStream();
-				OsmWriter.output(o, new OsmWriter.Single(osm, true));
-				System.out.println(new String(o.toByteArray(), "UTF-8").toString());
-				throw new RuntimeException(retCode+" "+retMsg);
+			if (retCode != 200 && retCode != 412) {
+				if (retries >= 0) {
+					retries--;
+					System.out.print("backing off for 10 seconds...");
+					Thread.sleep(10000);
+					System.out.println("retrying ("+retries+" left)");
+					sendRequestRetry(requestMethod, urlSuffix, osm, addBody, retries);
+				} else { 
+					// Look for a detailed error message from the server
+					if (activeConnection.getHeaderField("Error") != null)
+						retMsg += "\n" + activeConnection.getHeaderField("Error");
+
+					// Report our error
+					ByteArrayOutputStream o = new ByteArrayOutputStream();
+					OsmWriter.output(o, new OsmWriter.Single(osm, true));
+					System.out.println(new String(o.toByteArray(), "UTF-8").toString());
+					throw new RuntimeException(retCode+" "+retMsg);
+				}
 			}
 		} catch (UnknownHostException e) {
 			throw new RuntimeException(tr("Unknown host")+": "+e.getMessage(), e);
+		} catch(SocketTimeoutException e) {
+			System.out.println(" timed out, retries left: " + retries);
+			if (cancel)
+				return; // assume cancel
+			if (retries-- > 0)
+				sendRequestRetry(requestMethod, urlSuffix, osm, addBody, retries);
+			else
+				throw new RuntimeException(e.getMessage()+ " " + e.getClass().getCanonicalName(), e);
 		} catch (Exception e) {
 			if (cancel)
@@ -199,6 +244,10 @@
 			if (e instanceof RuntimeException)
 				throw (RuntimeException)e;
-			throw new RuntimeException(e.getMessage(), e);
-		}
+			throw new RuntimeException(e.getMessage()+ " " + e.getClass().getCanonicalName(), e);
+		}
+	}
+	private void sendRequest(String requestMethod, String urlSuffix,
+			OsmPrimitive osm, boolean addBody) {
+		sendRequestRetry(requestMethod, urlSuffix, osm, addBody, 10);
 	}
 }
Index: trunk/src/org/openstreetmap/josm/tools/ImageProvider.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/ImageProvider.java	(revision 527)
+++ trunk/src/org/openstreetmap/josm/tools/ImageProvider.java	(revision 529)
@@ -39,5 +39,5 @@
 	 * The icon cache
 	 */
-	private static Map<URL, Image> cache = new HashMap<URL, Image>();
+	private static Map<String, Image> cache = new HashMap<String, Image>();
 
 	/**
@@ -75,14 +75,20 @@
 			subdir += "/";
 		String ext = name.indexOf('.') != -1 ? "" : ".png";
+		String full_name = subdir+name+ext;
 
-		URL path = getImageUrl(subdir+name+ext);
-		if (path == null)
-			return null;
-		
-		Image img = cache.get(path);
+		Image img = cache.get(full_name);
 		if (img == null) {
+			// getImageUrl() does a ton of "stat()" calls and gets expensive
+			// and redundant when you have a whole ton of objects.  So,
+			// index the cache by the name of the icon we're looking for
+			// and don't bother to create a URL unless we're actually
+			// creating the image.
+			URL path = getImageUrl(full_name);
+			if (path == null)
+				return null;
 			img = Toolkit.getDefaultToolkit().createImage(path);
-			cache.put(path, img);
+			cache.put(full_name, img);
 		}
+	
 		return new ImageIcon(img);
 	}
