Index: trunk/test/unit/org/openstreetmap/josm/MainTest.java
===================================================================
--- trunk/test/unit/org/openstreetmap/josm/MainTest.java	(revision 12633)
+++ trunk/test/unit/org/openstreetmap/josm/MainTest.java	(revision 12634)
@@ -21,5 +21,4 @@
 import org.openstreetmap.josm.Main.InitializationTask;
 import org.openstreetmap.josm.actions.AboutAction;
-import org.openstreetmap.josm.gui.DownloadParamType;
 import org.openstreetmap.josm.gui.MapFrameListener;
 import org.openstreetmap.josm.io.OnlineResource;
@@ -40,17 +39,4 @@
     @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
     public JOSMTestRules test = new JOSMTestRules().platform().https().devAPI().main().projection();
-
-    /**
-     * Unit test of {@link DownloadParamType#paramType} method.
-     */
-    @Test
-    public void testParamType() {
-        assertEquals(DownloadParamType.bounds, DownloadParamType.paramType("48.000,16.000,48.001,16.001"));
-        assertEquals(DownloadParamType.fileName, DownloadParamType.paramType("data.osm"));
-        assertEquals(DownloadParamType.fileUrl, DownloadParamType.paramType("file:///home/foo/data.osm"));
-        assertEquals(DownloadParamType.fileUrl, DownloadParamType.paramType("file://C:\\Users\\foo\\data.osm"));
-        assertEquals(DownloadParamType.httpUrl, DownloadParamType.paramType("http://somewhere.com/data.osm"));
-        assertEquals(DownloadParamType.httpUrl, DownloadParamType.paramType("https://somewhere.com/data.osm"));
-    }
 
     /**
Index: trunk/test/unit/org/openstreetmap/josm/data/AutosaveTaskTest.java
===================================================================
--- trunk/test/unit/org/openstreetmap/josm/data/AutosaveTaskTest.java	(revision 12633)
+++ 	(revision )
@@ -1,246 +1,0 @@
-// License: GPL. For details, see LICENSE file.
-package org.openstreetmap.josm.data;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.time.ZoneId;
-import java.time.ZonedDateTime;
-import java.util.Date;
-import java.util.List;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.data.AutosaveTask.AutosaveLayerInfo;
-import org.openstreetmap.josm.data.coor.LatLon;
-import org.openstreetmap.josm.data.osm.DataSet;
-import org.openstreetmap.josm.data.osm.Node;
-import org.openstreetmap.josm.gui.layer.OsmDataLayer;
-import org.openstreetmap.josm.testutils.JOSMTestRules;
-
-import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
-
-/**
- * Unit tests for class {@link AutosaveTask}.
- */
-public class AutosaveTaskTest {
-    /**
-     * We need preferences and a home directory for this.
-     */
-    @Rule
-    @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
-    public JOSMTestRules test = new JOSMTestRules().preferences().platform().projection();
-
-    private AutosaveTask task;
-
-    /**
-     * Setup test.
-     * @throws IOException if autosave directory cannot be created
-     */
-    @Before
-    public void setUp() throws IOException {
-        task = new AutosaveTask();
-    }
-
-    /**
-     * Unit test to {@link AutosaveTask#getUnsavedLayersFiles} - empty case
-     */
-    @Test
-    public void testGetUnsavedLayersFilesEmpty() {
-        assertTrue(task.getUnsavedLayersFiles().isEmpty());
-    }
-
-    /**
-     * Unit test to {@link AutosaveTask#getUnsavedLayersFiles} - non empty case
-     * @throws IOException in case of I/O error
-     */
-    @Test
-    public void testGetUnsavedLayersFilesNotEmpty() throws IOException {
-        Files.createDirectories(task.getAutosaveDir());
-        String autodir = task.getAutosaveDir().toString();
-        File layer1 = Files.createFile(Paths.get(autodir, "layer1.osm")).toFile();
-        File layer2 = Files.createFile(Paths.get(autodir, "layer2.osm")).toFile();
-        File dir = Files.createDirectory(Paths.get(autodir, "dir.osm")).toFile();
-        List<File> files = task.getUnsavedLayersFiles();
-        assertEquals(2, files.size());
-        assertTrue(files.contains(layer1));
-        assertTrue(files.contains(layer2));
-        assertFalse(files.contains(dir));
-    }
-
-    /**
-     * Unit test to {@link AutosaveTask#getNewLayerFile}
-     * @throws IOException in case of I/O error
-     */
-    @Test
-    public void testGetNewLayerFile() throws IOException {
-        Files.createDirectories(task.getAutosaveDir());
-        AutosaveLayerInfo info = new AutosaveLayerInfo(new OsmDataLayer(new DataSet(), "layer", null));
-        Date fixed = Date.from(ZonedDateTime.of(2016, 1, 1, 1, 2, 3, 456_000_000, ZoneId.systemDefault()).toInstant());
-
-        AutosaveTask.PROP_INDEX_LIMIT.put(5);
-        for (int i = 0; i <= AutosaveTask.PROP_INDEX_LIMIT.get() + 2; i++) {
-            // Only retry 2 indexes to avoid 1000*1000 disk operations
-            File f = task.getNewLayerFile(info, fixed, Math.max(0, i - 2));
-            if (i > AutosaveTask.PROP_INDEX_LIMIT.get()) {
-                assertNull(f);
-            } else {
-                assertNotNull(f);
-                File pid = task.getPidFile(f);
-                assertTrue(pid.exists());
-                assertTrue(f.exists());
-                if (i == 0) {
-                    assertEquals("null_20160101_010203456.osm", f.getName());
-                    assertEquals("null_20160101_010203456.pid", pid.getName());
-                } else {
-                    assertEquals("null_20160101_010203456_" + i + ".osm", f.getName());
-                    assertEquals("null_20160101_010203456_" + i + ".pid", pid.getName());
-                }
-            }
-        }
-    }
-
-    /**
-     * Tests if {@link AutosaveTask#schedule()} creates the directories.
-     */
-    @Test
-    public void testScheduleCreatesDirectories() {
-        try {
-            task.schedule();
-            assertTrue(task.getAutosaveDir().toFile().isDirectory());
-        } finally {
-            task.cancel();
-        }
-    }
-
-    /**
-     * Tests that {@link AutosaveTask#run()} saves every layer
-     */
-    @Test
-    public void testAutosaveIgnoresUnmodifiedLayer() {
-        OsmDataLayer layer = new OsmDataLayer(new DataSet(), "OsmData", null);
-        Main.getLayerManager().addLayer(layer);
-        try {
-            task.schedule();
-            assertEquals(0, countFiles());
-            task.run();
-            assertEquals(0, countFiles());
-        } finally {
-            task.cancel();
-        }
-    }
-
-    private int countFiles() {
-        String[] files = task.getAutosaveDir().toFile().list((dir, name) -> name.endsWith(".osm"));
-        return files != null ? files.length : 0;
-    }
-
-    /**
-     * Tests that {@link AutosaveTask#run()} saves every layer.
-     */
-    @Test
-    public void testAutosaveSavesLayer() {
-        runAutosaveTaskSeveralTimes(1);
-    }
-
-    /**
-     * Tests that {@link AutosaveTask#run()} saves every layer.
-     */
-    @Test
-    public void testAutosaveSavesLayerMultipleTimes() {
-        AutosaveTask.PROP_FILES_PER_LAYER.put(3);
-        runAutosaveTaskSeveralTimes(5);
-    }
-
-    private void runAutosaveTaskSeveralTimes(int times) {
-        DataSet data = new DataSet();
-        OsmDataLayer layer = new OsmDataLayer(data, "OsmData", null);
-        Main.getLayerManager().addLayer(layer);
-        try {
-            task.schedule();
-            assertEquals(0, countFiles());
-
-            for (int i = 0; i < times; i++) {
-                data.addPrimitive(new Node(new LatLon(10, 10)));
-                task.run();
-                assertEquals(Math.min(i + 1, 3), countFiles());
-            }
-
-        } finally {
-            task.cancel();
-        }
-    }
-
-    /**
-     * Tests that {@link AutosaveTask#discardUnsavedLayers()} ignores layers from the current instance
-     * @throws IOException in case of I/O error
-     */
-    @Test
-    public void testDiscardUnsavedLayersIgnoresCurrentInstance() throws IOException {
-        runAutosaveTaskSeveralTimes(1);
-        try (BufferedWriter file = Files.newBufferedWriter(
-                new File(task.getAutosaveDir().toFile(), "any_other_file.osm").toPath(), StandardCharsets.UTF_8)) {
-            file.append("");
-        }
-        assertEquals(2, countFiles());
-
-        task.discardUnsavedLayers();
-        assertEquals(1, countFiles());
-    }
-
-    /**
-     * Tests that {@link AutosaveTask#run()} handles duplicate layers
-     */
-    @Test
-    public void testAutosaveHandlesDupplicateNames() {
-        DataSet data1 = new DataSet();
-        OsmDataLayer layer1 = new OsmDataLayer(data1, "OsmData", null);
-        Main.getLayerManager().addLayer(layer1);
-
-        DataSet data2 = new DataSet();
-        OsmDataLayer layer2 = new OsmDataLayer(data2, "OsmData", null);
-
-        try {
-            task.schedule();
-            assertEquals(0, countFiles());
-            // also test adding layer later
-            Main.getLayerManager().addLayer(layer2);
-
-            data1.addPrimitive(new Node(new LatLon(10, 10)));
-            data2.addPrimitive(new Node(new LatLon(10, 10)));
-            task.run();
-            assertEquals(2, countFiles());
-        } finally {
-            task.cancel();
-        }
-    }
-
-    /**
-     * Test that {@link AutosaveTask#recoverUnsavedLayers()} recovers unsaved layers.
-     * @throws Exception in case of error
-     */
-    @Test
-    public void testRecoverLayers() throws Exception {
-        runAutosaveTaskSeveralTimes(1);
-        try (BufferedWriter file = Files.newBufferedWriter(
-                new File(task.getAutosaveDir().toFile(), "any_other_file.osm").toPath(), StandardCharsets.UTF_8)) {
-            file.append("<?xml version=\"1.0\"?><osm version=\"0.6\"><node id=\"1\" lat=\"1\" lon=\"2\" version=\"1\"/></osm>");
-        }
-
-        assertEquals(2, countFiles());
-        task.recoverUnsavedLayers().get();
-
-        assertEquals(1, countFiles());
-    }
-}
Index: trunk/test/unit/org/openstreetmap/josm/data/CustomConfiguratorTest.java
===================================================================
--- trunk/test/unit/org/openstreetmap/josm/data/CustomConfiguratorTest.java	(revision 12633)
+++ 	(revision )
@@ -1,131 +1,0 @@
-// License: GPL. For details, see LICENSE file.
-package org.openstreetmap.josm.data;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.util.Arrays;
-import java.util.Collections;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.TestUtils;
-import org.openstreetmap.josm.data.CustomConfigurator.PreferencesUtils;
-import org.openstreetmap.josm.testutils.JOSMTestRules;
-import org.openstreetmap.josm.tools.Utils;
-
-import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
-import net.trajano.commons.testing.UtilityClassTestUtil;
-
-/**
- * Unit tests for class {@link CustomConfigurator}.
- */
-public class CustomConfiguratorTest {
-
-    /**
-     * Setup test.
-     */
-    @Rule
-    @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
-    public JOSMTestRules test = new JOSMTestRules().preferences();
-
-    /**
-     * Setup test.
-     */
-    @Before
-    public void setUp() {
-        CustomConfigurator.resetLog();
-    }
-
-    /**
-     * Test method for {@link CustomConfigurator#log}.
-     */
-    @Test
-    public void testLog() {
-        assertEquals("", CustomConfigurator.getLog());
-        CustomConfigurator.log("test");
-        assertEquals("test\n", CustomConfigurator.getLog());
-        CustomConfigurator.log("%d\n", 100);
-        assertEquals("test\n100\n", CustomConfigurator.getLog());
-        CustomConfigurator.log("test");
-        assertEquals("test\n100\ntest\n", CustomConfigurator.getLog());
-    }
-
-    /**
-     * Test method for {@link CustomConfigurator#exportPreferencesKeysToFile}.
-     * @throws IOException if any I/O error occurs
-     */
-    @Test
-    public void testExportPreferencesKeysToFile() throws IOException {
-        File tmp = File.createTempFile("josm.testExportPreferencesKeysToFile.lorem_ipsum", ".xml");
-
-        Main.pref.putCollection("lorem_ipsum", Arrays.asList(
-                "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
-                "Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor.",
-                "Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper congue, euismod non, mi.",
-                "Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat.",
-                "Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim.",
-                "Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue.",
-                "Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales.",
-                "Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh.",
-                "Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit."));
-        CustomConfigurator.exportPreferencesKeysToFile(tmp.getAbsolutePath(), false, "lorem_ipsum");
-        String xml = Utils.join("\n", Files.readAllLines(tmp.toPath(), StandardCharsets.UTF_8));
-        assertTrue(xml.contains("<preferences operation=\"replace\">"));
-        for (String entry : Main.pref.getCollection("lorem_ipsum")) {
-            assertTrue(entry + "\nnot found in:\n" + xml, xml.contains(entry));
-        }
-
-        Main.pref.putCollection("test", Arrays.asList("11111111", "2222222", "333333333"));
-        CustomConfigurator.exportPreferencesKeysByPatternToFile(tmp.getAbsolutePath(), true, "test");
-        xml = Utils.join("\n", Files.readAllLines(tmp.toPath(), StandardCharsets.UTF_8));
-        assertTrue(xml.contains("<preferences operation=\"append\">"));
-        for (String entry : Main.pref.getCollection("test")) {
-            assertTrue(entry + "\nnot found in:\n" + xml, xml.contains(entry));
-        }
-
-        Utils.deleteFile(tmp);
-    }
-
-    /**
-     * Test method for {@link CustomConfigurator#readXML}.
-     * @throws IOException if any I/O error occurs
-     */
-    @Test
-    public void testReadXML() throws IOException {
-        // Test 1 - read(dir, file) + append
-        Main.pref.putCollection("test", Collections.<String>emptyList());
-        assertTrue(Main.pref.getCollection("test").isEmpty());
-        CustomConfigurator.readXML(TestUtils.getTestDataRoot() + "customconfigurator", "append.xml");
-        String log = CustomConfigurator.getLog();
-        assertFalse(log, log.contains("Error"));
-        assertFalse(Main.pref.getCollection("test").isEmpty());
-
-        // Test 2 - read(file, pref) + replace
-        Preferences pref = new Preferences();
-        // avoid messing up preferences file (that makes all following unit tests fail)
-        pref.enableSaveOnPut(false);
-        pref.putCollection("lorem_ipsum", Arrays.asList("only 1 string"));
-        assertEquals(1, pref.getCollection("lorem_ipsum").size());
-        CustomConfigurator.readXML(new File(TestUtils.getTestDataRoot() + "customconfigurator", "replace.xml"), pref);
-        log = CustomConfigurator.getLog();
-        assertFalse(log, log.contains("Error"));
-        assertEquals(9, pref.getCollection("lorem_ipsum").size());
-    }
-
-    /**
-     * Tests that {@code PreferencesUtils} satisfies utility class criterias.
-     * @throws ReflectiveOperationException if an error occurs
-     */
-    @Test
-    public void testUtilityClass() throws ReflectiveOperationException {
-        UtilityClassTestUtil.assertUtilityClassWellDefined(PreferencesUtils.class);
-    }
-}
Index: trunk/test/unit/org/openstreetmap/josm/gui/MainApplicationTest.java
===================================================================
--- trunk/test/unit/org/openstreetmap/josm/gui/MainApplicationTest.java	(revision 12633)
+++ trunk/test/unit/org/openstreetmap/josm/gui/MainApplicationTest.java	(revision 12634)
@@ -47,5 +47,5 @@
     @Rule
     @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
