Index: /trunk/src/org/openstreetmap/josm/Main.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/Main.java	(revision 6298)
+++ /trunk/src/org/openstreetmap/josm/Main.java	(revision 6299)
@@ -293,5 +293,5 @@
      */
     public static void error(Throwable t) {
-        error(t.getClass().getName()+": "+t.getMessage());
+        error(t.getClass().getName()+": "+t.getMessage().trim());
     }
     
@@ -302,5 +302,5 @@
      */
     public static void warn(Throwable t) {
-        warn(t.getClass().getName()+": "+t.getMessage());
+        warn(t.getClass().getName()+": "+t.getMessage().trim());
     }
 
Index: /trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/ButtonMarker.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/ButtonMarker.java	(revision 6298)
+++ /trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/ButtonMarker.java	(revision 6299)
@@ -49,5 +49,5 @@
         Point screen = mv.getPoint(getEastNorth());
         buttonRectangle.setLocation(screen.x+4, screen.y+2);
-        symbol.paintIcon(mv, g, screen.x+4, screen.y+2);
+        paintIcon(mv, g, screen.x+4, screen.y+2);
         Border b;
         Point mousePosition = mv.getMousePosition();
Index: /trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/Marker.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/Marker.java	(revision 6298)
+++ /trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/Marker.java	(revision 6299)
@@ -2,7 +2,11 @@
 package org.openstreetmap.josm.gui.layer.markerlayer;
 
+import java.awt.AlphaComposite;
+import java.awt.Color;
 import java.awt.Graphics;
+import java.awt.Graphics2D;
 import java.awt.Point;
 import java.awt.event.ActionEvent;
+import java.awt.image.BufferedImage;
 import java.io.File;
 import java.net.MalformedURLException;
@@ -19,5 +23,5 @@
 import java.util.TimeZone;
 
-import javax.swing.Icon;
+import javax.swing.ImageIcon;
 
 import org.openstreetmap.josm.Main;
@@ -279,13 +283,17 @@
     private final String text;
 
-    public final Icon symbol;
+    protected final ImageIcon symbol;
+    private BufferedImage redSymbol = null;
     public final MarkerLayer parentLayer;
-    public double time; /* absolute time of marker in seconds since epoch */
-    public double offset; /* time offset in seconds from the gpx point from which it was derived,
-                             may be adjusted later to sync with other data, so not final */
+    /** Absolute time of marker in seconds since epoch */
+    public double time;
+    /** Time offset in seconds from the gpx point from which it was derived, may be adjusted later to sync with other data, so not final */
+    public double offset; 
 
     private String cachedText;
     private int textVersion = -1;
     private CachedLatLon coor;
+    
+    private boolean erroneous = false;
 
     public Marker(LatLon ll, TemplateEngineDataProvider dataProvider, String iconName, MarkerLayer parentLayer, double time, double offset) {
@@ -294,6 +302,4 @@
         this.offset = offset;
         this.time = time;
-        // /* ICON(markers/) */"Bridge"
-        // /* ICON(markers/) */"Crossing"
         this.symbol = iconName != null ? ImageProvider.getIfAvailable("markers",iconName) : null;
         this.parentLayer = parentLayer;
@@ -308,6 +314,4 @@
         this.offset = offset;
         this.time = time;
-        // /* ICON(markers/) */"Bridge"
-        // /* ICON(markers/) */"Crossing"
         this.symbol = iconName != null ? ImageProvider.getIfAvailable("markers",iconName) : null;
         this.parentLayer = parentLayer;
@@ -340,20 +344,35 @@
     }
 
+    /**
+     * Sets the marker's coordinates.
+     * @param coor The marker's coordinates (lat/lon)
+     */
     public final void setCoor(LatLon coor) {
         this.coor = new CachedLatLon(coor);
     }
 
+    /**
+     * Returns the marker's coordinates.
+     * @return The marker's coordinates (lat/lon)
+     */
     public final LatLon getCoor() {
         return coor;
     }
 
