Index: trunk/src/org/openstreetmap/josm/actions/OpenLocationAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/OpenLocationAction.java	(revision 6029)
+++ trunk/src/org/openstreetmap/josm/actions/OpenLocationAction.java	(revision 6031)
@@ -33,4 +33,5 @@
 import org.openstreetmap.josm.gui.ExtendedDialog;
 import org.openstreetmap.josm.gui.progress.PleaseWaitProgressMonitor;
+import org.openstreetmap.josm.gui.util.GuiHelper;
 import org.openstreetmap.josm.gui.widgets.HistoryComboBox;
 import org.openstreetmap.josm.tools.Shortcut;
@@ -148,4 +149,24 @@
 
     /**
+     * Summarizes acceptable urls for error message purposes.
+     * @since 6030
+     */
+    public String findSummaryDocumentation() {
+        String result = "";
+        for (int i = 0; i < downloadTasks.size(); i++) {
+            Class<? extends DownloadTask> taskClass = downloadTasks.get(i);
+            if (taskClass != null) {
+                try {
+                    DownloadTask task = taskClass.getConstructor().newInstance();
+                    result += "<br/>" + task.acceptsDocumentationSummary();
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        return result;
+    }
+
+    /**
      * Open the given URL.
      * @param new_layer true if the URL needs to be opened in a new layer, false otherwise
@@ -164,9 +185,11 @@
             Main.worker.submit(new PostDownloadHandler(task, future));
         } else {
+            final String details = findSummaryDocumentation();    // Explain what patterns are supported
             SwingUtilities.invokeLater(new Runnable() {
+                @Override
                 public void run() {
                     JOptionPane.showMessageDialog(Main.parent, tr(
-                            "<html>Cannot open URL ''{0}'' because no suitable download task is available.</html>",
-                            url), tr("Download Location"), JOptionPane.ERROR_MESSAGE);
+                            "<html><p>Cannot open URL ''{0}''<br/>The following load tasks accept the URL patterns shown:<br/>{1}</p></html>",
+                            url, details), tr("Download Location"), JOptionPane.ERROR_MESSAGE);
                 }
             });
Index: trunk/src/org/openstreetmap/josm/actions/downloadtasks/AbstractDownloadTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/downloadtasks/AbstractDownloadTask.java	(revision 6029)
+++ trunk/src/org/openstreetmap/josm/actions/downloadtasks/AbstractDownloadTask.java	(revision 6031)
@@ -4,4 +4,5 @@
 import java.util.ArrayList;
 import java.util.List;
+import org.openstreetmap.josm.io.XmlWriter;
 
 public abstract class AbstractDownloadTask implements DownloadTask {
@@ -38,6 +39,48 @@
     }
 
+    @Override
     public List<Object> getErrorObjects() {
         return errorMessages;
     }
+    
+    @Override
+    public String acceptsDocumentationSummary() {
+        StringBuilder buf = new StringBuilder();
+        buf.append(getTitle());
+        String patterns[] =  getPatterns();
+        if (patterns.length>0) {
+            buf.append(":<br/><ul>");
+            for (String pattern: patterns) {
+                buf.append("<li>");
+                buf.append(XmlWriter.encode(pattern));
+            } 
+            buf.append("</ul>");
+        }
+        return buf.toString();
+    }
+
+    // Can be overridden for more complex checking logic
+    @Override
+    public boolean acceptsUrl(String url) {
+        if (url==null) return false;
+        for (String p: getPatterns()) {
+            if (url.matches(p)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    // Default name to keep old plugins compatible
+    @Override
+    public String getTitle() {
+        return getClass().getName();
+    }
+
+    // Default pattern to keep old plugins compatible
+    @Override
+    public String[] getPatterns() {
+        return new String[]{};
+    }
+    
 }
Index: trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadGpsTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadGpsTask.java	(revision 6029)
+++ trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadGpsTask.java	(revision 6031)
@@ -45,4 +45,15 @@
     protected String newLayerName = null;
 
+    @Override
+    public String[] getPatterns() {
+        return new String[] {PATTERN_EXTERNAL_GPX_FILE, PATTERN_EXTERNAL_GPX_SCRIPT, PATTERN_TRACE_ID, PATTERN_TRACKPOINTS_BBOX};
+    }
+
+    @Override
+    public String getTitle() {
+        return tr("Download GPS");
+    }
+
+    @Override
     public Future<?> download(boolean newLayer, Bounds downloadArea, ProgressMonitor progressMonitor) {
         downloadTask = new DownloadTask(newLayer,
@@ -53,4 +64,5 @@
     }
 
+    @Override
     public Future<?> loadUrl(boolean newLayer, String url, ProgressMonitor progressMonitor) {
         if (url != null && (url.matches(PATTERN_TRACE_ID) || url.matches(PATTERN_EXTERNAL_GPX_SCRIPT) || url.matches(PATTERN_EXTERNAL_GPX_FILE))) {
@@ -74,13 +86,5 @@
     }
 
-    /* (non-Javadoc)
-     * @see org.openstreetmap.josm.actions.downloadtasks.DownloadTask#acceptsUrl(java.lang.String)
-     */
-    @Override
-    public boolean acceptsUrl(String url) {
-        return url != null && (url.matches(PATTERN_TRACE_ID) || url.matches(PATTERN_TRACKPOINTS_BBOX)
-                || url.matches(PATTERN_EXTERNAL_GPX_SCRIPT) || url.matches(PATTERN_EXTERNAL_GPX_FILE));
-    }
-
+    @Override
     public void cancel() {
         if (downloadTask != null) {
Index: trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmChangeCompressedTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmChangeCompressedTask.java	(revision 6029)
+++ trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmChangeCompressedTask.java	(revision 6031)
@@ -3,4 +3,6 @@
 
 import java.util.concurrent.Future;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
 
 import org.openstreetmap.josm.Main;
@@ -11,13 +13,15 @@
 
 public class DownloadOsmChangeCompressedTask extends DownloadOsmChangeTask {
+
+    @Override
+    public String[] getPatterns() {
+        return new String[]{"https?://.*/.*\\.osc.(gz|bz2?)"};
+    }
+
+    @Override
+    public String getTitle() {
+        return tr("Download Compressed OSM Change");
+    }
     
-    /* (non-Javadoc)
-     * @see org.openstreetmap.josm.actions.downloadtasks.DownloadTask#acceptsUrl(java.lang.String)
-     */
-    @Override
-    public boolean acceptsUrl(String url) {
-        return url != null && url.matches("https?://.*/.*\\.osc.(gz|bz2?)"); // Remote .osc.gz / .osc.bz / .osc.bz2 files
-    }
-        
     /**
      * Loads a given URL
@@ -26,4 +30,5 @@
      * @param progressMonitor progress monitor for user interaction
      */
+    @Override
     public Future<?> loadUrl(boolean new_layer, final String url, ProgressMonitor progressMonitor) {
         downloadTask = new DownloadTask(new_layer, new OsmServerLocationReader(url), progressMonitor) {
Index: trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmChangeTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmChangeTask.java	(revision 6029)
+++ trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmChangeTask.java	(revision 6031)
@@ -8,4 +8,6 @@
 import java.util.Map;
 import java.util.concurrent.Future;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
 
 import org.openstreetmap.josm.Main;
@@ -41,11 +43,15 @@
 
     @Override
-    public boolean acceptsUrl(String url) {
-        return url != null && (
-                url.matches("http://.*/api/0.6/changeset/\\p{Digit}+/download") // OSM API 0.6 changesets
-             || url.matches("https?://.*/.*\\.osc")                             // Remote .osc files
-                );
-    }
-
+    public String[] getPatterns() {
+        return new String[]{"http://.*/api/0.6/changeset/\\p{Digit}+/download", // OSM API 0.6 changesets
+            "https?://.*/.*\\.osc" // Remote .osc files
+        };
+    }
+
+    @Override
+    public String getTitle() {
+        return tr("Download OSM Change");
+    }
+        
     /* (non-Javadoc)
      * @see org.openstreetmap.josm.actions.downloadtasks.DownloadOsmTask#download(boolean, org.openstreetmap.josm.data.Bounds, org.openstreetmap.josm.gui.progress.ProgressMonitor)
Index: trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmCompressedTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmCompressedTask.java	(revision 6029)
+++ trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmCompressedTask.java	(revision 6031)
@@ -3,4 +3,6 @@
 
 import java.util.concurrent.Future;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
 
 import org.openstreetmap.josm.Main;
@@ -12,11 +14,15 @@
 
 public class DownloadOsmCompressedTask extends DownloadOsmTask {
-    
-    /* (non-Javadoc)
-     * @see org.openstreetmap.josm.actions.downloadtasks.DownloadTask#acceptsUrl(java.lang.String)
-     */
+
+    String PATTERN_GZ =  "https?://.*/.*\\.osm.(gz|bz2?)";
+
     @Override
-    public boolean acceptsUrl(String url) {
-        return url != null && url.matches("https?://.*/.*\\.osm.(gz|bz2?)"); // Remote .osm.gz / .osm.bz / .osm.bz2 files
+    public String[] getPatterns() {
+        return new String[]{PATTERN_GZ};
+    }
+
+    @Override
+    public String getTitle() {
+        return tr("Download Compressed OSM");
     }
     
@@ -36,4 +42,5 @@
      * @param progressMonitor progress monitor for user interaction
      */
+    @Override
     public Future<?> loadUrl(boolean new_layer, final String url, ProgressMonitor progressMonitor) {
         downloadTask = new DownloadTask(new_layer, new OsmServerLocationReader(url), progressMonitor) {
Index: trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTask.java	(revision 6029)
+++ trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTask.java	(revision 6031)
@@ -49,4 +49,23 @@
     
     protected String newLayerName = null;
+    
+    @Override
+    public String[] getPatterns() {
+        if (this.getClass() == DownloadOsmTask.class) {
+            return new String[]{PATTERN_OSM_API_URL, PATTERN_OVERPASS_API_URL, 
+                PATTERN_OVERPASS_API_XAPI_URL, PATTERN_EXTERNAL_OSM_FILE};
+        } else {
+            return super.getPatterns();
+        }
+    }
+
+    @Override
+    public String getTitle() {
+        if (this.getClass() == DownloadOsmTask.class) {
+            return tr("Download OSM");
+        } else {
+            return super.getTitle();
+        }
+    }
 
     protected void rememberDownloadedData(DataSet ds) {
@@ -136,4 +155,5 @@
      * @param url The URL as String
      */
+    @Override
     public Future<?> loadUrl(boolean new_layer, String url, ProgressMonitor progressMonitor) {
         if (url.matches(PATTERN_OVERPASS_API_URL)) {
@@ -156,18 +176,6 @@
         newLayerName = matcher.matches() ? matcher.group(1) : null;
     }
-    
-    /* (non-Javadoc)
-     * @see org.openstreetmap.josm.actions.downloadtasks.DownloadTask#acceptsUrl(java.lang.String)
-     */
-    @Override
-    public boolean acceptsUrl(String url) {
-        return url != null && (
-                url.matches(PATTERN_OSM_API_URL)           // OSM API 0.6 and XAPI
-             || url.matches(PATTERN_OVERPASS_API_URL)      // Overpass API
-             || url.matches(PATTERN_OVERPASS_API_XAPI_URL) // Overpass API XAPI compatibility layer
-             || url.matches(PATTERN_EXTERNAL_OSM_FILE)     // Remote .osm files
-                );
-    }
-
+
+    @Override
     public void cancel() {
         if (downloadTask != null) {
Index: trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmUrlTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmUrlTask.java	(revision 6029)
+++ trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmUrlTask.java	(revision 6031)
@@ -3,4 +3,6 @@
 
 import java.util.concurrent.Future;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
 
 import org.openstreetmap.josm.gui.progress.ProgressMonitor;
@@ -13,10 +15,13 @@
         return download(newLayer, OsmUrlToBounds.parse(url), null);
     }
+    
+    @Override
+    public String[] getPatterns() {
+        return new String[]{"http://www\\.openstreetmap\\.org/\\?lat=.*&lon=.*"};
+    }
 
     @Override
-    public boolean acceptsUrl(String url) {
-        return url != null && (
-                url.matches("http://www\\.openstreetmap\\.org/\\?lat=.*&lon=.*")
-                );
+    public String getTitle() {
+        return tr("Download OSM URL");
     }
 }
Index: trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadTask.java	(revision 6029)
+++ trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadTask.java	(revision 6031)
@@ -80,4 +80,19 @@
 
     /**
+     * Returns a short html documentation string, describing acceptable URLs.
+     */
+    String acceptsDocumentationSummary();
+    
+    /**
+     * Returns human-readable description of the task
+     */
+    String getTitle();
+    
+    /**
+     * Returns regular expression that match the URLs
+     */
+    String[] getPatterns();
+
+    /**
      * Replies the error objects of the task. Empty list, if no error messages are available.
      *
