Index: trunk/src/org/openstreetmap/josm/gui/conflict/tags/TagConflictResolverModel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/conflict/tags/TagConflictResolverModel.java	(revision 18006)
+++ trunk/src/org/openstreetmap/josm/gui/conflict/tags/TagConflictResolverModel.java	(revision 18007)
@@ -10,4 +10,5 @@
 import java.util.Map;
 import java.util.Set;
+import java.util.function.BiConsumer;
 
 import javax.swing.table.DefaultTableModel;
@@ -299,3 +300,12 @@
         return new HashSet<>(keysWithConflicts);
     }
+
+    /**
+     * Perform an action on all decisions, useful to perform a global decision (keep all, keep none, etc.)
+     * @param action action to perform on decision
+     * @since 18007
+     */
+    public final void actOnDecisions(BiConsumer<String, MultiValueResolutionDecision> action) {
+        decisions.forEach(action::accept);
+    }
 }
Index: trunk/src/org/openstreetmap/josm/io/GeoJSONReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/GeoJSONReader.java	(revision 18006)
+++ trunk/src/org/openstreetmap/josm/io/GeoJSONReader.java	(revision 18007)
@@ -12,9 +12,9 @@
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Optional;
-import java.util.TreeMap;
 import java.util.stream.Collectors;
 
@@ -37,4 +37,7 @@
 import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.data.osm.RelationMember;
+import org.openstreetmap.josm.data.osm.Tag;
+import org.openstreetmap.josm.data.osm.TagCollection;
+import org.openstreetmap.josm.data.osm.TagMap;
 import org.openstreetmap.josm.data.osm.UploadPolicy;
 import org.openstreetmap.josm.data.osm.Way;
@@ -43,4 +46,6 @@
 import org.openstreetmap.josm.data.validation.TestError;
 import org.openstreetmap.josm.data.validation.tests.DuplicateWay;
+import org.openstreetmap.josm.gui.conflict.tags.TagConflictResolutionUtil;
+import org.openstreetmap.josm.gui.conflict.tags.TagConflictResolverModel;
 import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
 import org.openstreetmap.josm.gui.progress.ProgressMonitor;
@@ -329,5 +334,5 @@
 
     /**
-     * Replace all existing tags in primitive by the values given in the GeoJSON feature.
+     * Merge existing tags in primitive (if any) with the values given in the GeoJSON feature.
      * @param feature the GeoJSON feature
      * @param primitive the OSM primitive
@@ -335,6 +340,17 @@
     private static void fillTagsFromFeature(final JsonObject feature, final OsmPrimitive primitive) {
         if (feature != null) {
-            primitive.setKeys(getTags(feature));
-        }
+            TagCollection featureTags = getTags(feature);
+            primitive.setKeys(new TagMap(primitive.isTagged() ? mergeAllTagValues(primitive, featureTags) : featureTags));
+        }
+    }
+
+    private static TagCollection mergeAllTagValues(final OsmPrimitive primitive, TagCollection featureTags) {
+        TagCollection tags = TagCollection.from(primitive).union(featureTags);
+        TagConflictResolutionUtil.applyAutomaticTagConflictResolution(tags);
+        TagConflictResolutionUtil.normalizeTagCollectionBeforeEditing(tags, Arrays.asList(primitive));
+        TagConflictResolverModel tagModel = new TagConflictResolverModel();
+        tagModel.populate(new TagCollection(tags), tags.getKeysWithMultipleValues());
+        tagModel.actOnDecisions((k, d) -> d.keepAll());
+        return tagModel.getAllResolutions();
     }
 
@@ -347,6 +363,6 @@
     }
 
-    private static Map<String, String> getTags(final JsonObject feature) {
-        final Map<String, String> tags = new TreeMap<>();
+    private static TagCollection getTags(final JsonObject feature) {
+        final TagCollection tags = new TagCollection();
 
         if (feature.containsKey(PROPERTIES) && !feature.isNull(PROPERTIES)) {
@@ -357,5 +373,5 @@
 
                     if (value instanceof JsonString) {
-                        tags.put(stringJsonValueEntry.getKey(), ((JsonString) value).getString());
+                        tags.add(new Tag(stringJsonValueEntry.getKey(), ((JsonString) value).getString()));
                     } else if (value instanceof JsonObject) {
                         Logging.warn(
@@ -365,5 +381,5 @@
                         );
                     } else if (value.getValueType() != JsonValue.ValueType.NULL) {
-                        tags.put(stringJsonValueEntry.getKey(), value.toString());
+                        tags.add(new Tag(stringJsonValueEntry.getKey(), value.toString()));
                     }
                 }
Index: trunk/test/data/regress/21044/test.geojson
===================================================================
--- trunk/test/data/regress/21044/test.geojson	(revision 18007)
+++ trunk/test/data/regress/21044/test.geojson	(revision 18007)
@@ -0,0 +1,52 @@
+{
+    "type": "FeatureCollection",
+    "name": "test files",
+    "crs": {
+        "type": "name",
+        "properties": {
+            "name": "urn:ogc:def:crs:OGC:1.3:CRS84"
+        }
+    },
+    "features": [
+        {
+            "type": "Feature",
+            "properties": {
+                "addr:building": null,
+                "addr:postcode": "06883",
+                "addr:housenumber": "26",
+                "addr:city": "Weston",
+                "addr:state": "CT",
+                "addr:street": "Pent Road",
+                "addr:unit": null,
+                "addr:floor": null
+            },
+            "geometry": {
+                "type": "Point",
+                "coordinates": [
+                    -73.39619362285797,
+                    41.235575988569618
+                ]
+            }
+        },
+        {
+            "type": "Feature",
+            "properties": {
+                "addr:building": null,
+                "addr:postcode": "06883",
+                "addr:housenumber": "22",
+                "addr:city": "Weston",
+                "addr:state": "CT",
+                "addr:street": "Pent Road",
+                "addr:unit": null,
+                "addr:floor": null
+            },
+            "geometry": {
+                "type": "Point",
+                "coordinates": [
+                    -73.39619362285797,
+                    41.235575988569618
+                ]
+            }
+        }
+    ]
+}
Index: trunk/test/unit/org/openstreetmap/josm/io/GeoJSONReaderTest.java
===================================================================
--- trunk/test/unit/org/openstreetmap/josm/io/GeoJSONReaderTest.java	(revision 18006)
+++ trunk/test/unit/org/openstreetmap/josm/io/GeoJSONReaderTest.java	(revision 18007)
@@ -217,4 +217,23 @@
 
     /**
+     * Non-regression test for <a href="https://josm.openstreetmap.de/ticket/21044">Bug #21044</a>.
+     * @throws Exception in case of error
+     */
+    @Test
+    void testTicket21044Duplicates() throws Exception {
+        try (InputStream in = TestUtils.getRegressionDataStream(21044, "test.geojson")) {
+            final List<OsmPrimitive> primitives = new ArrayList<>(
+                    new GeoJSONReader().doParseDataSet(in, null).getPrimitives(it -> true));
+            assertEquals(1, primitives.size());
+            OsmPrimitive primitive = primitives.get(0);
+            assertTrue(primitive instanceof Node);
+            Node n = (Node) primitive;
+            assertNull(n.get("addr:building"));
+            assertEquals("06883", n.get("addr:postcode"));
+            assertEquals("22;26", n.get("addr:housenumber"));
+        }
+    }
+
+    /**
      * Tests error reporting for an invalid FeatureCollection
      * @throws Exception in case of error
@@ -229,4 +248,3 @@
         }
     }
-
 }
