Index: /applications/editors/josm/plugins/slippymap/src/org/openstreetmap/josm/plugins/slippymap/SlippyMapLayer.java
===================================================================
--- /applications/editors/josm/plugins/slippymap/src/org/openstreetmap/josm/plugins/slippymap/SlippyMapLayer.java	(revision 13711)
+++ /applications/editors/josm/plugins/slippymap/src/org/openstreetmap/josm/plugins/slippymap/SlippyMapLayer.java	(revision 13712)
@@ -44,5 +44,6 @@
 {
 	public int currentZoomLevel = 14;
-    ArrayList<HashMap<SlippyMapKey, SlippyMapTile>> tileStorage = null;
+    //ArrayList<HashMap<SlippyMapKey, SlippyMapTile>> tileStorage = null;
+	private HashMap<SlippyMapKey, SlippyMapTile>[] tileStorage = null;
 
     Point[][]                                  pixelpos    = new Point[21][21];
@@ -59,5 +60,5 @@
     {
         super(tr("Slippy Map"));
-	background = true;
+        background = true;
 
         clearTileStorage();
@@ -178,8 +179,9 @@
      */
     public void increaseZoomLevel() {
-    	//TODO max lvl should be in preferences...
-    	if(currentZoomLevel < 17) {
+    	if(currentZoomLevel < SlippyMapPreferences.getMaxZoomLvl()) {
     		currentZoomLevel++;
-    		loadAllTiles();
+    		//if(SlippyMapPreferences.getAutoloadTiles()) {
+    		//	loadAllTiles();
+    		//}
     	}
     }
@@ -191,14 +193,18 @@
     	if(currentZoomLevel > 10) {
     		currentZoomLevel--;
-    		loadAllTiles();
+    		//if(SlippyMapPreferences.getAutoloadTiles()) {
+    		//	loadAllTiles();
+    		//}
     	}
     }
     
-    private void clearTileStorage()
-    {
-        tileStorage = new ArrayList<HashMap<SlippyMapKey, SlippyMapTile>>(20);
-
-        for (int i = 0; i < 18; i++)
-            tileStorage.add(new HashMap<SlippyMapKey, SlippyMapTile>());
+    public void clearTileStorage()
+    {
+    	int maxZoom = SlippyMapPreferences.getMaxZoomLvl();
+    	// +1 because of array indexed from 0.
+        tileStorage = new HashMap[maxZoom+1];
+
+        for (int i = 0; i < maxZoom+1; i++)
+            tileStorage[i] = new HashMap<SlippyMapKey, SlippyMapTile>();
     }
 
@@ -240,8 +246,8 @@
             	SlippyMapKey key = new SlippyMapKey(x,y);
 
-                SlippyMapTile tile = tileStorage.get(currentZoomLevel).get(key);
+                SlippyMapTile tile = tileStorage[currentZoomLevel].get(key);
 
                 if (tile == null)
-                    tileStorage.get(currentZoomLevel).put(key,
+                    tileStorage[currentZoomLevel].put(key,
                             tile = new SlippyMapTile(x, y, currentZoomLevel));
 
@@ -321,10 +327,20 @@
             {
             	SlippyMapKey key = new SlippyMapKey(x,y);
-                SlippyMapTile tile = tileStorage.get(currentZoomLevel).get(key);
+                SlippyMapTile tile;
+                try
+                {
+                	tile = tileStorage[currentZoomLevel].get(key);
+                } catch (IndexOutOfBoundsException ex) {
+                	throw new RuntimeException("currentZoomLevel=" + currentZoomLevel + " and tile storage array have just size=" + tileStorage.length + " and maxZoomLvl in preferences is " + SlippyMapPreferences.getMaxZoomLvl() + ".", ex);
+                }
 
                 if (tile == null)
                 {
-                    tileStorage.get(currentZoomLevel).put(key,
-                            tile = new SlippyMapTile(x, y, currentZoomLevel));
+                	tile = new SlippyMapTile(x, y, currentZoomLevel);
+                    tileStorage[currentZoomLevel].put(key, tile);
+                    if(SlippyMapPreferences.getAutoloadTiles()) {
+                    	//TODO probably do on background
+                    	tile.loadImage();
+            		}
                 }
                 Image img = tile.getImage();
@@ -357,5 +373,5 @@
             	SlippyMapKey key = new SlippyMapKey(x,y);
                 int texty = p.y + 2 + fontHeight;
-                SlippyMapTile tile = tileStorage.get(currentZoomLevel).get(key);
+                SlippyMapTile tile = tileStorage[currentZoomLevel].get(key);
                 p = pixelpos[x - z12x0 + 1][y - z12y0 + 2];
                 g.drawString("x=" + x + " y=" + y + " z=" + currentZoomLevel + "", p.x + 2, texty);
@@ -398,10 +414,14 @@
 
         if((z12x1 - z12x0 < 2) || (z12y1 - z12y0 < 2)) {
-        	increaseZoomLevel();
+        	if(SlippyMapPreferences.getAutozoom()) {
+        		increaseZoomLevel();
+        	}
         	this.paint(oldg, mv);
         }
         
         if((z12x1 - z12x0 > 6) || (z12y1 - z12y0 > 6)) {
-        	decreaseZoomLevel();
+        	if(SlippyMapPreferences.getAutozoom()) {
+        		decreaseZoomLevel();
+        	}
         	this.paint(oldg, mv);
         }
@@ -438,7 +458,7 @@
 
         SlippyMapKey key = new SlippyMapKey(tilex,tiley);
-        SlippyMapTile tile = tileStorage.get(currentZoomLevel).get(key);
+        SlippyMapTile tile = tileStorage[currentZoomLevel].get(key);
         if (tile == null)
-            tileStorage.get(currentZoomLevel).put(key,
+            tileStorage[currentZoomLevel].put(key,
                     tile = new SlippyMapTile(tilex, tiley, currentZoomLevel));
         return tile;
Index: /applications/editors/josm/plugins/slippymap/src/org/openstreetmap/josm/plugins/slippymap/SlippyMapPreferenceSetting.java
===================================================================
--- /applications/editors/josm/plugins/slippymap/src/org/openstreetmap/josm/plugins/slippymap/SlippyMapPreferenceSetting.java	(revision 13711)
+++ /applications/editors/josm/plugins/slippymap/src/org/openstreetmap/josm/plugins/slippymap/SlippyMapPreferenceSetting.java	(revision 13712)
@@ -3,8 +3,11 @@
 import static org.openstreetmap.josm.tools.I18n.tr;
 
+import javax.swing.Box;
+import javax.swing.JCheckBox;
 import javax.swing.JComboBox;
 import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JSpinner;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.gui.preferences.PreferenceDialog;
 import org.openstreetmap.josm.gui.preferences.PreferenceSetting;
@@ -22,36 +25,80 @@
      */
     private JComboBox tileSourceCombo;
+    
+    private JCheckBox autozoomActive = new JCheckBox(tr("autozoom"));
+    private JCheckBox autoloadTiles = new JCheckBox(tr("autoload tiles"));
+    private JSpinner maxZoomLvl = new JSpinner();
 
     public void addGui(PreferenceDialog gui)
     {
+        //String description = tr("A plugin that adds to JOSM new layer. This layer could render external tiles.");
+        JPanel slippymapTab = gui.createPreferenceTab("slippymap.png", tr("SlippyMap"), tr("Settings for the SlippyMap plugin."));
+
+        JPanel mapUrlPanel = new JPanel();
         String[] allMapUrls = SlippyMapPreferences.getAllMapUrls();
         tileSourceCombo = new JComboBox(allMapUrls);
-
+        tileSourceCombo.setEditable(true);
         String source = SlippyMapPreferences.getMapUrl();
-
-        for (int i = 0; i < allMapUrls.length; i++)
-        {
-//            System.err.println("Comparing '" + source + "' to '"
-//                   + allMapUrls[i]);
-
-            if (source.equals(allMapUrls[i]))
-            {
-                tileSourceCombo.setSelectedIndex(i);
-                break;
-            }
-        }
-
-        gui.display.add(new JLabel(tr("Tile Sources")), GBC.std());
-        gui.display.add(GBC.glue(5, 0), GBC.std().fill(GBC.HORIZONTAL));
-        gui.display.add(tileSourceCombo, GBC.eol().fill(GBC.HORIZONTAL));
+        tileSourceCombo.setSelectedItem(source);
+        mapUrlPanel.add(new JLabel(tr("Tile Sources")), GBC.std());
+        mapUrlPanel.add(GBC.glue(5, 0), GBC.std().fill(GBC.HORIZONTAL));
+        mapUrlPanel.add(tileSourceCombo, GBC.eol().fill(GBC.HORIZONTAL));
+        
+        JPanel autozoomPanel = new JPanel();
+        autozoomPanel.add(new JLabel(tr("Auto zoom: ")), GBC.std());
+        autozoomPanel.add(GBC.glue(5, 0), GBC.std().fill(GBC.HORIZONTAL));
+        autozoomPanel.add(autozoomActive, GBC.eol().fill(GBC.HORIZONTAL));
+        
+        JPanel autoloadPanel = new JPanel();
+        autoloadPanel.add(new JLabel(tr("Autoload Tiles: ")), GBC.std());
+        autoloadPanel.add(GBC.glue(5, 0), GBC.std().fill(GBC.HORIZONTAL));
+        autoloadPanel.add(autoloadTiles, GBC.eol().fill(GBC.HORIZONTAL));
+        
+        JPanel maxZoomLvlPanel = new JPanel();
+        maxZoomLvlPanel.add(new JLabel(tr("Max zoom lvl: ")), GBC.std());
+        maxZoomLvlPanel.add(GBC.glue(5, 0), GBC.std().fill(GBC.HORIZONTAL));
+        maxZoomLvlPanel.add(this.maxZoomLvl, GBC.eol().fill(GBC.HORIZONTAL));
+        
+        slippymapTab.add(mapUrlPanel, GBC.eol().fill(GBC.HORIZONTAL));
+        slippymapTab.add(autozoomPanel, GBC.eol().fill(GBC.HORIZONTAL));
+        slippymapTab.add(autoloadPanel, GBC.eol().fill(GBC.HORIZONTAL));
+        slippymapTab.add(maxZoomLvlPanel, GBC.eol().fill(GBC.HORIZONTAL));
+        slippymapTab.add(Box.createVerticalGlue(), GBC.eol().fill(GBC.VERTICAL));
+        
+        this.loadSettings();
     }
 
     /**
+     * <p>
+     * Load settings from {@link SlippyMapPreferences} class. Loaded preferences are stored to local GUI components.
+     * Actualy this method loads and sets this params:<br>
+     * <ul>
+     * 	<li>autozoom - {@link #autozoomActive} - {@link SlippyMapPreferences#getAutozoom()}</li>
+     * 	<li>autoload - {@link #autoloadTiles} - {@link SlippyMapPreferences#getAutoloadTiles()}</li>
+     * 	<li>maxZoomLvl - {@link #maxZoomLvl} - {@link SlippyMapPreferences#getMaxZoomLvl()}</li>
+     * </ul>
+     * </p>
+     */
+    private void loadSettings() {
+        this.autozoomActive.setSelected(SlippyMapPreferences.getAutozoom());
+        this.autoloadTiles.setSelected(SlippyMapPreferences.getAutoloadTiles());
+        this.maxZoomLvl.setValue(SlippyMapPreferences.getMaxZoomLvl());
+    }
+    
+    /**
+     * <p>
      * Someone pressed the "ok" button
+     * </p>
+     * <p>
+     * This method saves actual state from GUI objects to actual preferences.
+     * </p>
      */
     public boolean ok()
     {
-        Main.pref.put(SlippyMapPreferences.PREFERENCE_TILE_URL, tileSourceCombo.getSelectedItem().toString());
-        //restart isnt required
+        SlippyMapPreferences.setMapUrl(this.tileSourceCombo.getSelectedItem().toString());
+        SlippyMapPreferences.setAutozoom(this.autozoomActive.isSelected());
+        SlippyMapPreferences.setAutoloadTiles(this.autoloadTiles.isSelected());
+        SlippyMapPreferences.setMaxZoomLvl((Integer)this.maxZoomLvl.getValue());
+        //restart isn't required
         return false;
     }
Index: /applications/editors/josm/plugins/slippymap/src/org/openstreetmap/josm/plugins/slippymap/SlippyMapPreferences.java
===================================================================
--- /applications/editors/josm/plugins/slippymap/src/org/openstreetmap/josm/plugins/slippymap/SlippyMapPreferences.java	(revision 13711)
+++ /applications/editors/josm/plugins/slippymap/src/org/openstreetmap/josm/plugins/slippymap/SlippyMapPreferences.java	(revision 13712)
@@ -12,7 +12,10 @@
 public class SlippyMapPreferences
 {
-    public static String PREFERENCE_PREFIX   = "slippymap";
+    public static final String PREFERENCE_PREFIX   = "slippymap";
 
-    public static String PREFERENCE_TILE_URL = PREFERENCE_PREFIX + ".tile_url";
+    private static final String PREFERENCE_TILE_URL = PREFERENCE_PREFIX + ".tile_url";
+    private static final String PREFERENCE_AUTOZOOM = PREFERENCE_PREFIX + ".autozoom";
+    private static final String PREFERENCE_AUTOLOADTILES = PREFERENCE_PREFIX + ".autoload_tiles";
+    private static final String PREFERENCE_MAX_ZOOM_LVL = PREFERENCE_PREFIX + ".max_zoom_lvl";
     
     public static String getMapUrl()
@@ -28,5 +31,74 @@
         return url;
     }
+    
+    public static void setMapUrl(String mapUrl) {
+    	Main.pref.put(SlippyMapPreferences.PREFERENCE_TILE_URL, mapUrl);
+    }
+    
+    public static boolean getAutozoom()
+    {
+        String autozoom = Main.pref.get(PREFERENCE_AUTOZOOM);
 
+        if (autozoom == null || "".equals(autozoom))
+        {
+        	autozoom = "true";
+            Main.pref.put(PREFERENCE_AUTOZOOM, autozoom);
+        }
+
+        return Boolean.parseBoolean(autozoom);
+    }
+    
+    public static void setAutozoom(boolean autozoom) {
+    	Main.pref.put(SlippyMapPreferences.PREFERENCE_AUTOZOOM, autozoom);
+    }
+    
+    public static boolean getAutoloadTiles()
+    {
+        String autoloadTiles = Main.pref.get(PREFERENCE_AUTOLOADTILES);
+
+        if (autoloadTiles == null || "".equals(autoloadTiles))
+        {
+        	autoloadTiles = "true";
+            Main.pref.put(PREFERENCE_AUTOLOADTILES, autoloadTiles);
+        }
+
+        return Boolean.parseBoolean(autoloadTiles);
+    }
+    
+    public static void setAutoloadTiles(boolean autoloadTiles) {
+    	Main.pref.put(SlippyMapPreferences.PREFERENCE_AUTOLOADTILES, autoloadTiles);
+    }
+
+    public static int getMaxZoomLvl()
+    {
+        String maxZoomLvl = Main.pref.get(PREFERENCE_MAX_ZOOM_LVL);
+
+        if (maxZoomLvl == null || "".equals(maxZoomLvl))
+        {
+        	maxZoomLvl = "17";
+            Main.pref.put(PREFERENCE_MAX_ZOOM_LVL, maxZoomLvl);
+        }
+
+        int navrat;
+        try {
+        	navrat = Integer.parseInt(maxZoomLvl);
+        } catch (Exception ex) {
+        	throw new RuntimeException("Problem while converting string to int. Converting value of prefetrences " + PREFERENCE_MAX_ZOOM_LVL + ". Value=\"" + maxZoomLvl + "\". Should be an integer. Error: " + ex.getMessage(), ex);
+        }
+        if(navrat > 30) {
+    		System.err.println("MaxZoomLvl shouldnt be more than 30! Setting to 30.");
+    		navrat = 30;
+    	}
+        return navrat;
+    }
+    
+    public static void setMaxZoomLvl(int maxZoomLvl) {
+    	if(maxZoomLvl > 30) {
+    		System.err.println("MaxZoomLvl shouldnt be more than 30! Setting to 30.");
+    		maxZoomLvl = 30;
+    	}
+    	Main.pref.put(SlippyMapPreferences.PREFERENCE_MAX_ZOOM_LVL, "" + maxZoomLvl);
+    }
+    
     public static String[] getAllMapUrls()
     {
