Index: src/org/openstreetmap/josm/actions/AutoScaleAction.java
===================================================================
--- src/org/openstreetmap/josm/actions/AutoScaleAction.java	(revision 8145)
+++ src/org/openstreetmap/josm/actions/AutoScaleAction.java	(working copy)
@@ -7,11 +7,15 @@
 
 import java.awt.event.ActionEvent;
 import java.awt.event.KeyEvent;
+import java.awt.geom.Area;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
+import java.util.ListIterator;
+import java.util.concurrent.TimeUnit;
 
 import javax.swing.JOptionPane;
 import javax.swing.event.ListSelectionEvent;
@@ -21,6 +25,7 @@
 
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.Bounds;
+import org.openstreetmap.josm.data.DataSource;
 import org.openstreetmap.josm.data.conflict.Conflict;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.visitor.BoundingXYVisitor;
@@ -30,7 +35,6 @@
 import org.openstreetmap.josm.gui.MapView;
 import org.openstreetmap.josm.gui.dialogs.LayerListDialog;
 import org.openstreetmap.josm.gui.dialogs.ValidatorDialog.ValidatorBoundingXYVisitor;
-import org.openstreetmap.josm.gui.download.DownloadDialog;
 import org.openstreetmap.josm.gui.layer.Layer;
 import org.openstreetmap.josm.tools.Shortcut;
 
@@ -41,20 +45,25 @@
 public class AutoScaleAction extends JosmAction {
 
     public static final Collection<String> MODES = Collections.unmodifiableList(Arrays.asList(
-        marktr(/* ICON(dialogs/autoscale/) */ "data"),
-        marktr(/* ICON(dialogs/autoscale/) */ "layer"),
-        marktr(/* ICON(dialogs/autoscale/) */ "selection"),
-        marktr(/* ICON(dialogs/autoscale/) */ "conflict"),
-        marktr(/* ICON(dialogs/autoscale/) */ "download"),
-        marktr(/* ICON(dialogs/autoscale/) */ "problem"),
-        marktr(/* ICON(dialogs/autoscale/) */ "previous"),
-        marktr(/* ICON(dialogs/autoscale/) */ "next")));
+            marktr(/* ICON(dialogs/autoscale/) */"data"), marktr(/* ICON(dialogs/autoscale/) */"layer"),
+            marktr(/* ICON(dialogs/autoscale/) */"selection"), marktr(/* ICON(dialogs/autoscale/) */"conflict"),
+            marktr(/* ICON(dialogs/autoscale/) */"download"), marktr(/* ICON(dialogs/autoscale/) */"problem"),
+            marktr(/* ICON(dialogs/autoscale/) */"previous"), marktr(/* ICON(dialogs/autoscale/) */"next")));
 
     private final String mode;
 
     protected ZoomChangeAdapter zoomChangeAdapter;
     protected MapFrameAdapter mapFrameAdapter;
+    protected DataSource previousDataSource;
+    protected Collection<DataSource> dataSources;
+    protected ArrayList<DataSource> dataSourcesList;
+    protected int firstPass = 0;
+    protected long lastZoomTime = -1;
 
+    private long timeDifference;
+
+    private long seconds;
+
     /**
      * Zooms the current map view to the currently selected primitives.
      * Does nothing if there either isn't a current map view or if there isn't a current data
@@ -62,15 +71,12 @@
      *
      */
     public static void zoomToSelection() {
-        if (Main.main == null || !Main.main.hasEditLayer()) return;
+        if (Main.main == null || !Main.main.hasEditLayer())
+            return;
         Collection<OsmPrimitive> sel = Main.main.getEditLayer().data.getSelected();
         if (sel.isEmpty()) {
-            JOptionPane.showMessageDialog(
-                    Main.parent,
-                    tr("Nothing selected to zoom to."),
-                    tr("Information"),
-                    JOptionPane.INFORMATION_MESSAGE
-            );
+            JOptionPane.showMessageDialog(Main.parent, tr("Nothing selected to zoom to."), tr("Information"),
+                    JOptionPane.INFORMATION_MESSAGE);
             return;
         }
         zoomTo(sel);
@@ -97,14 +103,23 @@
 
         // TODO: convert this to switch/case and make sure the parsing still works
         /* leave as single line for shortcut overview parsing! */
-        if (mode.equals("data")) { shortcut = KeyEvent.VK_1; }
-        else if (mode.equals("layer")) { shortcut = KeyEvent.VK_2; }
-        else if (mode.equals("selection")) { shortcut = KeyEvent.VK_3; }
-        else if (mode.equals("conflict")) { shortcut = KeyEvent.VK_4; }
-        else if (mode.equals("download")) { shortcut = KeyEvent.VK_5; }
-        else if (mode.equals("problem")) { shortcut = KeyEvent.VK_6; }
-        else if (mode.equals("previous")) { shortcut = KeyEvent.VK_8; }
-        else if (mode.equals("next")) { shortcut = KeyEvent.VK_9; }
+        if (mode.equals("data")) {
+            shortcut = KeyEvent.VK_1;
+        } else if (mode.equals("layer")) {
+            shortcut = KeyEvent.VK_2;
+        } else if (mode.equals("selection")) {
+            shortcut = KeyEvent.VK_3;
+        } else if (mode.equals("conflict")) {
+            shortcut = KeyEvent.VK_4;
+        } else if (mode.equals("download")) {
+            shortcut = KeyEvent.VK_5;
+        } else if (mode.equals("problem")) {
+            shortcut = KeyEvent.VK_6;
+        } else if (mode.equals("previous")) {
+            shortcut = KeyEvent.VK_8;
+        } else if (mode.equals("next")) {
+            shortcut = KeyEvent.VK_9;
+        }
 
         return shortcut;
     }