+    /**
+     * Sets the marker's projected coordinates.
+     * @param eastNorth The marker's projected coordinates (easting/northing)
+     */
     public final void setEastNorth(EastNorth eastNorth) {
         this.coor = new CachedLatLon(eastNorth);
     }
 
+    /**
+     * Returns the marker's projected coordinates.
+     * @return The marker's projected coordinates (easting/northing)
+     */
     public final EastNorth getEastNorth() {
         return coor.getEastNorth();
     }
-
 
     /**
@@ -377,5 +396,4 @@
     }
 
-
     /**
      * Paints the marker.
@@ -388,5 +406,5 @@
         Point screen = mv.getPoint(getEastNorth());
         if (symbol != null && showTextOrIcon) {
-            symbol.paintIcon(mv, g, screen.x-symbol.getIconWidth()/2, screen.y-symbol.getIconHeight()/2);
+            paintIcon(mv, g, screen.x-symbol.getIconWidth()/2, screen.y-symbol.getIconHeight()/2);
         } else {
             g.drawLine(screen.x-2, screen.y-2, screen.x+2, screen.y+2);
@@ -399,5 +417,24 @@
         }
     }
-
+    
+    protected void paintIcon(MapView mv, Graphics g, int x, int y) {
+        if (!erroneous) {
+            symbol.paintIcon(mv, g, x, y);
+        } else {
+            if (redSymbol == null) {
+                int width = symbol.getIconWidth();
+                int height = symbol.getIconHeight();
+                                
+                redSymbol = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
+                Graphics2D gbi = redSymbol.createGraphics();
+                gbi.drawImage(symbol.getImage(), 0, 0, null);
+                gbi.setColor(Color.RED);
+                gbi.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.666f));
+                gbi.fillRect(0, 0, width, height);
+                gbi.dispose();
+            }
+            g.drawImage(redSymbol, x, y, mv);
+        }
+    }
 
     protected TemplateEntryProperty getTextTemplate() {
@@ -465,3 +502,24 @@
         throw new UnsupportedOperationException();
     }
+    
+    /**
+     * Determines if this marker is erroneous.
+     * @return {@code true} if this markers has any kind of error, {@code false} otherwise
+     * @since 6299
+     */
+    public final boolean isErroneous() {
+        return erroneous;
+    }
+    
+    /**
+     * Sets this marker erroneous or not.
+     * @param erroneous {@code true} if this markers has any kind of error, {@code false} otherwise
+     * @since 6299
+     */
+    public final void setErroneous(boolean erroneous) {
+        this.erroneous = erroneous;
+        if (!erroneous) {
+            redSymbol = null;
+        }
+    }
 }
Index: /trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/PlayHeadMarker.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/PlayHeadMarker.java	(revision 6298)
+++ /trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/PlayHeadMarker.java	(revision 6299)
@@ -274,5 +274,5 @@
         if (time < 0.0) return;
         Point screen = mv.getPoint(getEastNorth());
-        symbol.paintIcon(mv, g, screen.x, screen.y);
+        paintIcon(mv, g, screen.x, screen.y);
     }
 
Index: /trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/WebMarker.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/WebMarker.java	(revision 6298)
+++ /trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/WebMarker.java	(revision 6299)
@@ -5,4 +5,5 @@
 
 import java.awt.event.ActionEvent;
+import java.io.File;
 import java.net.URL;
 import java.util.Collections;
@@ -15,4 +16,6 @@
 import org.openstreetmap.josm.data.gpx.GpxLink;
 import org.openstreetmap.josm.data.gpx.WayPoint;
+import org.openstreetmap.josm.gui.Notification;
+import org.openstreetmap.josm.tools.CheckParameterUtil;
 import org.openstreetmap.josm.tools.OpenBrowser;
 