-    public JOSMTestRules test = new JOSMTestRules().platform().main();
+    public JOSMTestRules test = new JOSMTestRules().main().https().devAPI().timeout(20000);
 
     @SuppressFBWarnings(value = "DM_DEFAULT_ENCODING")
@@ -85,4 +85,17 @@
     public void testShowHelp() throws Exception {
         testShow("--help", MainApplication.getHelp().trim());
+    }
+
+    /**
+     * Unit test of {@link DownloadParamType#paramType} method.
+     */
+    @Test
+    public void testParamType() {
+        assertEquals(DownloadParamType.bounds, DownloadParamType.paramType("48.000,16.000,48.001,16.001"));
+        assertEquals(DownloadParamType.fileName, DownloadParamType.paramType("data.osm"));
+        assertEquals(DownloadParamType.fileUrl, DownloadParamType.paramType("file:///home/foo/data.osm"));
+        assertEquals(DownloadParamType.fileUrl, DownloadParamType.paramType("file://C:\\Users\\foo\\data.osm"));
+        assertEquals(DownloadParamType.httpUrl, DownloadParamType.paramType("http://somewhere.com/data.osm"));
+        assertEquals(DownloadParamType.httpUrl, DownloadParamType.paramType("https://somewhere.com/data.osm"));
     }
 
