Index: trunk/test/unit/org/openstreetmap/josm/gui/io/BasicUploadSettingsPanelTest.java
===================================================================
--- trunk/test/unit/org/openstreetmap/josm/gui/io/BasicUploadSettingsPanelTest.java	(revision 18144)
+++ trunk/test/unit/org/openstreetmap/josm/gui/io/BasicUploadSettingsPanelTest.java	(revision 18173)
@@ -2,5 +2,12 @@
 package org.openstreetmap.josm.gui.io;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.openstreetmap.josm.spi.preferences.Config;
 
 import org.openstreetmap.josm.testutils.annotations.BasicPreferences;
@@ -18,5 +25,41 @@
     @Test
     void testBasicUploadSettingsPanel() {
-        assertNotNull(new BasicUploadSettingsPanel(new ChangesetCommentModel(), new ChangesetCommentModel(), new ChangesetReviewModel()));
+        assertNotNull(new BasicUploadSettingsPanel(new UploadDialogModel()));
+    }
+
+    private static void doTestGetLastChangesetTagFromHistory(String historyKey, List<String> def) {
+        Config.getPref().putList(historyKey, null);
+        Config.getPref().putInt(BasicUploadSettingsPanel.COMMENT_LAST_USED_KEY, 0);
+        Config.getPref().putInt(BasicUploadSettingsPanel.COMMENT_MAX_AGE_KEY, 30);
+        assertNull(BasicUploadSettingsPanel.getLastChangesetTagFromHistory(historyKey, def));          // age NOK (history empty)
+
+        Config.getPref().putList(historyKey, Arrays.asList("foo", "bar"));
+        assertNull(BasicUploadSettingsPanel.getLastChangesetTagFromHistory(historyKey, def));          // age NOK (history not empty)
+
+        Config.getPref().putLong(BasicUploadSettingsPanel.COMMENT_LAST_USED_KEY, System.currentTimeMillis() / 1000);
+        assertEquals("foo", BasicUploadSettingsPanel.getLastChangesetTagFromHistory(historyKey, def)); // age OK, history not empty
+
+        Config.getPref().putList(historyKey, null);
+        assertEquals(def.get(0), BasicUploadSettingsPanel.getLastChangesetTagFromHistory(historyKey, def));   // age OK, history empty
+    }
+
+    /**
+     * Test of {@link BasicUploadSettingsPanel#getLastChangesetTagFromHistory} method.
+     */
+    @Test
+    void testGetLastChangesetCommentFromHistory() {
+        doTestGetLastChangesetTagFromHistory(
+                BasicUploadSettingsPanel.COMMENT_HISTORY_KEY,
+                Arrays.asList("baz", "quux"));
+    }
+
+    /**
+     * Test of {@link BasicUploadSettingsPanel#getLastChangesetTagFromHistory} method.
+     */
+    @Test
+    void testGetLastChangesetSourceFromHistory() {
+        doTestGetLastChangesetTagFromHistory(
+                BasicUploadSettingsPanel.SOURCE_HISTORY_KEY,
+                BasicUploadSettingsPanel.getDefaultSources());
     }
 }