@@ -25,8 +28,9 @@
 public class WebMarker extends ButtonMarker {
 
-    public final URL webUrl;
+    private final URL webUrl;
 
     public WebMarker(LatLon ll, URL webUrl, MarkerLayer parentLayer, double time, double offset) {
         super(ll, "web.png", parentLayer, time, offset);
+        CheckParameterUtil.ensureParameterNotNull(webUrl, "webUrl");
         this.webUrl = webUrl;
     }
@@ -35,9 +39,13 @@
         String error = OpenBrowser.displayUrl(webUrl.toString());
         if (error != null) {
-            JOptionPane.showMessageDialog(Main.parent,
-                    "<html><b>" +
-                            tr("There was an error while trying to display the URL for this marker") +
-                            "</b><br>" + tr("(URL was: ") + webUrl.toString() + ")" + "<br>" + error,
-                            tr("Error displaying URL"), JOptionPane.ERROR_MESSAGE);
+            setErroneous(true);
+            new Notification(
+                    "<b>" + tr("There was an error while trying to display the URL for this marker") + "</b><br>" + 
+                                  tr("(URL was: ") + webUrl.toString() + ")" + "<br>" + error)
+                    .setIcon(JOptionPane.ERROR_MESSAGE)
+                    .setDuration(Notification.TIME_LONG)
+                    .show();
+        } else {
+            updateErroneous();
         }
     }
@@ -51,3 +59,17 @@
         return wpt;
     }
+    
+    private final void updateErroneous() {
+        if ("file".equals(webUrl.getProtocol())) {
+            String path = webUrl.getPath();
+            try {
+                setErroneous(path.isEmpty() || !new File(path).exists());
+            } catch (Exception e) {
+                Main.warn(e);
+                setErroneous(true);
+            }
+        } else {
+            setErroneous(false);
+        }
+    }
 }
Index: /trunk/src/org/openstreetmap/josm/tools/OpenBrowser.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/tools/OpenBrowser.java	(revision 6298)
+++ /trunk/src/org/openstreetmap/josm/tools/OpenBrowser.java	(revision 6299)
@@ -29,4 +29,7 @@
 
     /**
+     * Displays an external URI using platform associated software. 
+     * A web resource will launch platform's browser, an audio file URI will launch audio player, etc. 
+     * @param uri The URI to display
      * @return <code>null</code> for success or a string in case of an error.
      * @throws IllegalStateException thrown if no platform is set to which opening the URL can be dispatched,
@@ -34,4 +37,5 @@
      */
     public static String displayUrl(URI uri) {
+        CheckParameterUtil.ensureParameterNotNull(uri, "uri");
         if (Main.applet) {
             try {
@@ -43,17 +47,25 @@
             }
         }
+        
+        Main.info(tr("Opening URL: {0}", uri));
 
         if (Desktop.isDesktopSupported()) {
             try {
-                try {
+                if (Main.platform instanceof PlatformHookWindows) {
+                    // Desktop API works fine under Windows, so we don't try any fallback in case of I/O exceptions because it's not API's fault
                     Desktop.getDesktop().browse(uri);
-                } catch (IOException e) {
-                    // Workaround for KDE (Desktop API is severely flawed)
-                    // see http://bugs.sun.com/view_bug.do?bug_id=6486393
-                    Main.warn("Desktop class failed. Platform dependent fall back for open url in browser.");
-                    displayUrlFallback(uri);
+                } else {
+                    // This is not the case with some Linux environments (see below), and not sure about Mac OS X, so we need to handle API failure
+                    try {
+                        Desktop.getDesktop().browse(uri);
+                    } catch (IOException e) {
+                        // Workaround for KDE (Desktop API is severely flawed)
+                        // see https://bugs.openjdk.java.net/browse/JDK-6486393
+                        Main.warn("Desktop class failed. Platform dependent fall back for open url in browser.");
+                        displayUrlFallback(uri);
+                    }
                 }
             } catch (Exception e) {
-                e.printStackTrace();
+                Main.warn(e);
                 return e.getMessage();
             }
@@ -69,4 +81,12 @@
     }
 
+    /**
+     * Displays an external URL using platform associated software. 
+     * A web resource will launch platform's browser, an audio file URL will launch audio player, etc. 
+     * @param url The URL to display
+     * @return <code>null</code> for success or a string in case of an error.
+     * @throws IllegalStateException thrown if no platform is set to which opening the URL can be dispatched,
+     * {@link Main#platform}
+     */
     public static String displayUrl(String url) {
         try {