Index: trunk/test/unit/org/openstreetmap/josm/gui/io/CustomConfiguratorTest.java
===================================================================
--- trunk/test/unit/org/openstreetmap/josm/gui/io/CustomConfiguratorTest.java	(revision 12634)
+++ trunk/test/unit/org/openstreetmap/josm/gui/io/CustomConfiguratorTest.java	(revision 12634)
@@ -0,0 +1,133 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.io;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.util.Arrays;
+import java.util.Collections;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.TestUtils;
+import org.openstreetmap.josm.data.Preferences;
+import org.openstreetmap.josm.data.PreferencesUtils;
+import org.openstreetmap.josm.gui.io.CustomConfigurator;
+import org.openstreetmap.josm.testutils.JOSMTestRules;
+import org.openstreetmap.josm.tools.Utils;
+
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+import net.trajano.commons.testing.UtilityClassTestUtil;
+
+/**
+ * Unit tests for class {@link CustomConfigurator}.
+ */
+public class CustomConfiguratorTest {
+
+    /**
+     * Setup test.
+     */
+    @Rule
+    @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
+    public JOSMTestRules test = new JOSMTestRules().preferences();
+
+    /**
+     * Setup test.
+     */
+    @Before
+    public void setUp() {
+        CustomConfigurator.resetLog();
+    }
+
+    /**
+     * Test method for {@link CustomConfigurator#log}.
+     */
+    @Test
+    public void testLog() {
+        assertEquals("", CustomConfigurator.getLog());
+        CustomConfigurator.log("test");
+        assertEquals("test\n", CustomConfigurator.getLog());
+        CustomConfigurator.log("%d\n", 100);
+        assertEquals("test\n100\n", CustomConfigurator.getLog());
+        CustomConfigurator.log("test");
+        assertEquals("test\n100\ntest\n", CustomConfigurator.getLog());
+    }
+
+    /**
+     * Test method for {@link CustomConfigurator#exportPreferencesKeysToFile}.
+     * @throws IOException if any I/O error occurs
+     */
+    @Test
+    public void testExportPreferencesKeysToFile() throws IOException {
+        File tmp = File.createTempFile("josm.testExportPreferencesKeysToFile.lorem_ipsum", ".xml");
+
+        Main.pref.putCollection("lorem_ipsum", Arrays.asList(
+                "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
+                "Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor.",
+                "Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper congue, euismod non, mi.",
+                "Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat.",
+                "Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim.",
+                "Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue.",
+                "Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales.",
+                "Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh.",
+                "Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit."));
+        CustomConfigurator.exportPreferencesKeysToFile(tmp.getAbsolutePath(), false, "lorem_ipsum");
+        String xml = Utils.join("\n", Files.readAllLines(tmp.toPath(), StandardCharsets.UTF_8));
+        assertTrue(xml.contains("<preferences operation=\"replace\">"));
+        for (String entry : Main.pref.getCollection("lorem_ipsum")) {
+            assertTrue(entry + "\nnot found in:\n" + xml, xml.contains(entry));
+        }
+
+        Main.pref.putCollection("test", Arrays.asList("11111111", "2222222", "333333333"));
+        CustomConfigurator.exportPreferencesKeysByPatternToFile(tmp.getAbsolutePath(), true, "test");
+        xml = Utils.join("\n", Files.readAllLines(tmp.toPath(), StandardCharsets.UTF_8));
+        assertTrue(xml.contains("<preferences operation=\"append\">"));
+        for (String entry : Main.pref.getCollection("test")) {
+            assertTrue(entry + "\nnot found in:\n" + xml, xml.contains(entry));
+        }
+
+        Utils.deleteFile(tmp);
+    }
+
+    /**
+     * Test method for {@link CustomConfigurator#readXML}.
+     * @throws IOException if any I/O error occurs
+     */
+    @Test
+    public void testReadXML() throws IOException {
+        // Test 1 - read(dir, file) + append
+        Main.pref.putCollection("test", Collections.<String>emptyList());
+        assertTrue(Main.pref.getCollection("test").isEmpty());
+        CustomConfigurator.readXML(TestUtils.getTestDataRoot() + "customconfigurator", "append.xml");
+        String log = CustomConfigurator.getLog();
+        assertFalse(log, log.contains("Error"));
+        assertFalse(Main.pref.getCollection("test").isEmpty());
+
+        // Test 2 - read(file, pref) + replace
+        Preferences pref = new Preferences();
+        // avoid messing up preferences file (that makes all following unit tests fail)
+        pref.enableSaveOnPut(false);
+        pref.putCollection("lorem_ipsum", Arrays.asList("only 1 string"));
+        assertEquals(1, pref.getCollection("lorem_ipsum").size());
+        CustomConfigurator.readXML(new File(TestUtils.getTestDataRoot() + "customconfigurator", "replace.xml"), pref);
+        log = CustomConfigurator.getLog();
+        assertFalse(log, log.contains("Error"));
+        assertEquals(9, pref.getCollection("lorem_ipsum").size());
+    }
+
+    /**
+     * Tests that {@code PreferencesUtils} satisfies utility class criterias.
+     * @throws ReflectiveOperationException if an error occurs
+     */
+    @Test
+    public void testUtilityClass() throws ReflectiveOperationException {
+        UtilityClassTestUtil.assertUtilityClassWellDefined(PreferencesUtils.class);
+    }
+}
Index: trunk/test/unit/org/openstreetmap/josm/gui/layer/AutosaveTaskTest.java
===================================================================
--- trunk/test/unit/org/openstreetmap/josm/gui/layer/AutosaveTaskTest.java	(revision 12634)
+++ trunk/test/unit/org/openstreetmap/josm/gui/layer/AutosaveTaskTest.java	(revision 12634)
@@ -0,0 +1,247 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.layer;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+import java.util.Date;
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.Node;
+import org.openstreetmap.josm.gui.layer.AutosaveTask;
+import org.openstreetmap.josm.gui.layer.OsmDataLayer;
+import org.openstreetmap.josm.gui.layer.AutosaveTask.AutosaveLayerInfo;
+import org.openstreetmap.josm.testutils.JOSMTestRules;
+
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+
+/**
+ * Unit tests for class {@link AutosaveTask}.
+ */
+public class AutosaveTaskTest {
+    /**
+     * We need preferences and a home directory for this.
+     */
+    @Rule
+    @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
+    public JOSMTestRules test = new JOSMTestRules().preferences().platform().projection();
+
+    private AutosaveTask task;
+
+    /**
+     * Setup test.
+     * @throws IOException if autosave directory cannot be created
+     */
+    @Before
+    public void setUp() throws IOException {
+        task = new AutosaveTask();
+    }
+
+    /**
+     * Unit test to {@link AutosaveTask#getUnsavedLayersFiles} - empty case
+     */
+    @Test
+    public void testGetUnsavedLayersFilesEmpty() {
+        assertTrue(task.getUnsavedLayersFiles().isEmpty());
+    }
+
+    /**
+     * Unit test to {@link AutosaveTask#getUnsavedLayersFiles} - non empty case
+     * @throws IOException in case of I/O error
+     */
+    @Test
+    public void testGetUnsavedLayersFilesNotEmpty() throws IOException {
+        Files.createDirectories(task.getAutosaveDir());
+        String autodir = task.getAutosaveDir().toString();
+        File layer1 = Files.createFile(Paths.get(autodir, "layer1.osm")).toFile();
+        File layer2 = Files.createFile(Paths.get(autodir, "layer2.osm")).toFile();
+        File dir = Files.createDirectory(Paths.get(autodir, "dir.osm")).toFile();
+        List<File> files = task.getUnsavedLayersFiles();
+        assertEquals(2, files.size());
+        assertTrue(files.contains(layer1));
+        assertTrue(files.contains(layer2));
+        assertFalse(files.contains(dir));
+    }
+
+    /**
+     * Unit test to {@link AutosaveTask#getNewLayerFile}
+     * @throws IOException in case of I/O error
+     */
+    @Test
+    public void testGetNewLayerFile() throws IOException {
+        Files.createDirectories(task.getAutosaveDir());
+        AutosaveLayerInfo info = new AutosaveLayerInfo(new OsmDataLayer(new DataSet(), "layer", null));
+        Date fixed = Date.from(ZonedDateTime.of(2016, 1, 1, 1, 2, 3, 456_000_000, ZoneId.systemDefault()).toInstant());
+
+        AutosaveTask.PROP_INDEX_LIMIT.put(5);
+        for (int i = 0; i <= AutosaveTask.PROP_INDEX_LIMIT.get() + 2; i++) {
+            // Only retry 2 indexes to avoid 1000*1000 disk operations
+            File f = task.getNewLayerFile(info, fixed, Math.max(0, i - 2));
+            if (i > AutosaveTask.PROP_INDEX_LIMIT.get()) {
+                assertNull(f);
+            } else {
+                assertNotNull(f);
+                File pid = task.getPidFile(f);
+                assertTrue(pid.exists());
+                assertTrue(f.exists());
+                if (i == 0) {
+                    assertEquals("null_20160101_010203456.osm", f.getName());
+                    assertEquals("null_20160101_010203456.pid", pid.getName());
+                } else {
+                    assertEquals("null_20160101_010203456_" + i + ".osm", f.getName());
+                    assertEquals("null_20160101_010203456_" + i + ".pid", pid.getName());
+                }
+            }
+        }
+    }
+
+    /**
+     * Tests if {@link AutosaveTask#schedule()} creates the directories.
+     */
+    @Test
+    public void testScheduleCreatesDirectories() {
+        try {
+            task.schedule();
+            assertTrue(task.getAutosaveDir().toFile().isDirectory());
+        } finally {
+            task.cancel();
+        }
+    }
+
+    /**
+     * Tests that {@link AutosaveTask#run()} saves every layer
+     */
+    @Test
+    public void testAutosaveIgnoresUnmodifiedLayer() {
+        OsmDataLayer layer = new OsmDataLayer(new DataSet(), "OsmData", null);
+        Main.getLayerManager().addLayer(layer);
+        try {
+            task.schedule();
+            assertEquals(0, countFiles());
+            task.run();
+            assertEquals(0, countFiles());
+        } finally {
+            task.cancel();
+        }
+    }
+
+    private int countFiles() {
+        String[] files = task.getAutosaveDir().toFile().list((dir, name) -> name.endsWith(".osm"));
+        return files != null ? files.length : 0;
+    }
+
+    /**
+     * Tests that {@link AutosaveTask#run()} saves every layer.
+     */
+    @Test
+    public void testAutosaveSavesLayer() {
+        runAutosaveTaskSeveralTimes(1);
+    }
+
+    /**
+     * Tests that {@link AutosaveTask#run()} saves every layer.
+     */
+    @Test
+    public void testAutosaveSavesLayerMultipleTimes() {
+        AutosaveTask.PROP_FILES_PER_LAYER.put(3);
+        runAutosaveTaskSeveralTimes(5);
+    }
+
+    private void runAutosaveTaskSeveralTimes(int times) {
+        DataSet data = new DataSet();
+        OsmDataLayer layer = new OsmDataLayer(data, "OsmData", null);
+        Main.getLayerManager().addLayer(layer);
+        try {
+            task.schedule();
+            assertEquals(0, countFiles());
+
+            for (int i = 0; i < times; i++) {
+                data.addPrimitive(new Node(new LatLon(10, 10)));
+                task.run();
+                assertEquals(Math.min(i + 1, 3), countFiles());
+            }
+
+        } finally {
+            task.cancel();
+        }
+    }
+
+    /**
+     * Tests that {@link AutosaveTask#discardUnsavedLayers()} ignores layers from the current instance
+     * @throws IOException in case of I/O error
+     */
+    @Test
+    public void testDiscardUnsavedLayersIgnoresCurrentInstance() throws IOException {
+        runAutosaveTaskSeveralTimes(1);
+        try (BufferedWriter file = Files.newBufferedWriter(
+                new File(task.getAutosaveDir().toFile(), "any_other_file.osm").toPath(), StandardCharsets.UTF_8)) {
+            file.append("");
+        }
+        assertEquals(2, countFiles());
+
+        task.discardUnsavedLayers();
+        assertEquals(1, countFiles());
+    }
+
+    /**
+     * Tests that {@link AutosaveTask#run()} handles duplicate layers
+     */
+    @Test
+    public void testAutosaveHandlesDupplicateNames() {
+        DataSet data1 = new DataSet();
+        OsmDataLayer layer1 = new OsmDataLayer(data1, "OsmData", null);
+        Main.getLayerManager().addLayer(layer1);
+
+        DataSet data2 = new DataSet();
+        OsmDataLayer layer2 = new OsmDataLayer(data2, "OsmData", null);
+
+        try {
+            task.schedule();
+            assertEquals(0, countFiles());
+            // also test adding layer later
+            Main.getLayerManager().addLayer(layer2);
+
+            data1.addPrimitive(new Node(new LatLon(10, 10)));
+            data2.addPrimitive(new Node(new LatLon(10, 10)));
+            task.run();
+            assertEquals(2, countFiles());
+        } finally {
+            task.cancel();
+        }
+    }
+
+    /**
+     * Test that {@link AutosaveTask#recoverUnsavedLayers()} recovers unsaved layers.
+     * @throws Exception in case of error
+     */
+    @Test
+    public void testRecoverLayers() throws Exception {
+        runAutosaveTaskSeveralTimes(1);
+        try (BufferedWriter file = Files.newBufferedWriter(
+                new File(task.getAutosaveDir().toFile(), "any_other_file.osm").toPath(), StandardCharsets.UTF_8)) {
+            file.append("<?xml version=\"1.0\"?><osm version=\"0.6\"><node id=\"1\" lat=\"1\" lon=\"2\" version=\"1\"/></osm>");
+        }
+
+        assertEquals(2, countFiles());
+        task.recoverUnsavedLayers().get();
+
+        assertEquals(1, countFiles());
+    }
+}
Index: trunk/test/unit/org/openstreetmap/josm/gui/oauth/FullyAutomaticAuthorizationUITest.java
===================================================================
--- trunk/test/unit/org/openstreetmap/josm/gui/oauth/FullyAutomaticAuthorizationUITest.java	(revision 12633)
+++ trunk/test/unit/org/openstreetmap/josm/gui/oauth/FullyAutomaticAuthorizationUITest.java	(revision 12634)
@@ -6,5 +6,5 @@
 import org.junit.Rule;
 import org.junit.Test;