Index: trunk/test/unit/org/openstreetmap/josm/gui/io/ChangesetCommentModelTest.java
===================================================================
--- trunk/test/unit/org/openstreetmap/josm/gui/io/ChangesetCommentModelTest.java	(revision 18144)
+++ 	(revision )
@@ -1,55 +1,0 @@
-// License: GPL. For details, see LICENSE file.
-package org.openstreetmap.josm.gui.io;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
-
-import java.util.Arrays;
-import java.util.Collections;
-
-import org.junit.jupiter.api.extension.RegisterExtension;
-import org.junit.jupiter.api.Test;
-import org.openstreetmap.josm.testutils.JOSMTestRules;
-
-import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
-
-/**
- * Unit tests of {@link ChangesetCommentModel} class.
- */
-class ChangesetCommentModelTest {
-
-    /**
-     * Setup tests
-     */
-    @RegisterExtension
-    @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
-    public JOSMTestRules test = new JOSMTestRules();
-
-    /**
-     * Test of {@link ChangesetCommentModel#findHashTags}.
-     */
-    @Test
-    void testFindHashTags() {
-        ChangesetCommentModel model = new ChangesetCommentModel();
-        assertEquals(Collections.emptyList(), model.findHashTags());
-        model.setComment(" ");
-        assertEquals(Collections.emptyList(), model.findHashTags());
-        model.setComment(" #");
-        assertEquals(Collections.emptyList(), model.findHashTags());
-        model.setComment(" # ");
-        assertEquals(Collections.emptyList(), model.findHashTags());
-        model.setComment(" https://example.com/#map ");
-        assertEquals(Collections.emptyList(), model.findHashTags());
-        model.setComment("#59606086");
-        assertEquals(Collections.emptyList(), model.findHashTags());
-        model.setComment(" #foo ");
-        assertEquals(Arrays.asList("#foo"), model.findHashTags());
-        model.setComment(" #foo #bar baz");
-        assertEquals(Arrays.asList("#foo", "#bar"), model.findHashTags());
-        model.setComment(" #foo, #bar, baz");
-        assertEquals(Arrays.asList("#foo", "#bar"), model.findHashTags());
-        model.setComment(" #foo; #bar; baz");
-        assertEquals(Arrays.asList("#foo", "#bar"), model.findHashTags());
-        model.setComment("#hotosm-project-4773 #DRONEBIRD #OsakaQuake2018 #AOYAMAVISION");
-        assertEquals(Arrays.asList("#hotosm-project-4773", "#DRONEBIRD", "#OsakaQuake2018", "#AOYAMAVISION"), model.findHashTags());
-    }
-}
Index: trunk/test/unit/org/openstreetmap/josm/gui/io/ChangesetManagementPanelTest.java
===================================================================
--- trunk/test/unit/org/openstreetmap/josm/gui/io/ChangesetManagementPanelTest.java	(revision 18144)
+++ trunk/test/unit/org/openstreetmap/josm/gui/io/ChangesetManagementPanelTest.java	(revision 18173)
@@ -5,4 +5,5 @@
 
 import org.junit.jupiter.api.Test;
+
 import org.openstreetmap.josm.testutils.annotations.BasicPreferences;
 
@@ -17,5 +18,5 @@
     @Test
     void testChangesetManagementPanel() {
-        assertNotNull(new ChangesetManagementPanel(new ChangesetCommentModel()));
+        assertNotNull(new ChangesetManagementPanel(new UploadDialogModel()));
     }
 }
