Index: trunk/src/org/openstreetmap/josm/actions/OpenLocationAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/OpenLocationAction.java	(revision 8194)
+++ trunk/src/org/openstreetmap/josm/actions/OpenLocationAction.java	(revision 8195)
@@ -7,4 +7,5 @@
 import java.awt.GridBagConstraints;
 import java.awt.GridBagLayout;
+import java.awt.GridLayout;
 import java.awt.event.ActionEvent;
 import java.awt.event.KeyEvent;
@@ -18,4 +19,5 @@
 import javax.swing.JCheckBox;
 import javax.swing.JLabel;
+import javax.swing.JList;
 import javax.swing.JOptionPane;
 import javax.swing.JPanel;
@@ -24,4 +26,6 @@
 import org.openstreetmap.josm.actions.downloadtasks.DownloadGpsTask;
 import org.openstreetmap.josm.actions.downloadtasks.DownloadNotesTask;
+import org.openstreetmap.josm.actions.downloadtasks.DownloadNotesUrlBoundsTask;
+import org.openstreetmap.josm.actions.downloadtasks.DownloadNotesUrlIdTask;
 import org.openstreetmap.josm.actions.downloadtasks.DownloadOsmChangeCompressedTask;
 import org.openstreetmap.josm.actions.downloadtasks.DownloadOsmChangeTask;
@@ -67,4 +71,6 @@
         addDownloadTaskClass(DownloadOsmChangeCompressedTask.class);
         addDownloadTaskClass(DownloadSessionTask.class);
+        addDownloadTaskClass(DownloadNotesUrlBoundsTask.class);
+        addDownloadTaskClass(DownloadNotesUrlIdTask.class);
     }
 
@@ -183,23 +189,50 @@
         PleaseWaitProgressMonitor monitor = new PleaseWaitProgressMonitor(tr("Download Data"));
         Collection<DownloadTask> tasks = findDownloadTasks(url, false);
-        DownloadTask task = null;
-        Future<?> future = null;
-        if (!tasks.isEmpty()) {
-            // TODO: handle multiple suitable tasks ?
+
+        if (tasks.size() > 1) {
+            tasks = askWhichTasksToLoad(tasks);
+        } else if (tasks.isEmpty()) {
+            warnNoSuitableTasks(url);
+            return;
+        }
+
+        for (final DownloadTask task : tasks) {
             try {
-                task = tasks.iterator().next();
-                future = task.loadUrl(newLayer, url, monitor);
+                Future<?> future = task.loadUrl(newLayer, url, monitor);
+                Main.worker.submit(new PostDownloadHandler(task, future));
             } catch (IllegalArgumentException e) {
                 Main.error(e);
             }
         }
-        if (future != null) {
-            Main.worker.submit(new PostDownloadHandler(task, future));
-        } else {
-            final String details = findSummaryDocumentation();    // Explain what patterns are supported
-            HelpAwareOptionPane.showMessageDialogInEDT(Main.parent, "<html><p>" + tr(
-                    "Cannot open URL ''{0}''<br>The following download tasks accept the URL patterns shown:<br>{1}",
-                    url, details) + "</p></html>", tr("Download Location"), JOptionPane.ERROR_MESSAGE, HelpUtil.ht("/Action/OpenLocation"));
-        }
+
+    }
+
+    /**
+     * Asks the user which of the possible tasks to perform.
+     * @param tasks a list of possible tasks
+     * @return the selected tasks from the user or an empty list if the dialog has been canceled
+     */
+    Collection<DownloadTask> askWhichTasksToLoad(final Collection<DownloadTask> tasks) {
+        final JList<DownloadTask> list = new JList<>(tasks.toArray(new DownloadTask[tasks.size()]));
+        list.addSelectionInterval(0, tasks.size() - 1);
+        final ExtendedDialog dialog = new ExtendedDialog(Main.parent, tr("Which tasks to perform?"), new String[]{tr("Ok"), tr("Cancel")}, true) {{
+            final JPanel pane = new JPanel(new GridLayout(2, 1));
+            pane.add(new JLabel(tr("Which tasks to perform?")));
+            pane.add(list);
+            setContent(pane);
+        }};
+        dialog.showDialog();
+        return dialog.getValue() == 1 ? list.getSelectedValuesList() : Collections.<DownloadTask>emptyList();
+    }
+
+    /**
+     * Displays an error message dialog that no suitable tasks have been found for the given url.
+     * @param url the given url
+     */
+    void warnNoSuitableTasks(final String url) {
+        final String details = findSummaryDocumentation();    // Explain what patterns are supported
+        HelpAwareOptionPane.showMessageDialogInEDT(Main.parent, "<html><p>" + tr(
+                "Cannot open URL ''{0}''<br>The following download tasks accept the URL patterns shown:<br>{1}",
+                url, details) + "</p></html>", tr("Download Location"), JOptionPane.ERROR_MESSAGE, HelpUtil.ht("/Action/OpenLocation"));
     }
 