-import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.gui.MainApplication;
 import org.openstreetmap.josm.testutils.JOSMTestRules;
 
@@ -28,5 +28,5 @@
     @Test
     public void testFullyAutomaticAuthorizationUI() {
-        assertNotNull(new FullyAutomaticAuthorizationUI("", Main.worker));
+        assertNotNull(new FullyAutomaticAuthorizationUI("", MainApplication.worker));
     }
 }
Index: trunk/test/unit/org/openstreetmap/josm/gui/oauth/ManualAuthorizationUITest.java
===================================================================
--- trunk/test/unit/org/openstreetmap/josm/gui/oauth/ManualAuthorizationUITest.java	(revision 12633)
+++ trunk/test/unit/org/openstreetmap/josm/gui/oauth/ManualAuthorizationUITest.java	(revision 12634)
@@ -6,5 +6,5 @@
 import org.junit.Rule;
 import org.junit.Test;
-import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.gui.MainApplication;
 import org.openstreetmap.josm.testutils.JOSMTestRules;
 
@@ -28,5 +28,5 @@
     @Test
     public void testManualAuthorizationUI() {
-        assertNotNull(new ManualAuthorizationUI("", Main.worker));
+        assertNotNull(new ManualAuthorizationUI("", MainApplication.worker));
     }
 }
Index: trunk/test/unit/org/openstreetmap/josm/gui/oauth/SemiAutomaticAuthorizationUITest.java
===================================================================
--- trunk/test/unit/org/openstreetmap/josm/gui/oauth/SemiAutomaticAuthorizationUITest.java	(revision 12633)
+++ trunk/test/unit/org/openstreetmap/josm/gui/oauth/SemiAutomaticAuthorizationUITest.java	(revision 12634)
@@ -6,5 +6,5 @@
 import org.junit.Rule;
 import org.junit.Test;
-import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.gui.MainApplication;
 import org.openstreetmap.josm.testutils.JOSMTestRules;
 
@@ -28,5 +28,5 @@
     @Test
     public void testSemiAutomaticAuthorizationUI() {
-        assertNotNull(new SemiAutomaticAuthorizationUI("", Main.worker));
+        assertNotNull(new SemiAutomaticAuthorizationUI("", MainApplication.worker));
     }
 }