Index: trunk/test/unit/org/openstreetmap/josm/gui/io/TagSettingsPanelTest.java
===================================================================
--- trunk/test/unit/org/openstreetmap/josm/gui/io/TagSettingsPanelTest.java	(revision 18144)
+++ 	(revision )
@@ -1,31 +1,0 @@
-// License: GPL. For details, see LICENSE file.
-package org.openstreetmap.josm.gui.io;
-
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-
-import org.junit.jupiter.api.extension.RegisterExtension;
-import org.junit.jupiter.api.Test;
-import org.openstreetmap.josm.testutils.JOSMTestRules;
-
-import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
-
-/**
- * Unit tests of {@link TagSettingsPanel} class.
- */
-class TagSettingsPanelTest {
-
-    /**
-     * Setup tests
-     */
-    @RegisterExtension
-    @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
-    public JOSMTestRules test = new JOSMTestRules().preferences();
-
-    /**
-     * Test of {@link TagSettingsPanel#TagSettingsPanel}.
-     */
-    @Test
-    void testTagSettingsPanel() {
-        assertNotNull(new TagSettingsPanel(new ChangesetCommentModel(), new ChangesetCommentModel(), new ChangesetReviewModel()));
-    }
-}
Index: trunk/test/unit/org/openstreetmap/josm/gui/io/UploadDialogModelTest.java
===================================================================
--- trunk/test/unit/org/openstreetmap/josm/gui/io/UploadDialogModelTest.java	(revision 18173)
+++ trunk/test/unit/org/openstreetmap/josm/gui/io/UploadDialogModelTest.java	(revision 18173)
@@ -0,0 +1,67 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.io;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import org.junit.jupiter.api.extension.RegisterExtension;
+import org.junit.jupiter.api.Test;
+
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.testutils.JOSMTestRules;
+
+/**
+ * Unit tests of {@link UploadDialogModel} class.
+ */
+public class UploadDialogModelTest {
+    /**
+     * Setup tests
+     */
+    @RegisterExtension
+    public JOSMTestRules test = new JOSMTestRules().preferences().main();
+
+    /**
+     * Test of {@link UploadDialogModel}.
+     */
+    @Test
+    void testUploadDialogModel() {
+        assertNotNull(new UploadDialogModel());
+    }
+
+    @Test
+    void testFindHashTags() {
+        UploadDialogModel model = new UploadDialogModel();
+
+        assertNull(model.findHashTags(" "));
+        assertNull(model.findHashTags(" #"));
+        assertNull(model.findHashTags(" # "));
+        assertNull(model.findHashTags(" https://example.com/#map "));
+        assertNull(model.findHashTags("#59606086"));
+        assertEquals("#foo", model.findHashTags(" #foo "));
+        assertEquals("#foo;#bar", model.findHashTags(" #foo #bar baz"));
+        assertEquals("#foo;#bar", model.findHashTags(" #foo, #bar, baz"));
+        assertEquals("#foo;#bar", model.findHashTags(" #foo; #bar; baz"));
+        assertEquals("#hotosm-project-4773;#DRONEBIRD;#OsakaQuake2018;#AOYAMAVISION",
+            model.findHashTags("#hotosm-project-4773 #DRONEBIRD #OsakaQuake2018 #AOYAMAVISION"));
+    }
+
+    @Test
+    void testCommentWithHashtags() {
+        UploadDialogModel model = new UploadDialogModel();
+        model.add("comment", "comment with a #hashtag");
+        assertEquals("#hashtag", model.getValue("hashtags"));
+    }
+
+    @Test
+    void testGetCommentWithDataSetHashTag() {
+        assertEquals("", UploadDialogModel.addHashTagsFromDataSet(null, null));
+        DataSet ds = new DataSet();
+        assertEquals("foo", UploadDialogModel.addHashTagsFromDataSet("foo", ds));
+        ds.getChangeSetTags().put("hashtags", "bar");
+        assertEquals("foo #bar", UploadDialogModel.addHashTagsFromDataSet("foo", ds));
+        ds.getChangeSetTags().put("hashtags", "bar;baz;#bar");
+        assertEquals("foo #bar #baz", UploadDialogModel.addHashTagsFromDataSet("foo", ds));
+    }
+
+}
Index: trunk/test/unit/org/openstreetmap/josm/gui/io/UploadDialogTest.java
===================================================================
--- trunk/test/unit/org/openstreetmap/josm/gui/io/UploadDialogTest.java	(revision 18144)
+++ trunk/test/unit/org/openstreetmap/josm/gui/io/UploadDialogTest.java	(revision 18173)
@@ -13,5 +13,4 @@
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
-import java.util.function.Supplier;
 
 import javax.swing.JOptionPane;
@@ -19,5 +18,4 @@
 import org.junit.jupiter.api.Test;
 import org.openstreetmap.josm.TestUtils;
-import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.gui.io.UploadDialog.UploadAction;
 import org.openstreetmap.josm.io.UploadStrategySpecification;
@@ -82,9 +80,4 @@
             return new ConcurrentHashMap<>();
         }
-
-        @Override
-        public void forceUpdateActiveField() {
-            // Do nothing
-        }
     }
 
@@ -114,39 +107,4 @@
         // test with unassigned unicode characters ==> no unicode block
         assertTrue(UploadDialog.UploadAction.isUploadCommentTooShort("\u0860"));