@@ -124,9 +139,9 @@
      * @param mode The autoscale mode (one of {@link AutoScaleAction#MODES})
      */
     public AutoScaleAction(final String mode) {
-        super(tr("Zoom to {0}", tr(mode)), "dialogs/autoscale/" + mode, tr("Zoom the view to {0}.", tr(mode)),
-                Shortcut.registerShortcut("view:zoom"+mode, tr("View: {0}", tr("Zoom to {0}", tr(mode))), getModeShortcut(mode), Shortcut.DIRECT),
-                true, null, false);
+        super(tr("Zoom to {0}", tr(mode)), "dialogs/autoscale/" + mode, tr("Zoom the view to {0}.", tr(mode)), Shortcut
+                .registerShortcut("view:zoom" + mode, tr("View: {0}", tr("Zoom to {0}", tr(mode))),
+                        getModeShortcut(mode), Shortcut.DIRECT), true, null, false);
         String modeHelp = Character.toUpperCase(mode.charAt(0)) + mode.substring(1);
         putValue("help", "Action/AutoScale/" + modeHelp);
         this.mode = mode;
@@ -156,14 +171,14 @@
             putValue("help", ht("/Action/ZoomToNext"));
             break;
         default:
-            throw new IllegalArgumentException("Unknown mode: "+mode);
+            throw new IllegalArgumentException("Unknown mode: " + mode);
         }
         installAdapters();
     }
 
-    public void autoScale()  {
+    public void autoScale() {
         if (Main.isDisplayingMapView()) {
-            switch(mode) {
+            switch (mode) {
             case "previous":
                 Main.map.mapView.zoomPrevious();
                 break;
@@ -194,7 +209,8 @@
      */
     protected Layer getFirstSelectedLayer() {
         List<Layer> layers = LayerListDialog.getInstance().getModel().getSelectedLayers();
-        if (layers.isEmpty()) return null;
+        if (layers.isEmpty())
+            return null;
         return layers.get(0);
     }
 
@@ -201,12 +217,14 @@
     private BoundingXYVisitor getBoundingBox() {
         BoundingXYVisitor v = "problem".equals(mode) ? new ValidatorBoundingXYVisitor() : new BoundingXYVisitor();
 
-        switch(mode) {
+        switch (mode) {
         case "problem":
             TestError error = Main.map.validatorDialog.getSelectedError();
-            if (error == null) return null;
+            if (error == null)
+                return null;
             ((ValidatorBoundingXYVisitor) v).visit(error);
-            if (v.getBounds() == null) return null;
+            if (v.getBounds() == null)
+                return null;
             v.enlargeBoundingBox(Main.pref.getDouble("validator.zoom-enlarge-bbox", 0.0002));
             break;
         case "data":
@@ -219,7 +237,8 @@
                 return null;
             // try to zoom to the first selected layer
             Layer l = getFirstSelectedLayer();
-            if (l == null) return null;
+            if (l == null)
+                return null;
             l.visitBoundingBox(v);
             break;
         case "selection":
@@ -236,12 +255,9 @@
                 }
             }
             if (sel.isEmpty()) {
-                JOptionPane.showMessageDialog(
-                        Main.parent,
-                        ("selection".equals(mode) ? tr("Nothing selected to zoom to.") : tr("No conflicts to zoom to")),
-                        tr("Information"),
-                        JOptionPane.INFORMATION_MESSAGE
-                );
+                JOptionPane
+                        .showMessageDialog(Main.parent, ("selection".equals(mode) ? tr("Nothing selected to zoom to.")
+                                : tr("No conflicts to zoom to")), tr("Information"), JOptionPane.INFORMATION_MESSAGE);
                 return null;
             }
             for (OsmPrimitive osm : sel) {
@@ -255,10 +271,47 @@
             v.enlargeToMinSize(Main.pref.getDouble("zoom_to_selection_min_size_in_meter", 100));
             break;
         case "download":
-            Bounds bounds = DownloadDialog.getSavedDownloadBounds();
+
+            if (lastZoomTime == -1) {
+                seconds = 0;
+            } else {
+                timeDifference = System.currentTimeMillis() - lastZoomTime;
+                seconds = TimeUnit.MILLISECONDS.toSeconds(timeDifference);
+            }
+
+            Bounds bounds;
+            dataSources = Main.main.getCurrentDataSet().getDataSources();
+            dataSourcesList = new ArrayList<>(dataSources);
+            System.out.println(seconds);
+            //Calculate time difference. If greater than thirty seconds reset to last download
+            if (seconds > 30) {
+                previousDataSource = dataSourcesList.listIterator(dataSourcesList.size()).previous();
+                v.visit(previousDataSource.bounds);
+                lastZoomTime = System.currentTimeMillis();
+                return v;
+            }
+
+            if (firstPass == 0) {
+                previousDataSource = dataSourcesList.listIterator(dataSourcesList.size()).previous();
+                firstPass = 2;
+            }
+            if (firstPass == 3) {
+                final Area dataSourceArea = Main.main.getCurrentDataSet().getDataSourceArea();
+                bounds = new Bounds(dataSourceArea.getBounds2D());
+                firstPass = 1;
+            } else {
+                getPreviousData();
+                bounds = previousDataSource.bounds;
+            }
+
+            if (previousDataSource == dataSourcesList.listIterator(1).previous()) {
+                firstPass++;
+            }
+
             if (bounds != null) {
                 try {
                     v.visit(bounds);
+                    lastZoomTime = System.currentTimeMillis();
                 } catch (Exception e) {
                     Main.warn(e);
                 }
@@ -268,11 +321,26 @@
         return v;
     }
 
+    public void getPreviousData() {
+        for (ListIterator<DataSource> iterator = dataSourcesList.listIterator(dataSourcesList.size()); iterator
+                .hasPrevious();) {
+            DataSource currentSource = iterator.previous();
+            if (currentSource.equals(previousDataSource)) {
+                if (iterator.hasPrevious()) {
+                    previousDataSource = iterator.previous();
+                } else {
+                    previousDataSource = dataSourcesList.listIterator(dataSourcesList.size()).previous();
+                }
+                return;
+            }
+        }
+    }
+
     @Override
     protected void updateEnabledState() {
-        switch(mode) {
+        switch (mode) {
         case "selection":
-            setEnabled(getCurrentDataSet() != null && ! getCurrentDataSet().getSelected().isEmpty());
+            setEnabled(getCurrentDataSet() != null && !getCurrentDataSet().getSelected().isEmpty());
             break;
         case "layer":
             if (!Main.isDisplayingMapView() || Main.map.mapView.getAllLayersAsList().isEmpty()) {
@@ -295,8 +363,7 @@
             setEnabled(Main.isDisplayingMapView() && Main.map.mapView.hasZoomRedoEntries());
             break;
         default:
-            setEnabled(Main.isDisplayingMapView() && Main.map.mapView.hasLayers()
-            );
+            setEnabled(Main.isDisplayingMapView() && Main.map.mapView.hasLayers());
         }
     }
 
@@ -337,13 +404,15 @@
         public MapFrameAdapter() {
             if ("conflict".equals(mode)) {
                 conflictSelectionListener = new ListSelectionListener() {
-                    @Override public void valueChanged(ListSelectionEvent e) {
+                    @Override
+                    public void valueChanged(ListSelectionEvent e) {
                         updateEnabledState();
                     }
                 };
             } else if ("problem".equals(mode)) {
                 validatorSelectionListener = new TreeSelectionListener() {
-                    @Override public void valueChanged(TreeSelectionEvent e) {
+                    @Override
+                    public void valueChanged(TreeSelectionEvent e) {
                         updateEnabledState();
                     }
                 };
@@ -350,7 +419,8 @@
             }
         }
 
-        @Override public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) {
+        @Override
+        public void mapFrameInitialized(MapFrame oldFrame, MapFrame newFrame) {
             if (conflictSelectionListener != null) {
                 if (newFrame != null) {
                     newFrame.conflictDialog.addListSelectionListener(conflictSelectionListener);
Index: src/org/openstreetmap/josm/gui/NavigatableComponent.java
===================================================================
--- src/org/openstreetmap/josm/gui/NavigatableComponent.java	(revision 8145)
+++ src/org/openstreetmap/josm/gui/NavigatableComponent.java	(working copy)
@@ -660,6 +660,14 @@
         }
     }
 
+    public Stack<ZoomData> getZoomUndoBuffer(){
+        return zoomUndoBuffer;
+    }
+
+    public Stack<ZoomData> getZoomRedoBuffer(){
+        return zoomRedoBuffer;
+    }
+
     public boolean hasZoomUndoEntries() {
         return !zoomUndoBuffer.isEmpty();
     }
