Index: trunk/src/org/openstreetmap/josm/actions/OpenLocationAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/OpenLocationAction.java	(revision 5316)
+++ trunk/src/org/openstreetmap/josm/actions/OpenLocationAction.java	(revision 5317)
@@ -23,4 +23,5 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.actions.downloadtasks.DownloadGpsTask;
+import org.openstreetmap.josm.actions.downloadtasks.DownloadOsmBzip2Task;
 import org.openstreetmap.josm.actions.downloadtasks.DownloadOsmChangeTask;
 import org.openstreetmap.josm.actions.downloadtasks.DownloadOsmTask;
@@ -55,4 +56,5 @@
         addDownloadTaskClass(DownloadOsmChangeTask.class);
         addDownloadTaskClass(DownloadOsmUrlTask.class);
+        addDownloadTaskClass(DownloadOsmBzip2Task.class);
     }
 
Index: trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmBzip2Task.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmBzip2Task.java	(revision 5317)
+++ trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmBzip2Task.java	(revision 5317)
@@ -0,0 +1,55 @@
+// License: GPL. Copyright 2007 by Immanuel Scholz and others
+package org.openstreetmap.josm.actions.downloadtasks;
+
+import java.util.concurrent.Future;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.Bounds;
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.gui.progress.ProgressMonitor;
+import org.openstreetmap.josm.io.OsmBzip2Importer;
+import org.openstreetmap.josm.io.OsmServerLocationReader;
+import org.openstreetmap.josm.io.OsmTransferException;
+
+public class DownloadOsmBzip2Task extends DownloadOsmTask {
+    
+    OsmBzip2Importer importer;
+    
+    /* (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://.*/.*\\.osm.bz2?"); // Remote .osm.bz / .osm.bz2 files
+    }
+    
+    /* (non-Javadoc)
+     * @see org.openstreetmap.josm.actions.downloadtasks.DownloadOsmTask#download(boolean, org.openstreetmap.josm.data.Bounds, org.openstreetmap.josm.gui.progress.ProgressMonitor)
+     */
+    @Override
+    public Future<?> download(boolean newLayer, Bounds downloadArea,
+            ProgressMonitor progressMonitor) {
+        return null;
+    }
+    
+    /**
+     * Loads a given URL
+     * @param True if the data should be saved to a new layer
+     * @param The URL as String
+     */
+    public Future<?> loadUrl(boolean new_layer, String url, ProgressMonitor progressMonitor) {
+        downloadTask = new DownloadTask(new_layer, new OsmServerLocationReader(url), progressMonitor) {
+            @Override
+            protected DataSet parseDataSet() throws OsmTransferException {
+                return reader.parseOsmBzip2(progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false));
+            }
+        };
+        currentBounds = null;
+        // Extract .osm.bz/bz2 filename from URL to set the new layer name
+        Matcher matcher = Pattern.compile("http://.*/(.*\\.osm.bz2?)").matcher(url);
+        newLayerName = matcher.matches() ? matcher.group(1) : null;
+        return Main.worker.submit(downloadTask);
+    }
+}
Index: trunk/src/org/openstreetmap/josm/io/OsmBzip2Importer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OsmBzip2Importer.java	(revision 5316)
+++ trunk/src/org/openstreetmap/josm/io/OsmBzip2Importer.java	(revision 5317)
@@ -8,4 +8,5 @@
 import java.io.FileInputStream;
 import java.io.IOException;
+import java.io.InputStream;
 
 import org.apache.tools.bzip2.CBZip2InputStream;
@@ -22,5 +23,12 @@
     @Override
     public void importData(File file, ProgressMonitor progressMonitor) throws IOException, IllegalDataException {
-        BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
+        importData(getBZip2InputStream(new FileInputStream(file)), file);
+    }
+    
+    public static CBZip2InputStream getBZip2InputStream(InputStream in) throws IOException {
+        if (in == null) {
+            return null;
+        }
+        BufferedInputStream bis = new BufferedInputStream(in);
         int b = bis.read();
         if (b != 'B')
@@ -29,6 +37,5 @@
         if (b != 'Z')
             throw new IOException(tr("Invalid bz2 file."));
-        CBZip2InputStream in = new CBZip2InputStream(bis);
-        importData(in, file);
+        return new CBZip2InputStream(bis);
     }
 }
Index: trunk/src/org/openstreetmap/josm/io/OsmServerLocationReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OsmServerLocationReader.java	(revision 5316)
+++ trunk/src/org/openstreetmap/josm/io/OsmServerLocationReader.java	(revision 5317)
@@ -4,13 +4,16 @@
 import static org.openstreetmap.josm.tools.I18n.tr;
 
+import java.io.IOException;
 import java.io.InputStream;
 
+import org.apache.tools.bzip2.CBZip2InputStream;
 import org.openstreetmap.josm.data.gpx.GpxData;
 import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.gui.progress.ProgressMonitor;
