Index: trunk/src/org/openstreetmap/josm/Main.java
===================================================================
--- trunk/src/org/openstreetmap/josm/Main.java	(revision 2326)
+++ trunk/src/org/openstreetmap/josm/Main.java	(revision 2327)
@@ -41,4 +41,5 @@
 import org.openstreetmap.josm.data.UndoRedoHandler;
 import org.openstreetmap.josm.data.coor.CoordinateFormat;
+import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.PrimitiveDeepCopy;
@@ -423,5 +424,5 @@
                 //DownloadTask osmTask = main.menu.download.downloadTasks.get(0);
                 DownloadTask osmTask = new DownloadOsmTask();
-                Future<?> future = osmTask.download(main.menu.download, b.min.lat(), b.min.lon(), b.max.lat(), b.max.lon(), null);
+                Future<?> future = osmTask.download(main.menu.download, b, null);
                 Main.worker.submit(new PostDownloadHandler(osmTask, future));
             }
@@ -467,8 +468,12 @@
         final StringTokenizer st = new StringTokenizer(s, ",");
         if (st.countTokens() == 4) {
+            Bounds b = new Bounds(
+                   new LatLon(Double.parseDouble(st.nextToken()),Double.parseDouble(st.nextToken())),
+                   new LatLon(Double.parseDouble(st.nextToken()),Double.parseDouble(st.nextToken()))
+                   );
             try {
                 DownloadTask task = rawGps ? new DownloadGpsTask() : new DownloadOsmTask();
                 // asynchronously launch the download task ...
-                Future<?> future = task.download(main.menu.download, Double.parseDouble(st.nextToken()), Double.parseDouble(st.nextToken()), Double.parseDouble(st.nextToken()), Double.parseDouble(st.nextToken()), null);
+                Future<?> future = task.download(main.menu.download, b, null);
                 // ... and the continuation when the download is finished (this will wait for the download to finish)
                 Main.worker.execute(new PostDownloadHandler(task, future));
Index: trunk/src/org/openstreetmap/josm/actions/DownloadAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/DownloadAction.java	(revision 2326)
+++ trunk/src/org/openstreetmap/josm/actions/DownloadAction.java	(revision 2327)
@@ -2,6 +2,6 @@
 package org.openstreetmap.josm.actions;
 
+import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
 import static org.openstreetmap.josm.tools.I18n.tr;
-import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
 
 import java.awt.BorderLayout;
@@ -15,5 +15,6 @@
 
 import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.actions.downloadtasks.DownloadTask;
+import org.openstreetmap.josm.actions.downloadtasks.DownloadGpsTask;
+import org.openstreetmap.josm.actions.downloadtasks.DownloadOsmTask;
 import org.openstreetmap.josm.actions.downloadtasks.PostDownloadHandler;
 import org.openstreetmap.josm.gui.ExtendedDialog;
@@ -31,6 +32,8 @@
  */
 public class DownloadAction extends JosmAction {
+    
 
     public DownloadDialog dialog;
+    private ExtendedDialog downloadDialog;
 
     public DownloadAction() {
@@ -45,5 +48,7 @@
      */
     protected ExtendedDialog createUploadDialog() {
-        dialog = new DownloadDialog();
+        if (dialog == null)
+            dialog = new DownloadDialog();
+        dialog.restoreSettings();
         JPanel downPanel = new JPanel(new BorderLayout());
         downPanel.add(dialog, BorderLayout.CENTER);
@@ -53,11 +58,13 @@
                 new Dimension(1000,600));
 
-        ExtendedDialog dialog = new ExtendedDialog(Main.parent,
+        if (downloadDialog == null) {
+            downloadDialog= new ExtendedDialog(Main.parent,
                 tr("Download"),
                 new String[] {tr("OK"), tr("Cancel")});
-        dialog.setContent(downPanel, false /* don't use a scroll pane inside the dialog */);
-        dialog.setButtonIcons(new String[] {"ok", "cancel"});
-        dialog.setRememberWindowGeometry(prefName, wg);
-        return dialog;
+            downloadDialog.setContent(downPanel, false /* don't use a scroll pane inside the dialog */);
+            downloadDialog.setButtonIcons(new String[] {"ok", "cancel"});
+            downloadDialog.setRememberWindowGeometry(prefName, wg);
+        }
+        return downloadDialog;
     }
 
@@ -65,18 +72,19 @@
         ExtendedDialog dlg = createUploadDialog();
         boolean finish = false;
-        while (!finish) {
+        while (!finish) {            
             dlg.showDialog();
-            Main.pref.put("download.newlayer", dialog.newLayer.isSelected());
             if (dlg.getValue() == 1 /* OK */) {
-                Main.pref.put("download.tab", Integer.toString(dialog.getSelectedTab()));
-                for (DownloadTask task : dialog.downloadTasks) {
-                    Main.pref.put("download."+task.getPreferencesSuffix(), task.getCheckBox().isSelected());
-                    if (task.getCheckBox().isSelected()) {
-                        // asynchronously launch the download task ...
-                        Future<?> future = task.download(this, dialog.minlat, dialog.minlon, dialog.maxlat, dialog.maxlon, null);
-                        // ... and the continuation when the download task is finished
-                        Main.worker.submit(new PostDownloadHandler(task, future));
-                        finish = true;
-                    }
+                dialog.rememberSettings();
+                if (dialog.isDownloadOsmData()) {
+                    DownloadOsmTask task = new DownloadOsmTask();
+                    Future<?> future = task.download(this, dialog.getSelectedDownloadArea(), null);
+                    Main.worker.submit(new PostDownloadHandler(task, future));
+                    finish = true;
+                }
+                if (dialog.isDownloadGpxData()) {
+                    DownloadGpsTask task = new DownloadGpsTask();
+                    Future<?> future = task.download(this,dialog.getSelectedDownloadArea(), null);
+                    Main.worker.submit(new PostDownloadHandler(task, future));
+                    finish = true;
                 }
             } else {
Index: trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadGpsTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadGpsTask.java	(revision 2326)
+++ trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadGpsTask.java	(revision 2327)
@@ -7,8 +7,7 @@
 import java.util.concurrent.Future;
 
-import javax.swing.JCheckBox;
-
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.actions.DownloadAction;
+import org.openstreetmap.josm.data.Bounds;
 import org.openstreetmap.josm.data.gpx.GpxData;
 import org.openstreetmap.josm.gui.PleaseWaitRunnable;
@@ -22,24 +21,14 @@
 public class DownloadGpsTask extends AbstractDownloadTask {
 
-    private JCheckBox checkBox = new JCheckBox(tr("Raw GPS data"));
     private DownloadTask downloadTask;
 
-    public Future<?> download(DownloadAction action, double minlat, double minlon,
-            double maxlat, double maxlon, ProgressMonitor progressMonitor) {
-        downloadTask = new DownloadTask(action.dialog.newLayer.isSelected(),
-                new BoundingBoxDownloader(minlat, minlon, maxlat, maxlon), progressMonitor);
+    public Future<?> download(DownloadAction action, Bounds downloadArea, ProgressMonitor progressMonitor) {
+        downloadTask = new DownloadTask(action.dialog.isNewLayerRequired(),
+                new BoundingBoxDownloader(downloadArea), 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);
     }
-
-    public JCheckBox getCheckBox() {
-        return checkBox;
-    }
-
-    public String getPreferencesSuffix() {
-        return "gps";
-    }
-
+    
     public Future<?> loadUrl(boolean a,java.lang.String b,  ProgressMonitor progressMonitor) {
         return null;
Index: trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTask.java	(revision 2326)
+++ trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTask.java	(revision 2327)
@@ -8,6 +8,4 @@
 import java.util.concurrent.Future;
 import java.util.logging.Logger;
-
-import javax.swing.JCheckBox;
 
 import org.openstreetmap.josm.Main;
@@ -38,6 +36,4 @@
     private DownloadTask downloadTask;
 
-    private JCheckBox checkBox = new JCheckBox(tr("OpenStreetMap data"), true);
-
     private void rememberDownloadedData(DataSet ds) {
         this.downloadedData = ds;
@@ -48,22 +44,12 @@
     }
 
-    public Future<?> download(DownloadAction action, double minlat, double minlon,
-            double maxlat, double maxlon, ProgressMonitor progressMonitor) {
-        // Swap min and max if user has specified them the wrong way round
-        // (easy to do if you are crossing 0, for example)
-        // FIXME should perhaps be done in download dialog?
-        if (minlat > maxlat) {
-            double t = minlat; minlat = maxlat; maxlat = t;
-        }
-        if (minlon > maxlon) {
-            double t = minlon; minlon = maxlon; maxlon = t;
-        }
-
+    public Future<?> download(DownloadAction action, Bounds downloadArea, ProgressMonitor progressMonitor) {
+       
         boolean newLayer = action != null
-        && (action.dialog == null || action.dialog.newLayer.isSelected());
+        && (action.dialog == null || action.dialog.isNewLayerRequired());
 
         downloadTask = new DownloadTask(newLayer,
-                new BoundingBoxDownloader(minlat, minlon, maxlat, maxlon), progressMonitor);
-        currentBounds = new Bounds(new LatLon(minlat, minlon), new LatLon(maxlat, maxlon));
+                new BoundingBoxDownloader(downloadArea), progressMonitor);
+        currentBounds = new Bounds(downloadArea);
         // 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.
@@ -82,12 +68,4 @@
         currentBounds = new Bounds(new LatLon(0,0), new LatLon(0,0));
         return Main.worker.submit(downloadTask);
-    }
-
-    public JCheckBox getCheckBox() {
-        return checkBox;
-    }
-
-    public String getPreferencesSuffix() {
-        return "osm";
     }
 
Index: trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTaskList.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTaskList.java	(revision 2326)
+++ trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTaskList.java	(revision 2327)
@@ -21,4 +21,5 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.actions.UpdateSelectionAction;
+import org.openstreetmap.josm.data.Bounds;
 import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
@@ -65,5 +66,5 @@
             childProgress.setSilent(true);
             childProgress.setCustomText(tr("Download {0} of {1} ({2} left)", i, rects.size(), rects.size() - i));
-            Future<?> future = dt.download(null, td.getMinY(), td.getMinX(), td.getMaxY(), td.getMaxX(), childProgress);
+            Future<?> future = dt.download(null, new Bounds(td), childProgress);
             osmTaskFutures.add(future);
             osmTasks.add(dt);
Index: trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadTask.java	(revision 2326)
+++ trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadTask.java	(revision 2327)
@@ -5,7 +5,6 @@
 import java.util.concurrent.Future;
 
-import javax.swing.JCheckBox;
-
 import org.openstreetmap.josm.actions.DownloadAction;
+import org.openstreetmap.josm.data.Bounds;
 import org.openstreetmap.josm.gui.progress.ProgressMonitor;
 
@@ -16,6 +15,5 @@
      * if no error messages should be popped up.
      */
-    Future<?> download(DownloadAction action, double minlat, double minlon,
-            double maxlat, double maxlon, ProgressMonitor progressMonitor);
+    Future<?> download(DownloadAction action, Bounds downloadArea, ProgressMonitor progressMonitor);
 
     /**
@@ -25,15 +23,4 @@
      */
     Future<?> loadUrl(boolean newLayer, String url, ProgressMonitor progressMonitor);
-
-    /**
-     * @return The checkbox presented to the user
-     */
-    JCheckBox getCheckBox();
-
-    /**
-     * @return The name of the preferences suffix to use for storing the
-     * selection state.
-     */
-    String getPreferencesSuffix();
 
     /**
Index: trunk/src/org/openstreetmap/josm/actions/downloadtasks/PostDownloadHandler.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/downloadtasks/PostDownloadHandler.java	(revision 2326)
+++ trunk/src/org/openstreetmap/josm/actions/downloadtasks/PostDownloadHandler.java	(revision 2327)
@@ -4,5 +4,7 @@
 import static org.openstreetmap.josm.tools.I18n.tr;
 
+import java.util.ArrayList;
 import java.util.LinkedHashSet;
+import java.util.List;
 import java.util.concurrent.Future;
 
@@ -16,5 +18,5 @@
 public class PostDownloadHandler implements Runnable {
     private DownloadTask task;
-    private Future<?> future;
+    private List<Future<?>> futures;
 
     /**
@@ -25,15 +27,48 @@
     public PostDownloadHandler(DownloadTask task, Future<?> future) {
         this.task = task;
-        this.future = future;
+        this.futures = new ArrayList<Future<?>>();
+        if (future != null) {
+            this.futures.add(future);
+        }
     }
 
+    /**
+     * constructor
+     * @param task the asynchronous download task
+     * @param future the future on which the completion of the download task can be synchronized
+     */
+    public PostDownloadHandler(DownloadTask task, Future<?> ... futures) {
+        this.task = task;
+        this.futures = new ArrayList<Future<?>>();
+        if (futures == null) return;
+        for (Future<?> future: futures) {
+            this.futures.add(future);
+        }
+    }
+    
+
+    /**
+     * constructor
+     * @param task the asynchronous download task
+     * @param future the future on which the completion of the download task can be synchronized
+     */
+    public PostDownloadHandler(DownloadTask task, List<Future<?>> futures) {
+        this.task = task;
+        this.futures = new ArrayList<Future<?>>();
+        if (futures == null) return;
+        this.futures.addAll(futures);
+    }
+    
     public void run() {
-        // wait for the download task to complete
+        // wait for all downloads task to finish (by waiting for the futures
+        // to return a value)
         //
-        try {
-            future.get();
-        } catch(Exception e) {
-            e.printStackTrace();
-            return;
+        for (Future<?> future: futures) {
+            try {
+                future.get();
+            } catch(Exception e) {
+                e.printStackTrace();
+                return;
+            }
         }
 
Index: trunk/src/org/openstreetmap/josm/data/Bounds.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/Bounds.java	(revision 2326)
+++ trunk/src/org/openstreetmap/josm/data/Bounds.java	(revision 2327)
@@ -4,5 +4,7 @@
 import java.awt.geom.Rectangle2D;
 
+import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.coor.LatLon;
+import static org.openstreetmap.josm.tools.I18n.tr;
 
 /**
@@ -16,5 +18,13 @@
      * The minimum and maximum coordinates.
      */
-    public LatLon min, max;
+    private LatLon min, max;
+    
+    public LatLon getMin() {
+        return min;
+    }
+
+    public LatLon getMax() {
+        return max;
+    }
 
     /**
@@ -30,5 +40,48 @@
         this.max = b;
     }
+    
+    public Bounds(double minlat, double minlon, double maxlat, double maxlon) {
+        this.min = new LatLon(minlat, minlon);
+        this.max = new LatLon(maxlat, maxlon);
+    }
+    
+    public Bounds(double [] coords) {
+        if (coords == null)
+            throw new IllegalArgumentException(tr("Parameter ''{0}'' must not be null", "coords"));
+        if (coords.length != 4)
+            throw new IllegalArgumentException(tr("Expected array of length 4, got {0}", coords.length));
+        this.min = new LatLon(coords[0], coords[1]);
+        this.max = new LatLon(coords[2], coords[3]);
+    }
+    
+    public Bounds(String asString, String separator) throws IllegalArgumentException {
+        if (asString == null)
+            throw new IllegalArgumentException(tr("Parameter ''{0}'' must not be null", "asString"));
+        String[] components = asString.split(separator);
+        if (components.length != 4) {
+            throw new IllegalArgumentException(tr("Exactly four doubles excpected in string, got {0}", components.length));
+        }
+        double[] values = new double[4];
+        for (int i=0; i<4; i++) {
+            try {
+                values[i] = Double.parseDouble(components[i]);
+            } catch(NumberFormatException e) {
+                throw new IllegalArgumentException(tr("Illegal double value ''{0}''", components[i]));
+            }
+        }
+        this.min = new LatLon(values[0], values[1]);
+        this.max = new LatLon(values[2], values[3]);
+    }
+    
+    public Bounds(Bounds other) {
+        this.min = new LatLon(other.min);
+        this.max = new LatLon(other.max);
+    }
 
+    public Bounds(Rectangle2D rect) {
+        this.min = new LatLon(rect.getMinY(), rect.getMinX());
+        this.max = new LatLon(rect.getMaxY(), rect.getMaxX());
+    }
+    
     @Override public String toString() {
         return "Bounds["+min.lat()+","+min.lon()+","+max.lat()+","+max.lon()+"]";
@@ -70,4 +123,47 @@
         return new Rectangle2D.Double(min.lon(), min.lat(), max.lon()-min.lon(), max.lat()-min.lat());
     }
+    
+    public double getArea() {
+        return (max.lon() - min.lon()) * (max.lat() - min.lat());
+    }
+
+    public String encodeAsString(String separator) {
+        StringBuffer sb = new StringBuffer();
+        sb.append(min.lat()).append(separator).append(min.lon())
+        .append(separator).append(max.lat()).append(separator)
+        .append(max.lon());
+        return sb.toString();
+    }
+    
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime * result + ((max == null) ? 0 : max.hashCode());
+        result = prime * result + ((min == null) ? 0 : min.hashCode());
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        Bounds other = (Bounds) obj;
+        if (max == null) {
+            if (other.max != null)
+                return false;
+        } else if (!max.equals(other.max))
+            return false;
+        if (min == null) {
+            if (other.min != null)
+                return false;
+        } else if (!min.equals(other.min))
+            return false;
+        return true;
+    }
 
 }
Index: trunk/src/org/openstreetmap/josm/data/Preferences.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/Preferences.java	(revision 2326)
+++ trunk/src/org/openstreetmap/josm/data/Preferences.java	(revision 2327)
@@ -62,9 +62,32 @@
         public String name;
         public double[] latlon = new double[4]; // minlat, minlon, maxlat, maxlon
+        
+        public Bookmark() {           
+        }
+        
+        public Bookmark(Bounds b) {
+            if (b == null) {
+                latlon[0] = 0.0;
+                latlon[1] = 0.0;
+                latlon[2] = 0.0;
+                latlon[3] = 0.0;
+            } else {
+                latlon[0] = b.getMin().lat();
+                latlon[1] = b.getMin().lon();
+                latlon[2] = b.getMax().lat();
+                latlon[3] = b.getMax().lon();
+            }
+        }
+        
         @Override public String toString() {
             return name;
         }
+                
         public int compareTo(Bookmark b) {
             return name.toLowerCase().compareTo(b.name.toLowerCase());
+        }
+        
+        public Bounds asBounds() {
+            return new Bounds(latlon[0], latlon[1], latlon[2], latlon[3]);
         }
     }
Index: trunk/src/org/openstreetmap/josm/data/coor/Coordinate.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/coor/Coordinate.java	(revision 2326)
+++ trunk/src/org/openstreetmap/josm/data/coor/Coordinate.java	(revision 2327)
@@ -45,3 +45,30 @@
     }
 
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = super.hashCode();
+        long temp;
+        temp = java.lang.Double.doubleToLongBits(x);
+        result = prime * result + (int) (temp ^ (temp >>> 32));
+        temp = java.lang.Double.doubleToLongBits(y);
+        result = prime * result + (int) (temp ^ (temp >>> 32));
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (!super.equals(obj))
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        Coordinate other = (Coordinate) obj;
+        if (java.lang.Double.doubleToLongBits(x) != java.lang.Double.doubleToLongBits(other.x))
+            return false;
+        if (java.lang.Double.doubleToLongBits(y) != java.lang.Double.doubleToLongBits(other.y))
+            return false;
+        return true;
+    }
 }
Index: trunk/src/org/openstreetmap/josm/data/coor/LatLon.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/coor/LatLon.java	(revision 2326)
+++ trunk/src/org/openstreetmap/josm/data/coor/LatLon.java	(revision 2327)
@@ -90,6 +90,6 @@
     public boolean isOutSideWorld() {
         Bounds b = Main.proj.getWorldBoundsLatLon();
-        return lat() < b.min.lat() || lat() > b.max.lat() ||
-        lon() < b.min.lon() || lon() > b.max.lon();
+        return lat() < b.getMin().lat() || lat() > b.getMax().lat() ||
+        lon() < b.getMin().lon() || lon() > b.getMax().lon();
     }
 
@@ -98,5 +98,5 @@
      */
     public boolean isWithin(Bounds b) {
-        return lat() >= b.min.lat() && lat() <= b.max.lat() && lon() > b.min.lon() && lon() < b.max.lon();
+        return lat() >= b.getMin().lat() && lat() <= b.getMax().lat() && lon() > b.getMin().lon() && lon() < b.getMax().lon();
     }
 
Index: trunk/src/org/openstreetmap/josm/data/osm/visitor/BoundingXYVisitor.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/visitor/BoundingXYVisitor.java	(revision 2326)
+++ trunk/src/org/openstreetmap/josm/data/osm/visitor/BoundingXYVisitor.java	(revision 2327)
@@ -45,6 +45,6 @@
         if(b != null)
         {
-            visit(b.min);
-            visit(b.max);
+            visit(b.getMin());
+            visit(b.getMax());
         }
     }
Index: trunk/src/org/openstreetmap/josm/gui/MapView.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/MapView.java	(revision 2326)
+++ trunk/src/org/openstreetmap/josm/gui/MapView.java	(revision 2327)
@@ -369,13 +369,13 @@
         tempG.setColor(Color.WHITE);
         Bounds b = getProjection().getWorldBoundsLatLon();
-        double lat = b.min.lat();
-        double lon = b.min.lon();
-
-        Point p = getPoint(b.min);
+        double lat = b.getMin().lat();
+        double lon = b.getMin().lon();
+
+        Point p = getPoint(b.getMin());
 
         GeneralPath path = new GeneralPath();
 
         path.moveTo(p.x, p.y);
-        double max = b.max.lat();
+        double max = b.getMax().lat();
         for(; lat <= max; lat += 1.0)
         {
@@ -383,5 +383,5 @@
             path.lineTo(p.x, p.y);
         }
-        lat = max; max = b.max.lon();
+        lat = max; max = b.getMax().lon();
         for(; lon <= max; lon += 1.0)
         {
@@ -389,5 +389,5 @@
             path.lineTo(p.x, p.y);
         }
-        lon = max; max = b.min.lat();
+        lon = max; max = b.getMin().lat();
         for(; lat >= max; lat -= 1.0)
         {
@@ -395,5 +395,5 @@
             path.lineTo(p.x, p.y);
         }
-        lat = max; max = b.min.lon();
+        lat = max; max = b.getMin().lon();
         for(; lon >= max; lon -= 1.0)
         {
Index: trunk/src/org/openstreetmap/josm/gui/NavigatableComponent.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/NavigatableComponent.java	(revision 2326)
+++ trunk/src/org/openstreetmap/josm/gui/NavigatableComponent.java	(revision 2327)
@@ -60,6 +60,6 @@
     private EastNorth calculateDefaultCenter() {
         Bounds b = Main.proj.getWorldBoundsLatLon();
-        double lat = (b.max.lat() + b.min.lat())/2;
-        double lon = (b.max.lon() + b.min.lon())/2;
+        double lat = (b.getMax().lat() + b.getMin().lat())/2;
+        double lon = (b.getMax().lon() + b.getMin().lon())/2;
 
         return Main.proj.latlon2eastNorth(new LatLon(lat, lon));
@@ -128,6 +128,6 @@
     public ProjectionBounds getMaxProjectionBounds() {
         Bounds b = getProjection().getWorldBoundsLatLon();
-        return new ProjectionBounds(getProjection().latlon2eastNorth(b.min),
-                getProjection().latlon2eastNorth(b.max));
+        return new ProjectionBounds(getProjection().latlon2eastNorth(b.getMin()),
+                getProjection().latlon2eastNorth(b.getMax()));
     }
 
@@ -193,8 +193,8 @@
         double lat = cl.lat();
         double lon = cl.lon();
-        if(lat < b.min.lat()) {changed = true; lat = b.min.lat(); }
-        else if(lat > b.max.lat()) {changed = true; lat = b.max.lat(); }
-        if(lon < b.min.lon()) {changed = true; lon = b.min.lon(); }
-        else if(lon > b.max.lon()) {changed = true; lon = b.max.lon(); }
+        if(lat < b.getMin().lat()) {changed = true; lat = b.getMin().lat(); }
+        else if(lat > b.getMax().lat()) {changed = true; lat = b.getMax().lat(); }
+        if(lon < b.getMin().lon()) {changed = true; lon = b.getMin().lon(); }
+        else if(lon > b.getMax().lon()) {changed = true; lon = b.getMax().lon(); }
         if(changed) {
             newCenter = new CachedLatLon(lat, lon).getEastNorth();
@@ -209,6 +209,6 @@
         int width = getWidth()/2;
         int height = getHeight()/2;
-        LatLon l1 = new LatLon(b.min.lat(), lon);
-        LatLon l2 = new LatLon(b.max.lat(), lon);
+        LatLon l1 = new LatLon(b.getMin().lat(), lon);
+        LatLon l2 = new LatLon(b.getMax().lat(), lon);
         EastNorth e1 = getProjection().latlon2eastNorth(l1);
         EastNorth e2 = getProjection().latlon2eastNorth(l2);
@@ -217,6 +217,6 @@
         {
             double newScaleH = d/height;
-            e1 = getProjection().latlon2eastNorth(new LatLon(lat, b.min.lon()));
-            e2 = getProjection().latlon2eastNorth(new LatLon(lat, b.max.lon()));
+            e1 = getProjection().latlon2eastNorth(new LatLon(lat, b.getMin().lon()));
+            e2 = getProjection().latlon2eastNorth(new LatLon(lat, b.getMax().lon()));
             d = e2.east() - e1.east();
             if(d < width*newScale) {
@@ -292,6 +292,6 @@
 
     public void zoomTo(Bounds box) {
-        zoomTo(new ProjectionBounds(getProjection().latlon2eastNorth(box.min),
-                getProjection().latlon2eastNorth(box.max)));
+        zoomTo(new ProjectionBounds(getProjection().latlon2eastNorth(box.getMin()),
+                getProjection().latlon2eastNorth(box.getMax())));
     }
 
Index: trunk/src/org/openstreetmap/josm/gui/download/BookmarkSelection.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/download/BookmarkSelection.java	(revision 2326)
+++ trunk/src/org/openstreetmap/josm/gui/download/BookmarkSelection.java	(revision 2327)
@@ -8,7 +8,4 @@
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
-import java.awt.event.MouseAdapter;
-import java.awt.event.MouseEvent;
-import java.awt.event.MouseListener;
 
 import javax.swing.DefaultListModel;
@@ -42,5 +39,5 @@
 
         JPanel dlg = new JPanel(new GridBagLayout());
-        gui.tabpane.addTab(tr("Bookmarks"), dlg);
+        gui.addDownloadAreaSelector(dlg, tr("Bookmarks"));
 
         bookmarks = new BookmarkList();
@@ -49,9 +46,5 @@
                 Preferences.Bookmark b = (Preferences.Bookmark)bookmarks.getSelectedValue();
                 if (b != null) {
-                    gui.minlat = b.latlon[0];
-                    gui.minlon = b.latlon[1];
-                    gui.maxlat = b.latlon[2];
-                    gui.maxlon = b.latlon[3];
-                    gui.boundingBoxChanged(BookmarkSelection.this);
+                    gui.boundingBoxChanged(b.asBounds(),BookmarkSelection.this);
                 }
             }
@@ -108,9 +101,5 @@
 
     public void boundingBoxChanged(DownloadDialog gui) {
-        tempBookmark = new Preferences.Bookmark();
-        tempBookmark.latlon[0] = gui.minlat;
-        tempBookmark.latlon[1] = gui.minlon;
-        tempBookmark.latlon[2] = gui.maxlat;
-        tempBookmark.latlon[3] = gui.maxlon;
+        tempBookmark = new Preferences.Bookmark(gui.getSelectedDownloadArea());
         bookmarks.clearSelection();
     }
Index: trunk/src/org/openstreetmap/josm/gui/download/BoundingBoxSelection.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/download/BoundingBoxSelection.java	(revision 2326)
+++ trunk/src/org/openstreetmap/josm/gui/download/BoundingBoxSelection.java	(revision 2327)
@@ -9,6 +9,4 @@
 import java.awt.event.FocusEvent;
 import java.awt.event.FocusListener;
-import java.awt.event.KeyEvent;
-import java.awt.event.KeyListener;
 
 import javax.swing.JLabel;
@@ -56,8 +54,8 @@
                             double maxlat = Double.parseDouble(latlon[2].getText());
                             double maxlon = Double.parseDouble(latlon[3].getText());
-                            if (minlat != gui.minlat || minlon != gui.minlon || maxlat != gui.maxlat || maxlon != gui.maxlon) {
-                                gui.minlat = minlat; gui.minlon = minlon;
-                                gui.maxlat = maxlat; gui.maxlon = maxlon;
-                                gui.boundingBoxChanged(BoundingBoxSelection.this);
+                            Bounds b = new Bounds(minlat,minlon, maxlat,maxlon);
+                            if (gui.getSelectedDownloadArea() == null) return;
+                            if (gui.getSelectedDownloadArea() == null || !gui.getSelectedDownloadArea().equals(new Bounds(minlat,minlon, maxlat,maxlon))) {
+                                gui.boundingBoxChanged(b, BoundingBoxSelection.this);
                             }
                         } catch (NumberFormatException x) {
@@ -119,5 +117,5 @@
         });
 
-        gui.tabpane.addTab(tr("Bounding Box"), dlg);
+        gui.addDownloadAreaSelector(dlg, tr("Bounding Box"));
     }
 
@@ -132,10 +130,6 @@
     private boolean parseURL(DownloadDialog gui) {
         Bounds b = OsmUrlToBounds.parse(osmUrl.getText());
-        if(b == null) return false;
-        gui.minlon = b.min.lon();
-        gui.minlat = b.min.lat();
-        gui.maxlon = b.max.lon();
-        gui.maxlat = b.max.lat();
-        gui.boundingBoxChanged(BoundingBoxSelection.this);
+        if(b == null) return false;        
+        gui.boundingBoxChanged(b,BoundingBoxSelection.this);
         updateBboxFields(gui);
         updateUrl(gui);
@@ -144,8 +138,10 @@
 
     private void updateBboxFields(DownloadDialog gui) {
-        latlon[0].setText(Double.toString(gui.minlat));
-        latlon[1].setText(Double.toString(gui.minlon));
-        latlon[2].setText(Double.toString(gui.maxlat));
-        latlon[3].setText(Double.toString(gui.maxlon));
+        Bounds b = gui.getSelectedDownloadArea();
+        if (b == null) return;
+        latlon[0].setText(Double.toString(b.getMin().lat()));
+        latlon[1].setText(Double.toString(b.getMin().lon()));
+        latlon[2].setText(Double.toString(b.getMax().lat()));
+        latlon[3].setText(Double.toString(b.getMax().lon()));
         for (JTextField f : latlon) {
             f.setCaretPosition(0);
@@ -154,6 +150,6 @@
 
     private void updateUrl(DownloadDialog gui) {
-        showUrl.setText(OsmUrlToBounds.getURL(new Bounds(
-                new LatLon(gui.minlat, gui.minlon), new LatLon(gui.maxlat, gui.maxlon))));
+        if (gui.getSelectedDownloadArea() == null) return;
+        showUrl.setText(OsmUrlToBounds.getURL(gui.getSelectedDownloadArea()));
     }
 }
Index: trunk/src/org/openstreetmap/josm/gui/download/DownloadDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/download/DownloadDialog.java	(revision 2326)
+++ trunk/src/org/openstreetmap/josm/gui/download/DownloadDialog.java	(revision 2327)
@@ -15,4 +15,5 @@
 import java.util.ArrayList;
 import java.util.List;
+import java.util.logging.Logger;
 
 import javax.swing.AbstractAction;
@@ -24,11 +25,6 @@
 
 import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.actions.DownloadAction;
-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.data.Bounds;
 import org.openstreetmap.josm.gui.MapView;
-import org.openstreetmap.josm.gui.progress.ProgressMonitor;
 import org.openstreetmap.josm.plugins.PluginHandler;
 import org.openstreetmap.josm.tools.GBC;
@@ -46,21 +42,15 @@
  */
 public class DownloadDialog extends JPanel {
-
-    /**
-     * The list of download tasks. First entry should be the osm data entry
-     * and the second the gps entry. After that, plugins can register additional
-     * download possibilities.
-     */
-    public final List<DownloadTask> downloadTasks = new ArrayList<DownloadTask>(5);
-
-    public final List<DownloadSelection> downloadSelections = new ArrayList<DownloadSelection>();
-    public final JTabbedPane tabpane = new JTabbedPane();
-    public final JCheckBox newLayer;
-    public final JLabel sizeCheck = new JLabel();
-
-    public double minlon;
-    public double minlat;
-    public double maxlon;
-    public double maxlat;
+    static private final Logger logger = Logger.getLogger(DownloadDialog.class.getName());
+
+    private final List<DownloadSelection> downloadSelections = new ArrayList<DownloadSelection>();
+    private final JTabbedPane tpDownloadAreaSelectors = new JTabbedPane();
+    private final JCheckBox cbNewLayer;
+    private final JLabel sizeCheck = new JLabel();
+
+    private Bounds currentBounds = null;
+
+    private JCheckBox cbDownloadOsmData = new JCheckBox(tr("OpenStreetMap data"), true);
+    private JCheckBox cbDownloadGpxData = new JCheckBox(tr("Raw GPS data"));
 
 
@@ -68,17 +58,9 @@
         setLayout(new GridBagLayout());
 
-        downloadTasks.add(new DownloadOsmTask());
-        downloadTasks.add(new DownloadGpsTask());
-
         // adding the download tasks
         add(new JLabel(tr("Data Sources and Types")), GBC.eol().insets(0,5,0,0));
-        for (DownloadTask task : downloadTasks) {
-            add(task.getCheckBox(), GBC.eol().insets(20,0,0,0));
-            // don't override defaults, if we (initially) don't have any preferences
-            if(Main.pref.hasKey("download."+task.getPreferencesSuffix())) {
-                task.getCheckBox().setSelected(Main.pref.getBoolean("download."+task.getPreferencesSuffix()));
-            }
-        }
-
+        add(cbDownloadOsmData,  GBC.eol().insets(20,0,0,0));
+        add(cbDownloadGpxData,  GBC.eol().insets(20,0,0,0));
+        
         // predefined download selections
         downloadSelections.add(new SlippyMapChooser());
@@ -97,36 +79,13 @@
             s.addGui(this);
         }
-
-        if (Main.map != null) {
-            MapView mv = Main.map.mapView;
-            minlon = mv.getLatLon(0, mv.getHeight()).lon();
-            minlat = mv.getLatLon(0, mv.getHeight()).lat();
-            maxlon = mv.getLatLon(mv.getWidth(), 0).lon();
-            maxlat = mv.getLatLon(mv.getWidth(), 0).lat();
-            boundingBoxChanged(null);
-        }
-        else if (Main.pref.hasKey("osm-download.bounds")) {
-            // read the bounding box from the preferences
-            try {
-                String bounds[] = Main.pref.get("osm-download.bounds").split(";");
-                minlat = Double.parseDouble(bounds[0]);
-                minlon = Double.parseDouble(bounds[1]);
-                maxlat = Double.parseDouble(bounds[2]);
-                maxlon = Double.parseDouble(bounds[3]);
-                boundingBoxChanged(null);
-            }
-            catch (Exception e) {
-                e.printStackTrace();
-            }
-        }
-
-        newLayer = new JCheckBox(tr("Download as new layer"), Main.pref.getBoolean("download.newlayer", false));
-        add(newLayer, GBC.eol().insets(0,5,0,0));
+   
+        cbNewLayer = new JCheckBox(tr("Download as new layer"));
+        add(cbNewLayer, GBC.eol().insets(0,5,0,0));
 
         add(new JLabel(tr("Download Area")), GBC.eol().insets(0,5,0,0));
-        add(tabpane, GBC.eol().fill());
+        add(tpDownloadAreaSelectors, GBC.eol().fill());
 
         try {
-            tabpane.setSelectedIndex(Main.pref.getInteger("download.tab", 0));
+            tpDownloadAreaSelectors.setSelectedIndex(Main.pref.getInteger("download.tab", 0));
         } catch (Exception ex) {
             Main.pref.putInteger("download.tab", 0);
@@ -145,4 +104,6 @@
             }
         });
+        
+        restoreSettings();
     }
 
@@ -163,14 +124,13 @@
         Bounds b = OsmUrlToBounds.parse(result);
         if (b != null) {
-            minlon = b.min.lon();
-            minlat = b.min.lat();
-            maxlon = b.max.lon();
-            maxlat = b.max.lat();
-            boundingBoxChanged(null);
+            boundingBoxChanged(new Bounds(b),null);
         }
     }
 
     private void updateSizeCheck() {
-        if ((maxlon-minlon)*(maxlat-minlat) > Main.pref.getDouble("osm-server.max-request-area", 0.25)) {
+        if (currentBounds == null) {
+            sizeCheck.setText(tr("No area selected yet"));
+            sizeCheck.setForeground(Color.darkGray);
+        } else if (currentBounds.getArea() > Main.pref.getDouble("osm-server.max-request-area", 0.25)) {
             sizeCheck.setText(tr("Download area too large; will probably be rejected by server"));
             sizeCheck.setForeground(Color.red);
@@ -188,5 +148,6 @@
      * @param eventSource - the DownloadSelection object that fired this notification.
      */
-    public void boundingBoxChanged(DownloadSelection eventSource) {
+    public void boundingBoxChanged(Bounds b, DownloadSelection eventSource) {
+        this.currentBounds = b;
         for (DownloadSelection s : downloadSelections) {
             if (s != eventSource) {
@@ -196,10 +157,93 @@
         updateSizeCheck();
     }
-
-    /*
-     * Returns currently selected tab.
-     */
-    public int getSelectedTab() {
-        return tabpane.getSelectedIndex();
-    }
+    
+    /**
+     * Replies true if the user selected to download OSM data
+     * 
+     * @return true if the user selected to download OSM data
+     */
+    public boolean isDownloadOsmData() {
+        return cbDownloadOsmData.isSelected();
+    }
+    
+    /**
+     * Replies true if the user selected to download GPX data
+     * 
+     * @return true if the user selected to download GPX data
+     */
+    public boolean isDownloadGpxData() {
+        return cbDownloadGpxData.isSelected();
+    }
+    
+    /**
+     * Replies true if the user requires to download into a new layer 
+     * 
+     * @return true if the user requires to download into a new layer 
+     */
+    public boolean isNewLayerRequired() {
+        return cbNewLayer.isSelected();
+    }
+    
+    /**
+     * Adds a new download area selector to the download dialog
+     * 
+     * @param selector the download are selector 
+     * @param displayName the display name of the selector
+     */
+    public void addDownloadAreaSelector(JPanel selector, String displayName) {
+        tpDownloadAreaSelectors.add(displayName, selector);
+    }
+    
+    /**
+     * Remembers the current settings in the download dialog 
+     * 
+     */
+    public void rememberSettings() {
+        Main.pref.put("download.tab", Integer.toString(tpDownloadAreaSelectors.getSelectedIndex()));
+        Main.pref.put("download.osm", cbDownloadOsmData.isSelected());
+        Main.pref.put("download.gps", cbDownloadGpxData.isSelected());
+        Main.pref.put("download.newlayer", cbNewLayer.isSelected());
+        if (currentBounds != null) {
+            Main.pref.put("osm-download.bounds", currentBounds.encodeAsString(";"));
+        }
+    }
+    
+    public void restoreSettings() {
+        cbDownloadOsmData.setSelected(Main.pref.getBoolean("download.osm", true));
+        cbDownloadGpxData.setSelected(Main.pref.getBoolean("download.gps", false));
+        cbNewLayer.setSelected(Main.pref.getBoolean("download.newlayer", false));
+        int idx = Main.pref.getInteger("download.tab", 0);
+        if (idx < 0 || idx > tpDownloadAreaSelectors.getTabCount()) {
+            idx = 0;
+        }
+        tpDownloadAreaSelectors.setSelectedIndex(idx);
+        
+        if (Main.map != null) {
+            MapView mv = Main.map.mapView;
+            currentBounds = new Bounds(
+                    mv.getLatLon(0, mv.getHeight()),
+                    mv.getLatLon(mv.getWidth(), 0)                    
+                    );
+            boundingBoxChanged(currentBounds,null);
+        }
+        else if (Main.pref.hasKey("osm-download.bounds")) {
+            // read the bounding box from the preferences
+            try {
+                currentBounds = new Bounds(Main.pref.get("osm-download.bounds"), ";");
+                boundingBoxChanged(currentBounds,null);
+            }
+            catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+    }
+    
+    /**
+     * Replies the currently selected download area. May be null, if no download area is selected
+     * yet.
+     */
+    public Bounds getSelectedDownloadArea() {
+        return currentBounds;
+    }
+    
 }
Index: trunk/src/org/openstreetmap/josm/gui/download/PlaceSelection.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/download/PlaceSelection.java	(revision 2326)
+++ trunk/src/org/openstreetmap/josm/gui/download/PlaceSelection.java	(revision 2327)
@@ -32,4 +32,6 @@
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.Bounds;
+import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.tools.GBC;
 import org.xml.sax.Attributes;
@@ -224,5 +226,5 @@
         scrollPane.setPreferredSize(new Dimension(200,200));
         panel.add(scrollPane, c);
-        gui.tabpane.add(panel, tr("Places"));
+        gui.addDownloadAreaSelector(panel, tr("Places"));
 
         scrollPane.setPreferredSize(scrollPane.getPreferredSize());
@@ -298,10 +300,16 @@
                 {
                     double size = 180.0 / Math.pow(2, r.zoom);
-                    gui.minlat = r.lat - size / 2;
-                    gui.maxlat = r.lat + size / 2;
-                    gui.minlon = r.lon - size;
-                    gui.maxlon = r.lon + size;
+                    Bounds b = new Bounds(
+                        new LatLon(
+                            r.lat - size / 2,
+                            r.lat + size / 2
+                         ),
+                         new LatLon(
+                            r.lon - size,
+                            r.lon + size
+                         )
+                    );
                     updatingSelf = true;
-                    gui.boundingBoxChanged(null);
+                    gui.boundingBoxChanged(b,null);
                     updatingSelf = false;
                 }
Index: trunk/src/org/openstreetmap/josm/gui/download/SlippyMapChooser.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/download/SlippyMapChooser.java	(revision 2326)
+++ trunk/src/org/openstreetmap/josm/gui/download/SlippyMapChooser.java	(revision 2327)
@@ -30,4 +30,6 @@
 import org.openstreetmap.gui.jmapviewer.interfaces.TileSource;
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.Bounds;
+import org.openstreetmap.josm.data.coor.LatLon;
 
 /**
@@ -120,6 +122,6 @@
         String labelText = tr("<b>Zoom:</b> Mousewheel, double click or Ctrl + Up/Down "
                 + "<b>Move map:</b> Hold right mousebutton and move mouse or use cursor keys. <b>Select:</b> Hold left mousebutton and draw a frame.");
-        slipyyMapTabPanel.add(new JLabel("<html>" + labelText + "</html>"), BorderLayout.SOUTH);
-        iGui.tabpane.add(slipyyMapTabPanel, tr("Slippy map"));
+        slipyyMapTabPanel.add(new JLabel("<html>" + labelText + "</html>"), BorderLayout.SOUTH);        
+        iGui.addDownloadAreaSelector(slipyyMapTabPanel, tr("Slippy map"));
         new OsmMapControl(this, slipyyMapTabPanel, iSizeButton, iSourceButton);
     }
@@ -165,13 +167,16 @@
 
     public void boundingBoxChanged(DownloadDialog gui) {
-
+        Bounds b = gui.getSelectedDownloadArea();
+        if (b == null)
+            return;
+        
         // test if a bounding box has been set set
-        if (gui.minlat == 0.0 && gui.minlon == 0.0 && gui.maxlat == 0.0 && gui.maxlon == 0.0)
+        if (b.getMin().lat() == 0.0 && b.getMin().lon() == 0.0 && b.getMax().lat() == 0.0 && b.getMax().lon() == 0.0)
             return;
 
-        int y1 = OsmMercator.LatToY(gui.minlat, MAX_ZOOM);
-        int y2 = OsmMercator.LatToY(gui.maxlat, MAX_ZOOM);
-        int x1 = OsmMercator.LonToX(gui.minlon, MAX_ZOOM);
-        int x2 = OsmMercator.LonToX(gui.maxlon, MAX_ZOOM);
+        int y1 = OsmMercator.LatToY(b.getMin().lat(), MAX_ZOOM);
+        int y2 = OsmMercator.LatToY(b.getMax().lat(), MAX_ZOOM);
+        int x1 = OsmMercator.LonToX(b.getMin().lon(), MAX_ZOOM);
+        int x2 = OsmMercator.LonToX(b.getMax().lon(), MAX_ZOOM);
 
         iSelectionRectStart = new Point(Math.min(x1, x2), Math.min(y1, y2));
@@ -179,6 +184,6 @@
 
         // calc the screen coordinates for the new selection rectangle
-        MapMarkerDot xmin_ymin = new MapMarkerDot(gui.minlat, gui.minlon);
-        MapMarkerDot xmax_ymax = new MapMarkerDot(gui.maxlat, gui.maxlon);
+        MapMarkerDot xmin_ymin = new MapMarkerDot(b.getMin());
+        MapMarkerDot xmax_ymax = new MapMarkerDot(b.getMax());
 
         Vector<MapMarker> marker = new Vector<MapMarker>(2);
@@ -218,10 +223,14 @@
         Coordinate l1 = getPosition(p_max);
         Coordinate l2 = getPosition(p_min);
-        iGui.minlon = Math.min(l2.getLon(), l1.getLon());
-        iGui.minlat = Math.min(l1.getLat(), l2.getLat());
-        iGui.maxlon = Math.max(l2.getLon(), l1.getLon());
-        iGui.maxlat = Math.max(l1.getLat(), l2.getLat());
-
-        iGui.boundingBoxChanged(this);
+        Bounds b = new Bounds(
+                new LatLon(
+                        Math.min(l2.getLat(), l1.getLat()), 
+                        Math.min(l1.getLon(), l2.getLon())
+                        ),
+                new LatLon(
+                        Math.max(l2.getLat(), l1.getLat()), 
+                        Math.max(l1.getLon(), l2.getLon()))
+                );
+        iGui.boundingBoxChanged(b, this);
         repaint();
     }
Index: trunk/src/org/openstreetmap/josm/gui/download/TileSelection.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/download/TileSelection.java	(revision 2326)
+++ trunk/src/org/openstreetmap/josm/gui/download/TileSelection.java	(revision 2327)
@@ -16,4 +16,6 @@
 import javax.swing.SpinnerNumberModel;
 
+import org.openstreetmap.josm.data.Bounds;
+import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.tools.GBC;
 /**
@@ -65,9 +67,9 @@
                     if (toy<fromy) { int i = fromy; fromy=toy; toy=i; }
 
-                    gui.minlat = tileYToLat(zoomlvl, toy+1);
-                    gui.minlon = tileXToLon(zoomlvl, fromx);
-                    gui.maxlat = tileYToLat(zoomlvl, fromy);
-                    gui.maxlon = tileXToLon(zoomlvl, tox+1);
-                    gui.boundingBoxChanged(TileSelection.this);
+                    Bounds b = new Bounds(
+                            new LatLon(tileYToLat(zoomlvl, toy + 1), tileXToLon(zoomlvl, fromx)),
+                            new LatLon(tileYToLat(zoomlvl, fromy), tileXToLon(zoomlvl, tox + 1))
+                            );
+                    gui.boundingBoxChanged(b, TileSelection.this);
                     //repaint();
                 } catch (NumberFormatException x) {
@@ -82,5 +84,5 @@
         }
 
-        gui.tabpane.addTab(tr("Tile Numbers"), smpanel);
+        gui.addDownloadAreaSelector(smpanel, tr("Tile Numbers"));
     }
 
@@ -94,8 +96,11 @@
     private void updateBboxFields(DownloadDialog gui) {
         int z = ((Integer) tileZ.getValue()).intValue();
-        tileX0.setText(Integer.toString(lonToTileX(z, gui.minlon)));
-        tileX1.setText(Integer.toString(lonToTileX(z, gui.maxlon-.00001)));
-        tileY0.setText(Integer.toString(latToTileY(z, gui.maxlat-.00001)));
-        tileY1.setText(Integer.toString(latToTileY(z, gui.minlat)));
+        Bounds b = gui.getSelectedDownloadArea();
+        if (b == null)
+            return;
+        tileX0.setText(Integer.toString(lonToTileX(z, b.getMin().lon())));
+        tileX1.setText(Integer.toString(lonToTileX(z, b.getMax().lon()-.00001)));
+        tileY0.setText(Integer.toString(latToTileY(z, b.getMax().lat()-.00001)));
+        tileY1.setText(Integer.toString(latToTileY(z, b.getMin().lat())));
     }
 
Index: trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java	(revision 2326)
+++ trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java	(revision 2327)
@@ -226,7 +226,7 @@
             // now succesively subtract downloaded areas
             for (DataSource src : data.dataSources) {
-                if (src.bounds != null && !src.bounds.min.equals(src.bounds.max)) {
-                    EastNorth en1 = mv.getProjection().latlon2eastNorth(src.bounds.min);
-                    EastNorth en2 = mv.getProjection().latlon2eastNorth(src.bounds.max);
+                if (src.bounds != null && !src.bounds.getMin().equals(src.bounds.getMax())) {
+                    EastNorth en1 = mv.getProjection().latlon2eastNorth(src.bounds.getMin());
+                    EastNorth en2 = mv.getProjection().latlon2eastNorth(src.bounds.getMax());
                     Point p1 = mv.getPoint(en1);
                     Point p2 = mv.getPoint(en2);
Index: trunk/src/org/openstreetmap/josm/gui/preferences/ProjectionPreference.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/ProjectionPreference.java	(revision 2326)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/ProjectionPreference.java	(revision 2327)
@@ -97,5 +97,5 @@
         Bounds b = Main.proj.getWorldBoundsLatLon();
         CoordinateFormat cf = CoordinateFormat.getDefaultFormat();
-        bounds.setText(b.min.latToString(cf)+"; "+b.min.lonToString(cf)+" : "+b.max.latToString(cf)+"; "+b.max.lonToString(cf));
+        bounds.setText(b.getMin().latToString(cf)+"; "+b.getMin().lonToString(cf)+" : "+b.getMax().latToString(cf)+"; "+b.getMax().lonToString(cf));
         /* TODO: Fix bugs, refresh code line and world bounds, fix design (e.g. add border around sub-prefs-stuff */
     }
Index: trunk/src/org/openstreetmap/josm/io/BoundingBoxDownloader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/BoundingBoxDownloader.java	(revision 2326)
+++ trunk/src/org/openstreetmap/josm/io/BoundingBoxDownloader.java	(revision 2327)
@@ -7,5 +7,5 @@
 import java.io.InputStream;
 
-import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.Bounds;
 import org.openstreetmap.josm.data.gpx.GpxData;
 import org.openstreetmap.josm.data.osm.DataSet;
@@ -24,12 +24,9 @@
     private final double lon2;
 
-    public BoundingBoxDownloader(double lat1, double lon1, double lat2, double lon2) {
-        this.lat1 = lat1;
-        this.lon1 = lon1;
-        this.lat2 = lat2;
-        this.lon2 = lon2;
-        // store the bounding box in the preferences so it can be
-        // re-used across invocations of josm
-        Main.pref.put("osm-download.bounds", lat1+";"+lon1+";"+lat2+";"+lon2);
+    public BoundingBoxDownloader(Bounds downloadArea) {
+        this.lat1 = downloadArea.getMin().lat();
+        this.lon1 = downloadArea.getMin().lon();
+        this.lat2 = downloadArea.getMax().lat();
+        this.lon2 = downloadArea.getMax().lon();
     }
 
@@ -44,5 +41,5 @@
         try {
             progressMonitor.indeterminateSubTask(tr("Contacting OSM Server..."));
-            String url = "trackpoints?bbox="+lon1+","+lat1+","+lon2+","+lat2+"&page=";
+            String url = "trackpoints?bbox="+lon1+","+lat1+","+lon2+","+lat2+"&page=";            
 
             boolean done = false;
Index: trunk/src/org/openstreetmap/josm/io/GpxWriter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/GpxWriter.java	(revision 2326)
+++ trunk/src/org/openstreetmap/josm/io/GpxWriter.java	(revision 2327)
@@ -127,6 +127,6 @@
         if(bounds != null)
         {
-            String b = "minlat=\"" + bounds.min.lat() + "\" minlon=\"" + bounds.min.lon() +
-                "\" maxlat=\"" + bounds.max.lat() + "\" maxlon=\"" + bounds.max.lon() + "\"" ;
+            String b = "minlat=\"" + bounds.getMin().lat() + "\" minlon=\"" + bounds.getMin().lon() +
+                "\" maxlat=\"" + bounds.getMax().lat() + "\" maxlon=\"" + bounds.getMax().lon() + "\"" ;
             inline("bounds", b);
         }
Index: trunk/src/org/openstreetmap/josm/io/OsmWriter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OsmWriter.java	(revision 2326)
+++ trunk/src/org/openstreetmap/josm/io/OsmWriter.java	(revision 2327)
@@ -93,8 +93,8 @@
         for (DataSource s : ds.dataSources) {
             out.println("  <bounds minlat='"
-                    + s.bounds.min.lat()+"' minlon='"
-                    + s.bounds.min.lon()+"' maxlat='"
-                    + s.bounds.max.lat()+"' maxlon='"
-                    + s.bounds.max.lon()
+                    + s.bounds.getMin().lat()+"' minlon='"
+                    + s.bounds.getMin().lon()+"' maxlat='"
+                    + s.bounds.getMax().lat()+"' maxlon='"
+                    + s.bounds.getMax().lon()
                     +"' origin='"+XmlWriter.encode(s.origin)+"' />");
         }
Index: trunk/src/org/openstreetmap/josm/tools/OsmUrlToBounds.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/OsmUrlToBounds.java	(revision 2326)
+++ trunk/src/org/openstreetmap/josm/tools/OsmUrlToBounds.java	(revision 2327)
@@ -59,7 +59,7 @@
     static public int getZoom(Bounds b) {
         // convert to mercator (for calculation of zoom only)
-        double latMin = Math.log(Math.tan(Math.PI/4.0+b.min.lat()/180.0*Math.PI/2.0))*180.0/Math.PI;
-        double latMax = Math.log(Math.tan(Math.PI/4.0+b.max.lat()/180.0*Math.PI/2.0))*180.0/Math.PI;
-        double size = Math.max(Math.abs(latMax-latMin), Math.abs(b.max.lon()-b.min.lon()));
+        double latMin = Math.log(Math.tan(Math.PI/4.0+b.getMin().lat()/180.0*Math.PI/2.0))*180.0/Math.PI;
+        double latMax = Math.log(Math.tan(Math.PI/4.0+b.getMax().lat()/180.0*Math.PI/2.0))*180.0/Math.PI;
+        double size = Math.max(Math.abs(latMax-latMin), Math.abs(b.getMax().lon()-b.getMin().lon()));
         int zoom = 0;
         while (zoom <= 20) {