-    }
-
-    private static void doTestGetLastChangesetTagFromHistory(String historyKey, Supplier<String> methodToTest, String def) {
-        Config.getPref().putList(historyKey, null);
-        Config.getPref().putInt(BasicUploadSettingsPanel.HISTORY_LAST_USED_KEY, 0);
-        Config.getPref().putInt(BasicUploadSettingsPanel.HISTORY_MAX_AGE_KEY, 30);
-        assertNull(methodToTest.get());          // age NOK (history empty)
-        Config.getPref().putList(historyKey, Arrays.asList("foo"));
-        assertNull(methodToTest.get());          // age NOK (history not empty)
-        Config.getPref().putLong(BasicUploadSettingsPanel.HISTORY_LAST_USED_KEY, System.currentTimeMillis() / 1000);
-        assertEquals("foo", methodToTest.get()); // age OK, history not empty
-        Config.getPref().putList(historyKey, null);
-        assertEquals(def, methodToTest.get());   // age OK, history empty
-    }
-
-    /**
-     * Test of {@link UploadDialog#getLastChangesetCommentFromHistory} method.
-     */
-    @Test
-    void testGetLastChangesetCommentFromHistory() {
-        doTestGetLastChangesetTagFromHistory(
-                BasicUploadSettingsPanel.HISTORY_KEY,
-                UploadDialog::getLastChangesetCommentFromHistory,
-                null);
-    }
-
-    /**
-     * Test of {@link UploadDialog#getLastChangesetSourceFromHistory} method.
-     */
-    @Test
-    void testGetLastChangesetSourceFromHistory() {
-        doTestGetLastChangesetTagFromHistory(
-                BasicUploadSettingsPanel.SOURCE_HISTORY_KEY,
-                UploadDialog::getLastChangesetSourceFromHistory,
-                BasicUploadSettingsPanel.getDefaultSources().get(0));
     }
 
@@ -186,14 +144,3 @@
         doTestValidateUploadTag("upload.source");
     }
-
-    @Test
-    void testGetCommentWithDataSetHashTag() {
-        assertEquals("", UploadDialog.getCommentWithDataSetHashTag(null, null));
-        DataSet ds = new DataSet();
-        assertEquals("foo", UploadDialog.getCommentWithDataSetHashTag("foo", ds));
-        ds.getChangeSetTags().put("hashtags", "bar");
-        assertEquals("foo #bar", UploadDialog.getCommentWithDataSetHashTag("foo", ds));
-        ds.getChangeSetTags().put("hashtags", "bar;baz;#bar");
-        assertEquals("foo #bar #baz", UploadDialog.getCommentWithDataSetHashTag("foo", ds));
-    }
 }