Index: trunk/src/org/openstreetmap/josm/actions/downloadtasks/AbstractDownloadTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/downloadtasks/AbstractDownloadTask.java	(revision 8194)
+++ trunk/src/org/openstreetmap/josm/actions/downloadtasks/AbstractDownloadTask.java	(revision 8195)
@@ -108,4 +108,9 @@
     }
 
+    @Override
+    public String toString() {
+        return this.getTitle();
+    }
+
     // Default pattern to keep old plugins compatible
     @Override
Index: trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadNotesTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadNotesTask.java	(revision 8194)
+++ trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadNotesTask.java	(revision 8195)
@@ -16,4 +16,5 @@
 import org.openstreetmap.josm.gui.progress.ProgressMonitor;
 import org.openstreetmap.josm.io.BoundingBoxDownloader;
+import org.openstreetmap.josm.io.OsmApi;
 import org.openstreetmap.josm.io.OsmServerLocationReader;
 import org.openstreetmap.josm.io.OsmServerReader;
@@ -28,4 +29,10 @@
 
     private DownloadTask downloadTask;
+
+    public Future<?> download(boolean newLayer, long id, ProgressMonitor progressMonitor) {
+        final String url = OsmApi.getOsmApi().getBaseUrl() + "notes/" + id;
+        downloadTask = new DownloadRawUrlTask(new OsmServerLocationReader(url), progressMonitor);
+        return Main.worker.submit(downloadTask);
+    }
 
     @Override
Index: trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadNotesUrlBoundsTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadNotesUrlBoundsTask.java	(revision 8195)
+++ trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadNotesUrlBoundsTask.java	(revision 8195)
@@ -0,0 +1,27 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.actions.downloadtasks;
+
+import org.openstreetmap.josm.gui.progress.ProgressMonitor;
+import org.openstreetmap.josm.tools.OsmUrlToBounds;
+
+import java.util.concurrent.Future;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+public class DownloadNotesUrlBoundsTask extends DownloadNotesTask {
+
+    @Override
+    public Future<?> loadUrl(boolean newLayer, String url, ProgressMonitor progressMonitor) {
+        return download(newLayer, OsmUrlToBounds.parse(url), null);
+    }
+
+    @Override
+    public String[] getPatterns() {
+        return new String[]{
+                "https?://www\\.(osm|openstreetmap)\\.org/(.*)?#map=\\p{Digit}+/.*/.*&layers=N"};
+    }
+    @Override
+    public String getTitle() {
+        return tr("Download OSM Notes within Bounds");
+    }
+}
Index: trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadNotesUrlIdTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadNotesUrlIdTask.java	(revision 8195)
+++ trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadNotesUrlIdTask.java	(revision 8195)
@@ -0,0 +1,41 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.actions.downloadtasks;
+
+import org.openstreetmap.josm.gui.progress.ProgressMonitor;
+
+import java.util.concurrent.Future;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+public class DownloadNotesUrlIdTask extends DownloadNotesTask {
+
+    private final String URL_ID_PATTERN = "https?://www\\.(osm|openstreetmap)\\.org/note/(\\p{Digit}+).*";
+
+    @Override
+    public Future<?> loadUrl(boolean newLayer, String url, ProgressMonitor progressMonitor) {
+        final Matcher matcher = Pattern.compile(URL_ID_PATTERN).matcher(url);
+        final long id;
+        try {
+            matcher.matches();
+            return download(newLayer, Long.parseLong(matcher.group(2)), null);
+        } catch (RuntimeException ex) {
+            throw new IllegalStateException("Failed to parse note id from " + url);
+        }
+    }
+
+    @Override
+    public String[] getPatterns() {
+        return new String[]{URL_ID_PATTERN};
+    }
+
+    public boolean acceptsUrl(String url) {
+        return super.acceptsUrl(url);
+    }
+
+    @Override
+    public String getTitle() {
+        return tr("Download OSM Note by ID");
+    }
+}
