Index: src/org/openstreetmap/josm/Main.java
===================================================================
--- src/org/openstreetmap/josm/Main.java	(revision 292)
+++ src/org/openstreetmap/josm/Main.java	(revision 293)
@@ -238,4 +238,5 @@
 		jarUrls = allPluginLibraries.toArray(jarUrls);
 		URLClassLoader pluginClassLoader = new URLClassLoader(jarUrls, Main.class.getClassLoader());
+		ImageProvider.sources.add(0, pluginClassLoader);
 
 		for (Collection<PluginInformation> c : p.values()) {
@@ -243,7 +244,8 @@
 				try {
 					Class<?> klass = info.loadClass(pluginClassLoader);
-					ImageProvider.sources.add(0, klass);
-					System.out.println("loading "+info.name);
-					Main.plugins.add(info.load(klass));
+					if (klass != null) {
+						System.out.println("loading "+info.name);
+						Main.plugins.add(info.load(klass));
+					}
 				} catch (PluginException e) {
 					e.printStackTrace();
Index: src/org/openstreetmap/josm/actions/mapmode/AddNodeAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/mapmode/AddNodeAction.java	(revision 292)
+++ src/org/openstreetmap/josm/actions/mapmode/AddNodeAction.java	(revision 293)
@@ -25,4 +25,5 @@
 import org.openstreetmap.josm.data.osm.Way;
 import org.openstreetmap.josm.gui.MapFrame;
+import org.openstreetmap.josm.tools.ImageProvider;
 
 /**
@@ -53,8 +54,16 @@
 
 	public AddNodeAction(MapFrame mapFrame, String name, Mode mode, String desc) {
-		super(name, "node/"+mode, desc, mapFrame, Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
+		super(name, "node/"+mode, desc, mapFrame, getCursor());
 		this.mode = mode;
 		putValue("help", "Action/AddNode/"+Character.toUpperCase(mode.toString().charAt(0))+mode.toString().substring(1));
 	}
+
+	private static Cursor getCursor() {
+		try {
+	        return ImageProvider.getCursor("crosshair", null);
+        } catch (Exception e) {
+        }
+	    return Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR);
+    }
 
 	@Override public void enterMode() {
Index: src/org/openstreetmap/josm/plugins/PluginInformation.java
===================================================================
--- src/org/openstreetmap/josm/plugins/PluginInformation.java	(revision 292)
+++ src/org/openstreetmap/josm/plugins/PluginInformation.java	(revision 293)
@@ -1,3 +1,5 @@
 package org.openstreetmap.josm.plugins;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
 
 import java.io.File;
@@ -8,4 +10,5 @@
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
@@ -33,5 +36,5 @@
 	public final int stage;
 	public final String version;
-	public final List<URL> libraries = new ArrayList<URL>();
+	public final List<URL> libraries = new LinkedList<URL>();
 
 	public final Map<String, String> attr = new TreeMap<String, String>();
@@ -52,5 +55,5 @@
 		this(file, file.getName().substring(0, file.getName().length()-4), null);
 	}
-	
+
 	public PluginInformation(File file, String name, InputStream manifestStream) {
 		this.name = name;
@@ -68,35 +71,46 @@
 		        manifest.read(manifestStream);
 			}
-			Attributes attr = manifest.getMainAttributes();
-			className = attr.getValue("Plugin-Class");
-			description = attr.getValue("Plugin-Description");
-			early = Boolean.parseBoolean(attr.getValue("Plugin-Early"));
-			String stageStr = attr.getValue("Plugin-Stage");
-			stage = stageStr == null ? 50 : Integer.parseInt(stageStr);
-			version = attr.getValue("Plugin-Version");
-			author = attr.getValue("Author");
+			if (manifest != null) {
+				Attributes attr = manifest.getMainAttributes();
+				className = attr.getValue("Plugin-Class");
+				description = attr.getValue("Plugin-Description");
+				early = Boolean.parseBoolean(attr.getValue("Plugin-Early"));
+				String stageStr = attr.getValue("Plugin-Stage");
+				stage = stageStr == null ? 50 : Integer.parseInt(stageStr);
+				version = attr.getValue("Plugin-Version");
+				author = attr.getValue("Author");
+
+				String classPath = attr.getValue(Attributes.Name.CLASS_PATH);
+				if (classPath != null) {
+					String[] cp = classPath.split(" ");
+					StringBuilder entry = new StringBuilder();
+					for (String s : cp) {
+						entry.append(s);
+						if (s.endsWith("\\")) {
+							entry.setLength(entry.length()-1);
+							entry.append("%20"); // append the split character " " as html-encode
+							continue;
+						}
+						s = entry.toString();
+						entry = new StringBuilder();
+						if (!s.startsWith("/") && !s.startsWith("\\") && !s.matches("^.\\:") && file != null)
+							s = file.getParent() + File.separator + s;
+						libraries.add(new URL(getURLString(s)));
+					}
+				}
+				for (Object o : attr.keySet())
+					this.attr.put(o.toString(), attr.getValue(o.toString()));
+			} else {
+				// resource-only plugin
+				className = null;
+				description = tr("unknown");
+				early = false;
+				stage = 50;
+				version = null;
+				author = null;
+			}
 			if (file != null)
-				libraries.add(new URL(getURLString(file.getAbsolutePath())));
-			String classPath = attr.getValue(Attributes.Name.CLASS_PATH);
-			if (classPath != null) {
-				String[] cp = classPath.split(" ");
-				StringBuilder entry = new StringBuilder();
-				for (String s : cp) {
-					entry.append(s);
-					if (s.endsWith("\\")) {
-						entry.setLength(entry.length()-1);
-						entry.append("%20"); // append the split character " " as html-encode
-						continue;
-					}
-					s = entry.toString();
-					entry = new StringBuilder();
-					if (!s.startsWith("/") && !s.startsWith("\\") && !s.matches("^.\\:") && file != null)
-						s = file.getParent() + File.separator + s;
-					libraries.add(new URL(getURLString(s)));
-				}
-			}
-
-			for (Object o : attr.keySet())
-				this.attr.put(o.toString(), attr.getValue(o.toString()));
+				libraries.add(0, new URL(getURLString(file.getAbsolutePath())));
+
 			if (jar != null)
 				jar.close();
@@ -122,4 +136,6 @@
 	 */
 	public Class<?> loadClass(ClassLoader classLoader) {
+		if (className == null)
+			return null;
 		try {
 			Class<?> realClass = Class.forName(className, true, classLoader);
Index: src/org/openstreetmap/josm/tools/ImageProvider.java
===================================================================
--- src/org/openstreetmap/josm/tools/ImageProvider.java	(revision 292)
+++ src/org/openstreetmap/josm/tools/ImageProvider.java	(revision 293)
@@ -44,5 +44,5 @@
 	 * Plugin's class loaders are added by main.
 	 */
-	public static final List<Class<?>> sources = new LinkedList<Class<?>>();
+	public static final List<ClassLoader> sources = new LinkedList<ClassLoader>();
 
 	/**
@@ -89,16 +89,24 @@
 	private static URL getImageUrl(String imageName) {
 	    URL path = null;
-	    for (Class<?> source : sources)
-			if ((path = source.getResource("/images/"+imageName)) != null)
+	    // Try user-preference directory first
+    	try {
+    		if (new File(Main.pref.getPreferencesDir()+"images/"+imageName).exists())
+    			return new URL("file", "", Main.pref.getPreferencesDir()+"images/"+imageName);
+    	} catch (MalformedURLException e) {
+    	}
+
+	    // Try plugins and josm classloader
+	    for (ClassLoader source : sources)
+			if ((path = source.getResource("images/"+imageName)) != null)
 				return path;
-	    
-	    // Try all ressource directories as well
-		for (String location : Main.pref.getAllPossiblePreferenceDirs()) {
-			try {
-				if (new File(location+"images/"+imageName).exists())
-					return new URL("file", "", location+"images/"+imageName);
-            } catch (MalformedURLException e) {
-            }
-		}
+
+	    // Try all other ressource directories
+	    for (String location : Main.pref.getAllPossiblePreferenceDirs()) {
+	    	try {
+	    		if (new File(location+"images/"+imageName).exists())
+	    			return new URL("file", "", location+"images/"+imageName);
+	    	} catch (MalformedURLException e) {
+	    	}
+	    }
 	    return null;
     }
@@ -112,5 +120,7 @@
 
 	public static Cursor getCursor(String name, String overlay) {
-		ImageIcon img = overlay(get("cursor/"+name), "cursor/modifier/"+overlay, OverlayPosition.SOUTHEAST);
+		ImageIcon img = get("cursor",name);
+		if (overlay != null)
+			img = overlay(img, "cursor/modifier/"+overlay, OverlayPosition.SOUTHEAST);
 		Cursor c = Toolkit.getDefaultToolkit().createCustomCursor(img.getImage(),
 				name.equals("crosshair") ? new Point(10,10) : new Point(3,2), "Cursor");
@@ -156,5 +166,5 @@
 
 	static {
-		sources.add(Main.class);
+		sources.add(ClassLoader.getSystemClassLoader());
 	}
 }