Index: trunk/test/unit/org/openstreetmap/josm/gui/tagging/ac/AutoCompComboBoxModelTest.java
===================================================================
--- trunk/test/unit/org/openstreetmap/josm/gui/tagging/ac/AutoCompComboBoxModelTest.java	(revision 18173)
+++ trunk/test/unit/org/openstreetmap/josm/gui/tagging/ac/AutoCompComboBoxModelTest.java	(revision 18173)
@@ -0,0 +1,100 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.tagging.ac;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertSame;
+
+import java.util.Comparator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import org.openstreetmap.josm.data.osm.search.SearchSetting;
+import org.openstreetmap.josm.data.tagging.ac.AutoCompletionItem;
+import org.openstreetmap.josm.data.tagging.ac.AutoCompletionPriority;
+
+import org.junit.jupiter.api.Test;
+import org.openstreetmap.josm.testutils.annotations.FullPreferences;
+
+/**
+ * Test class for {@link AutoCompComboBoxModel}
+ */
+@FullPreferences
+class AutoCompComboBoxModelTest {
+
+    class TestData {
+        public String s;
+        public AutoCompletionItem ac;
+        public SearchSetting ss;
+
+        TestData(String s, AutoCompletionPriority p) {
+            this.s = s;
+            this.ss = new SearchSetting();
+            ss.text = s;
+            this.ac = new AutoCompletionItem(s, p);
+        }
+    }
+
+    // CHECKSTYLE.OFF: SingleSpaceSeparator
+    // CHECKSTYLE.OFF: ParenPad
+
+    Map<String, TestData> testData = new LinkedHashMap<String, TestData>() {{
+        put("a1",   new TestData("a1",   AutoCompletionPriority.UNKNOWN));
+        put("a2",   new TestData("a2",   AutoCompletionPriority.IS_IN_STANDARD));
+        put("a3",   new TestData("a3",   AutoCompletionPriority.IS_IN_DATASET));
+        put("a4",   new TestData("a4",   AutoCompletionPriority.IS_IN_STANDARD_AND_IN_DATASET));
+        put("b",    new TestData("b",    AutoCompletionPriority.UNKNOWN));
+        put("bcde", new TestData("bcde", AutoCompletionPriority.UNKNOWN));
+        put("bde",  new TestData("bde",  AutoCompletionPriority.UNKNOWN));
+        put("bdef", new TestData("bdef", AutoCompletionPriority.IS_IN_STANDARD_AND_IN_DATASET));
+    }};
+
+    @Test
+    void testAutoCompModel() {
+        assertNotNull(new AutoCompComboBoxModel<String>());
+        assertNotNull(new AutoCompComboBoxModel<SearchSetting>());
+        assertNotNull(new AutoCompComboBoxModel<AutoCompletionItem>());
+    }
+
+    @Test
+    void testAutoCompModelFindString() {
+        AutoCompComboBoxModel<String> model = new AutoCompComboBoxModel<>();
+        testData.forEach((k, v) -> model.addElement(v.s));
+
+        assertNull(model.findBestCandidate("bb"));
+        assertEquals("a1",   model.findBestCandidate("a" ));
+        assertEquals("b",    model.findBestCandidate("b" ));
+        assertEquals("bcde", model.findBestCandidate("bc"));
+        assertEquals("bde",  model.findBestCandidate("bd"));
+    }
+
+    @Test
+    void testAutoCompModelFindSearchSetting() {
+        AutoCompComboBoxModel<SearchSetting> model = new AutoCompComboBoxModel<>();
+        // Use the default Comparator (that compares on toString).
+        testData.forEach((k, v) -> model.addElement(v.ss));
+
+        assertNull(model.findBestCandidate("bb"));
+        // test for sameness (aka ==).  Some objects are expensive to copy, so we want to be able to
+        // round-trip an object thru the AutoCompComboBox without copying it.
+        assertSame(testData.get("a1"  ).ss, model.findBestCandidate("a" ));
+        assertSame(testData.get("b"   ).ss, model.findBestCandidate("b" ));
+        assertSame(testData.get("bcde").ss, model.findBestCandidate("bc"));
+        assertSame(testData.get("bde" ).ss, model.findBestCandidate("bd"));
+    }
+
+    @Test
+    void testAutoCompModelFindAutoCompletionItem() {
+        AutoCompComboBoxModel<AutoCompletionItem> model = new AutoCompComboBoxModel<>();
+        // AutoCompletionItem implements Comparable. Build a Comparator from Comparable.
+        model.setComparator(Comparator.naturalOrder());
+        testData.forEach((k, v) -> model.addElement(v.ac));
+
+        assertNull(model.findBestCandidate("bb"));
+        assertSame(testData.get("a4"  ).ac, model.findBestCandidate("a" )); // higher prio than "a1"
+        assertSame(testData.get("b"   ).ac, model.findBestCandidate("b" ));
+        assertSame(testData.get("bcde").ac, model.findBestCandidate("bc"));
+        assertSame(testData.get("bdef").ac, model.findBestCandidate("bd")); // higher prio than "bde"
+    }
+}
Index: trunk/test/unit/org/openstreetmap/josm/gui/tagging/ac/AutoCompComboBoxTest.java
===================================================================
--- trunk/test/unit/org/openstreetmap/josm/gui/tagging/ac/AutoCompComboBoxTest.java	(revision 18173)
+++ trunk/test/unit/org/openstreetmap/josm/gui/tagging/ac/AutoCompComboBoxTest.java	(revision 18173)
@@ -0,0 +1,21 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.tagging.ac;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+import org.junit.jupiter.api.Test;
+import org.openstreetmap.josm.data.tagging.ac.AutoCompletionItem;
+import org.openstreetmap.josm.testutils.annotations.FullPreferences;
+
+/**
+ * Test class for {@link AutoCompletingComboBox}
+ */
+@FullPreferences
+class AutoCompComboBoxTest {
+
+    @Test
+    void testAutoCompletingComboBox() {
+        assertNotNull(new AutoCompComboBox<String>());
+        assertNotNull(new AutoCompComboBox<AutoCompletionItem>());
+    }
+}