+import org.xml.sax.SAXException;
 
 public class OsmServerLocationReader extends OsmServerReader {
 
-    String url;
+    protected final String url;
 
     public OsmServerLocationReader(String url) {
@@ -18,17 +21,13 @@
     }
 
-    /**
-     * Method to download OSM files from somewhere
-     */
-    @Override
-    public DataSet parseOsm(ProgressMonitor progressMonitor) throws OsmTransferException {
-        InputStream in = null;
+    protected abstract class Parser<T> {
+        public InputStream in = null;
+        public abstract T parse() throws OsmTransferException, IllegalDataException, IOException, SAXException;
+    }
+
+    protected final <T> T doParse(Parser<T> parser, final ProgressMonitor progressMonitor) throws OsmTransferException {
         progressMonitor.beginTask(tr("Contacting Server...", 10));
         try {
-            in = getInputStreamRaw(url, progressMonitor.createSubTaskMonitor(9, false));
-            if (in == null)
-                return null;
-            progressMonitor.subTask(tr("Downloading OSM data..."));
-            return OsmReader.parseDataSet(in, progressMonitor.createSubTaskMonitor(1, false));
+            return parser.parse();
         } catch(OsmTransferException e) {
             throw e;
@@ -41,9 +40,45 @@
             try {
                 activeConnection = null;
-                if (in != null) {
-                    in.close();
+                if (parser.in != null) {
+                    parser.in.close();
+                    parser.in = null;
                 }
             } catch(Exception e) {/* ignore it */}
         }
+    }
+
+    /**
+     * Method to download OSM files from somewhere
+     */
+    @Override
+    public DataSet parseOsm(final ProgressMonitor progressMonitor) throws OsmTransferException {
+        return doParse(new Parser<DataSet>() {
+            @Override
+            public DataSet parse() throws OsmTransferException, IllegalDataException {
+                in = getInputStreamRaw(url, progressMonitor.createSubTaskMonitor(9, false));
+                if (in == null)
+                    return null;
+                progressMonitor.subTask(tr("Downloading OSM data..."));
+                return OsmReader.parseDataSet(in, progressMonitor.createSubTaskMonitor(1, false));
+            }
+        }, progressMonitor);
+    }
+
+    /**
+     * Method to download BZip2-compressed OSM files from somewhere
+     */
+    @Override
+    public DataSet parseOsmBzip2(final ProgressMonitor progressMonitor) throws OsmTransferException {
+        return doParse(new Parser<DataSet>() {
+            @Override
+            public DataSet parse() throws OsmTransferException, IllegalDataException, IOException {
+                in = getInputStreamRaw(url, progressMonitor.createSubTaskMonitor(9, false));
+                if (in == null)
+                    return null;
+                CBZip2InputStream bzin = OsmBzip2Importer.getBZip2InputStream(in);
+                progressMonitor.subTask(tr("Downloading OSM data..."));
+                return OsmReader.parseDataSet(bzin, progressMonitor.createSubTaskMonitor(1, false));
+            }
+        }, progressMonitor);
     }
 
@@ -52,60 +87,34 @@
      */
     @Override
-    public DataSet parseOsmChange(ProgressMonitor progressMonitor)
+    public DataSet parseOsmChange(final ProgressMonitor progressMonitor)
             throws OsmTransferException {
-        InputStream in = null;
-        progressMonitor.beginTask(tr("Contacting Server...", 10));
-        try {
-            in = getInputStreamRaw(url, progressMonitor.createSubTaskMonitor(9, false));
-            if (in == null)
-                return null;
-            progressMonitor.subTask(tr("Downloading OSM data..."));
-            return OsmChangeReader.parseDataSet(in, progressMonitor.createSubTaskMonitor(1, false));
-        } 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 */}
-        }
+        return doParse(new Parser<DataSet>() {
+            @Override
+            public DataSet parse() throws OsmTransferException, IllegalDataException {
+                in = getInputStreamRaw(url, progressMonitor.createSubTaskMonitor(9, false));
+                if (in == null)
+                    return null;
+                progressMonitor.subTask(tr("Downloading OSM data..."));
+                return OsmChangeReader.parseDataSet(in, progressMonitor.createSubTaskMonitor(1, false));
+            }
+        }, progressMonitor);
     }
 
     @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 */}
-        }
+    public GpxData parseRawGps(final ProgressMonitor progressMonitor) throws OsmTransferException {
+        return doParse(new Parser<GpxData>() {
+            @Override
+            public GpxData parse() throws OsmTransferException, IllegalDataException, IOException, SAXException {
+                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;
+            }
+        }, progressMonitor);
     }
 }
Index: trunk/src/org/openstreetmap/josm/io/OsmServerReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OsmServerReader.java	(revision 5316)
+++ trunk/src/org/openstreetmap/josm/io/OsmServerReader.java	(revision 5317)
@@ -144,11 +144,15 @@
     }
 
-    public abstract DataSet parseOsm(ProgressMonitor progressMonitor) throws OsmTransferException;
+    public abstract DataSet parseOsm(final ProgressMonitor progressMonitor) throws OsmTransferException;
 
-    public DataSet parseOsmChange(ProgressMonitor progressMonitor) throws OsmTransferException {
+    public DataSet parseOsmChange(final ProgressMonitor progressMonitor) throws OsmTransferException {
         return null;
     }
     
-    public GpxData parseRawGps(ProgressMonitor progressMonitor) throws OsmTransferException {
+    public GpxData parseRawGps(final ProgressMonitor progressMonitor) throws OsmTransferException {
+        return null;
+    }
+
+    public DataSet parseOsmBzip2(final ProgressMonitor progressMonitor) throws OsmTransferException {
         return null;
     }
