Index: trunk/src/org/openstreetmap/josm/actions/OpenLocationAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/OpenLocationAction.java	(revision 4520)
+++ trunk/src/org/openstreetmap/josm/actions/OpenLocationAction.java	(revision 4521)
@@ -9,4 +9,5 @@
 import java.awt.event.ActionEvent;
 import java.awt.event.KeyEvent;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.LinkedList;
@@ -16,8 +17,12 @@
 import javax.swing.JCheckBox;
 import javax.swing.JLabel;
+import javax.swing.JOptionPane;
 import javax.swing.JPanel;
+import javax.swing.SwingUtilities;
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.actions.downloadtasks.DownloadGpsTask;
 import org.openstreetmap.josm.actions.downloadtasks.DownloadOsmTask;
+import org.openstreetmap.josm.actions.downloadtasks.DownloadTask;
 import org.openstreetmap.josm.actions.downloadtasks.PostDownloadHandler;
 import org.openstreetmap.josm.gui.ExtendedDialog;
@@ -33,4 +38,6 @@
 public class OpenLocationAction extends JosmAction {
 
+    protected final List<Class<? extends DownloadTask>> downloadTasks;
+    
     /**
      * Create an open action. The name is "Open a file".
@@ -41,4 +48,7 @@
                 Shortcut.registerShortcut("system:open_location", tr("File: {0}", tr("Open Location...")), KeyEvent.VK_L, Shortcut.GROUP_MENU), true);
         putValue("help", ht("/Action/OpenLocation"));
+        this.downloadTasks = new ArrayList<Class<? extends DownloadTask>>();
+        addDownloadTaskClass(DownloadOsmTask.class);
+        addDownloadTaskClass(DownloadGpsTask.class);
     }
 
@@ -104,11 +114,38 @@
 
     /**
-     * Open the given file.
+     * Open the given URL.
      */
-    public void openUrl(boolean new_layer, String url) {
-        DownloadOsmTask task = new DownloadOsmTask();
+    public void openUrl(boolean new_layer, final String url) {
         PleaseWaitProgressMonitor monitor = new PleaseWaitProgressMonitor(tr("Download Data"));
-        Future<?> future = task.loadUrl(new_layer, url, monitor);
-        Main.worker.submit(new PostDownloadHandler(task, future));
+        DownloadTask task = null;
+        Future<?> future = null;
+        for (int i = 0; future == null && i < downloadTasks.size(); i++) {
+            Class<? extends DownloadTask> taskClass = downloadTasks.get(i);
+            if (taskClass != null) {
+                try {
+                    task = taskClass.getConstructor().newInstance();
+                    if (task.acceptsUrl(url)) {
+                        future = task.loadUrl(new_layer, url, monitor);
+                    }
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+        if (future != null) {
+            Main.worker.submit(new PostDownloadHandler(task, future));
+        } else {
+            SwingUtilities.invokeLater(new Runnable() {
+                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);
+                }
+            });
+        }
+    }
+    
+    public boolean addDownloadTaskClass(Class<? extends DownloadTask> taskClass) {
+        return this.downloadTasks.add(taskClass);
     }
 }
Index: trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadGpsTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadGpsTask.java	(revision 4520)
+++ trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadGpsTask.java	(revision 4521)
@@ -9,4 +9,5 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.Bounds;
+import org.openstreetmap.josm.data.Bounds.ParseMethod;
 import org.openstreetmap.josm.data.gpx.GpxData;
 import org.openstreetmap.josm.gui.PleaseWaitRunnable;
@@ -15,4 +16,6 @@
 import org.openstreetmap.josm.gui.progress.ProgressMonitor;
 import org.openstreetmap.josm.io.BoundingBoxDownloader;
+import org.openstreetmap.josm.io.OsmServerLocationReader;
+import org.openstreetmap.josm.io.OsmServerReader;
 import org.openstreetmap.josm.io.OsmTransferException;
 import org.xml.sax.SAXException;
@@ -21,4 +24,8 @@
 
     private DownloadTask downloadTask;
+    
+    private static final String PATTERN_TRACE_ID = "http://.*openstreetmap.org/trace/\\p{Digit}+/data";
+    
+    private static final String PATTERN_TRACKPOINTS_BBOX = "http://.*/api/0.6/trackpoints\\?bbox=.*,.*,.*,.*";
 
     public Future<?> download(boolean newLayer, Bounds downloadArea, ProgressMonitor progressMonitor) {
@@ -30,7 +37,29 @@
     }
 
-    public Future<?> loadUrl(boolean a,java.lang.String b,  ProgressMonitor progressMonitor) {
+    public Future<?> loadUrl(boolean newLayer, String url, ProgressMonitor progressMonitor) {
+        if (url != null && url.matches(PATTERN_TRACE_ID)) {
+            downloadTask = new DownloadTask(newLayer,
+                    new OsmServerLocationReader(url), progressMonitor);
+            // We need submit instead of execute so we can wait for it to finish and get the error
+            // message if necessary. If no one calls getErrorMessage() it just behaves like execute.
+            return Main.worker.submit(downloadTask);
+            
+        } else if (url != null && url.matches(PATTERN_TRACKPOINTS_BBOX)) {
+            String[] table = url.split("\\?|=|&");
+            for (int i = 0; i<table.length; i++) {
+                if (table[i].equals("bbox") && i<table.length-1 ) {
+                    return download(newLayer, new Bounds(table[i+1], ",", ParseMethod.LEFT_BOTTOM_RIGHT_TOP), progressMonitor);
+                }
+            }
+        }
         return null;
-        // FIXME this is not currently used
+    }
+
+    /* (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));
     }
 
@@ -42,9 +71,9 @@
 
     class DownloadTask extends PleaseWaitRunnable {
-        private BoundingBoxDownloader reader;
+        private OsmServerReader reader;
         private GpxData rawData;
         private final boolean newLayer;
 
-        public DownloadTask(boolean newLayer, BoundingBoxDownloader reader, ProgressMonitor progressMonitor) {
+        public DownloadTask(boolean newLayer, OsmServerReader reader, ProgressMonitor progressMonitor) {
             super(tr("Downloading GPS data"));
             this.reader = reader;
Index: trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTask.java	(revision 4520)
+++ trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTask.java	(revision 4521)
@@ -64,4 +64,12 @@
         return Main.worker.submit(downloadTask);
     }
+    
+    /* (non-Javadoc)
+     * @see org.openstreetmap.josm.actions.downloadtasks.DownloadTask#acceptsUrl(java.lang.String)
+     */
+    @Override
+    public boolean acceptsUrl(String url) {
+        return url != null && url.matches("http://.*/api/0.6/(map|nodes?|ways?|relations?).*");
+    }
 
     public void cancel() {
Index: trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadTask.java	(revision 4520)
+++ trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadTask.java	(revision 4521)
@@ -65,4 +65,11 @@
      */
     Future<?> loadUrl(boolean newLayer, String url, ProgressMonitor progressMonitor);
+    
+    /**
+     * Returns true if the task is able to open the given URL, false otherwise.
+     * @param url the url to download from
+     * @return True if the task is able to open the given URL, false otherwise.
+     */
+    boolean acceptsUrl(String url);
 
     /**
Index: trunk/src/org/openstreetmap/josm/data/Bounds.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/Bounds.java	(revision 4520)
+++ trunk/src/org/openstreetmap/josm/data/Bounds.java	(revision 4521)
@@ -30,5 +30,10 @@
         return new LatLon(maxLat, maxLon);
     }
-
+    
+    public enum ParseMethod {
+        MINLAT_MINLON_MAXLAT_MAXLON,
+        LEFT_BOTTOM_RIGHT_TOP
+    }
+    
     /**
      * Construct bounds out of two points
@@ -60,8 +65,12 @@
 
     public Bounds(String asString, String separator) throws IllegalArgumentException {
+        this(asString, separator, ParseMethod.MINLAT_MINLON_MAXLAT_MAXLON);
+    }
+
+    public Bounds(String asString, String separator, ParseMethod parseMethod) throws IllegalArgumentException {
         CheckParameterUtil.ensureParameterNotNull(asString, "asString");
         String[] components = asString.split(separator);
         if (components.length != 4)
-            throw new IllegalArgumentException(MessageFormat.format("Exactly four doubles excpected in string, got {0}: {1}", components.length, asString));
+            throw new IllegalArgumentException(MessageFormat.format("Exactly four doubles expected in string, got {0}: {1}", components.length, asString));
         double[] values = new double[4];
         for (int i=0; i<4; i++) {
@@ -72,17 +81,38 @@
             }
         }
-        if (!LatLon.isValidLat(values[0]))
-            throw new IllegalArgumentException(tr("Illegal latitude value ''{0}''", values[0]));
-        if (!LatLon.isValidLon(values[1]))
-            throw new IllegalArgumentException(tr("Illegal longitude value ''{0}''", values[1]));
-        if (!LatLon.isValidLat(values[2]))
-            throw new IllegalArgumentException(tr("Illegal latitude value ''{0}''", values[2]));
-        if (!LatLon.isValidLon(values[3]))
-            throw new IllegalArgumentException(tr("Illegal latitude value ''{0}''", values[3]));
-
-        this.minLat = LatLon.roundToOsmPrecision(values[0]);
-        this.minLon = LatLon.roundToOsmPrecision(values[1]);
-        this.maxLat = LatLon.roundToOsmPrecision(values[2]);
-        this.maxLon = LatLon.roundToOsmPrecision(values[3]);
+        
+        int minLatIndex;
+        int minLonIndex;
+        int maxLatIndex;
+        int maxLonIndex;
+        
+        switch (parseMethod) {
+            case LEFT_BOTTOM_RIGHT_TOP:
+                minLatIndex = 1;
+                minLonIndex = 0;
+                maxLatIndex = 3;
+                maxLonIndex = 2;
+                break;
+            case MINLAT_MINLON_MAXLAT_MAXLON:
+            default:
+                minLatIndex = 0;
+                minLonIndex = 1;
+                maxLatIndex = 2;
+                maxLonIndex = 3;
+        }
+        
+        if (!LatLon.isValidLat(values[minLatIndex]))
+            throw new IllegalArgumentException(tr("Illegal latitude value ''{0}''", values[minLatIndex]));
+        if (!LatLon.isValidLon(values[minLonIndex]))
+            throw new IllegalArgumentException(tr("Illegal longitude value ''{0}''", values[minLonIndex]));
+        if (!LatLon.isValidLat(values[maxLatIndex]))
+            throw new IllegalArgumentException(tr("Illegal latitude value ''{0}''", values[maxLatIndex]));
+        if (!LatLon.isValidLon(values[maxLonIndex]))
+            throw new IllegalArgumentException(tr("Illegal longitude value ''{0}''", values[maxLonIndex]));
+
+        this.minLat = LatLon.roundToOsmPrecision(values[minLatIndex]);
+        this.minLon = LatLon.roundToOsmPrecision(values[minLonIndex]);
+        this.maxLat = LatLon.roundToOsmPrecision(values[maxLatIndex]);
+        this.maxLon = LatLon.roundToOsmPrecision(values[maxLonIndex]);
     }
 
Index: trunk/src/org/openstreetmap/josm/io/BoundingBoxDownloader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/BoundingBoxDownloader.java	(revision 4520)
+++ trunk/src/org/openstreetmap/josm/io/BoundingBoxDownloader.java	(revision 4521)
@@ -36,5 +36,6 @@
      *      ways.
      */
-    public GpxData parseRawGps(ProgressMonitor progressMonitor) throws IOException, SAXException,OsmTransferException {
+    @Override
+    public GpxData parseRawGps(ProgressMonitor progressMonitor) throws OsmTransferException {
         progressMonitor.beginTask("", 1);
         try {
@@ -70,11 +71,11 @@
             if (cancel)
                 return null;
-            throw new SAXException("Illegal characters within the HTTP-header response.", e);
+            throw new OsmTransferException("Illegal characters within the HTTP-header response.", e);
         } catch (IOException e) {
             if (cancel)
                 return null;
-            throw e;
+            throw new OsmTransferException(e);
         } catch (SAXException e) {
-            throw e;
+            throw new OsmTransferException(e);
         } catch (OsmTransferException e) {
             throw e;
Index: trunk/src/org/openstreetmap/josm/io/OsmServerLocationReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OsmServerLocationReader.java	(revision 4520)
+++ trunk/src/org/openstreetmap/josm/io/OsmServerLocationReader.java	(revision 4521)
@@ -6,4 +6,5 @@
 import java.io.InputStream;
 
+import org.openstreetmap.josm.data.gpx.GpxData;
 import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.gui.progress.ProgressMonitor;
@@ -39,11 +40,41 @@
             progressMonitor.finishTask();
             try {
+                activeConnection = null;
                 if (in != null) {
                     in.close();
                 }
-                activeConnection = null;
             } catch(Exception e) {/* ignore it */}
         }
     }
 
+    @Override
+    public GpxData parseRawGps(ProgressMonitor progressMonitor) throws OsmTransferException {
+        InputStream in = null;
+        progressMonitor.beginTask(tr("Contacting Server...", 10));
+        try {
+            in = getInputStreamRaw(url, progressMonitor.createSubTaskMonitor(1, true));
+            if (in == null)
+                return null;
+            progressMonitor.subTask(tr("Downloading OSM data..."));
+            GpxReader reader = new GpxReader(in);
+            reader.parse(false);
+            GpxData result = reader.data;
+            result.fromServer = true;
+            return result;
+        } catch(OsmTransferException e) {
+            throw e;
+        } catch (Exception e) {
+            if (cancel)
+                return null;
+            throw new OsmTransferException(e);
+        } finally {
+            progressMonitor.finishTask();
+            try {
+                activeConnection = null;
+                if (in != null) {
+                    in.close();
+                }
+            } catch(Exception e) {/* ignore it */}
+        }
+    }
 }
Index: trunk/src/org/openstreetmap/josm/io/OsmServerReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OsmServerReader.java	(revision 4520)
+++ trunk/src/org/openstreetmap/josm/io/OsmServerReader.java	(revision 4521)
@@ -16,4 +16,5 @@
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.gpx.GpxData;
 import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.gui.progress.ProgressMonitor;
@@ -141,4 +142,8 @@
     public abstract DataSet parseOsm(ProgressMonitor progressMonitor) throws OsmTransferException;
 
+    public GpxData parseRawGps(ProgressMonitor progressMonitor) throws OsmTransferException {
+        return null;
+    }
+    
     /**
      * Returns true if this reader is adding authentication credentials to the read
