Index: /trunk/src/org/openstreetmap/josm/data/osm/AbstractPrimitive.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/data/osm/AbstractPrimitive.java	(revision 16640)
+++ /trunk/src/org/openstreetmap/josm/data/osm/AbstractPrimitive.java	(revision 16641)
@@ -735,4 +735,5 @@
                             "created_by",
                             "converted_by",
+                            "current_id",
                             "geobase:datasetName",
                             "geobase:uuid",
Index: /trunk/src/org/openstreetmap/josm/io/OsmReader.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/io/OsmReader.java	(revision 16640)
+++ /trunk/src/org/openstreetmap/josm/io/OsmReader.java	(revision 16641)
@@ -5,5 +5,7 @@
 
 import java.io.InputStream;
+import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.Objects;
 import java.util.Set;
@@ -40,7 +42,24 @@
 public class OsmReader extends AbstractReader {
 
+    /**
+     * Options are used to change how the xml data is parsed.
+     * For example, {@link Options#CONVERT_UNKNOWN_TO_TAGS} is used to convert unknown XML attributes to a tag for the object.
+     * @since 16641
+     */
+    public enum Options {
+        /**
+         * Convert unknown XML attributes to tags
+         */
+        CONVERT_UNKNOWN_TO_TAGS,
+        /**
+         * Save the original id of an object (currently stored in `current_id`)
+         */
+        SAVE_ORIGINAL_ID
+    }
+
     protected XMLStreamReader parser;
 
-    protected boolean convertUnknownToTags;
+    /** The {@link OsmReader.Options} to use when parsing the xml data */
+    protected final Collection<Options> options;
 
     private static final Set<String> COMMON_XML_ATTRIBUTES = new TreeSet<>();
@@ -65,17 +84,17 @@
      */
     protected OsmReader() {
-        this(false);
+        this((Options) null);
     }
 
     /**
      * constructor (for private and subclasses use only)
-     * @param convertUnknownToTags if true, keep unknown xml attributes as tags
+     * @param options The options to use when reading data
      *
      * @see #parseDataSet(InputStream, ProgressMonitor)
-     * @since 15470
-     */
-    protected OsmReader(boolean convertUnknownToTags) {
+     * @since 16641
+     */
+    protected OsmReader(Options... options) {
         // Restricts visibility
-        this.convertUnknownToTags = convertUnknownToTags;
+        this.options = options == null ? Collections.emptyList() : Arrays.asList(options);
     }
 
@@ -426,5 +445,8 @@
             parseChangeset(current, parser.getAttributeValue(null, "changeset"));
 
-            if (convertUnknownToTags) {
+            if (options.contains(Options.SAVE_ORIGINAL_ID)) {
+                parseTag(current, "current_id", Long.toString(getLong("id")));
+            }
+            if (options.contains(Options.CONVERT_UNKNOWN_TO_TAGS)) {
                 for (int i = 0; i < parser.getAttributeCount(); i++) {
                     if (!COMMON_XML_ATTRIBUTES.contains(parser.getAttributeLocalName(i))) {
@@ -497,5 +519,5 @@
      */
     public static DataSet parseDataSet(InputStream source, ProgressMonitor progressMonitor) throws IllegalDataException {
-        return parseDataSet(source, progressMonitor, false);
+        return parseDataSet(source, progressMonitor, (Options) null);
     }
 
@@ -505,14 +527,14 @@
      * @param source the source input stream. Must not be null.
      * @param progressMonitor the progress monitor. If null, {@link NullProgressMonitor#INSTANCE} is assumed
-     * @param convertUnknownToTags true if unknown xml attributes should be kept as tags
+     * @param options The options to use when parsing the dataset
      *
      * @return the dataset with the parsed data
      * @throws IllegalDataException if an error was found while parsing the data from the source
      * @throws IllegalArgumentException if source is null
-     * @since 15470
-     */
-    public static DataSet parseDataSet(InputStream source, ProgressMonitor progressMonitor, boolean convertUnknownToTags)
+     * @since 16641
+     */
+    public static DataSet parseDataSet(InputStream source, ProgressMonitor progressMonitor, Options... options)
             throws IllegalDataException {
-        return new OsmReader(convertUnknownToTags).doParseDataSet(source, progressMonitor);
+        return new OsmReader(options).doParseDataSet(source, progressMonitor);
     }
 }
Index: /trunk/test/unit/org/openstreetmap/josm/io/OsmReaderTest.java
===================================================================
--- /trunk/test/unit/org/openstreetmap/josm/io/OsmReaderTest.java	(revision 16640)
+++ /trunk/test/unit/org/openstreetmap/josm/io/OsmReaderTest.java	(revision 16641)
@@ -23,4 +23,5 @@
 import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
 import org.openstreetmap.josm.gui.progress.ProgressMonitor;
+import org.openstreetmap.josm.io.OsmReader.Options;
 import org.openstreetmap.josm.testutils.JOSMTestRules;
 
@@ -83,6 +84,17 @@
         try (InputStream in = new ByteArrayInputStream(
                 ("<?xml version='1.0' encoding='UTF-8'?>" + osm).getBytes(StandardCharsets.UTF_8))) {
-            assertTrue(OsmReader.parseDataSet(in, NullProgressMonitor.INSTANCE, parseUnknownAttributes).allPrimitives()
+            assertTrue(OsmReader.parseDataSet(in, NullProgressMonitor.INSTANCE, Options.CONVERT_UNKNOWN_TO_TAGS).allPrimitives()
                     .isEmpty());
+        }
+        testUnknown(osm, parseUnknownAttributes, true);
+        testUnknown(osm, parseUnknownAttributes, true);
+    }
+
+    private static void testUnknown(String osm, boolean parseUnknownAttributes, boolean keepOriginalId)
+            throws Exception {
+        try (InputStream in = new ByteArrayInputStream(
+                ("<?xml version='1.0' encoding='UTF-8'?>" + osm).getBytes(StandardCharsets.UTF_8))) {
+            assertTrue(OsmReader.parseDataSet(in, NullProgressMonitor.INSTANCE, Options.CONVERT_UNKNOWN_TO_TAGS, Options.SAVE_ORIGINAL_ID)
+                    .allPrimitives().isEmpty());
         }
     }
@@ -141,12 +153,12 @@
      * Test valid data.
      * @param osm OSM data without XML prefix
-     * @param parseUnknownAttributes if true, attempt to parse unknown xml attributes
+     * @param options The options to use to parse the data
      * @return parsed data set
      * @throws Exception if any error occurs
      */
-    private static DataSet testValidData(String osm, boolean parseUnknownAttributes) throws Exception {
-        try (InputStream in = new ByteArrayInputStream(
-                ("<?xml version='1.0' encoding='UTF-8'?>" + osm).getBytes(StandardCharsets.UTF_8))) {
-            return OsmReader.parseDataSet(in, NullProgressMonitor.INSTANCE, parseUnknownAttributes);
+    private static DataSet testValidData(String osm, Options... options) throws Exception {
+        try (InputStream in = new ByteArrayInputStream(
+                ("<?xml version='1.0' encoding='UTF-8'?>" + osm).getBytes(StandardCharsets.UTF_8))) {
+            return OsmReader.parseDataSet(in, NullProgressMonitor.INSTANCE, options);
         }
     }
@@ -183,5 +195,5 @@
         try (InputStream in = new ByteArrayInputStream(
                 ("<?xml version='1.0' encoding='UTF-8'?>" + osm).getBytes(StandardCharsets.UTF_8))) {
-            OsmReader.parseDataSet(in, NullProgressMonitor.INSTANCE, parseUnknownAttributes);
+            OsmReader.parseDataSet(in, NullProgressMonitor.INSTANCE, Options.CONVERT_UNKNOWN_TO_TAGS);
             fail("should throw exception");
         } catch (IllegalDataException e) {
@@ -325,6 +337,8 @@
         String gdprChangeset = "<osm version='0.6'><node id='1' version='1' changeset='0'/></osm>";
         testValidData(gdprChangeset);
-        testValidData(gdprChangeset, true);
-        testValidData(gdprChangeset, false);
+        testValidData(gdprChangeset, Options.CONVERT_UNKNOWN_TO_TAGS);
+        testValidData(gdprChangeset, (Options) null);
+        testValidData(gdprChangeset, Options.SAVE_ORIGINAL_ID);
+        testValidData(gdprChangeset, Options.values());
     }
 
@@ -406,5 +420,6 @@
                 "<remark>runtime error: Query ran out of memory in \"query\" at line 5.</remark>\r\n" +
                 "</osm>";
-        for (DataSet ds : Arrays.asList(testValidData(query), testValidData(query, true), testValidData(query, false))) {
+        for (DataSet ds : Arrays.asList(testValidData(query), testValidData(query, Options.CONVERT_UNKNOWN_TO_TAGS), testValidData(query, (Options) null),
+                testValidData(query, Options.SAVE_ORIGINAL_ID), testValidData(query, Options.values()))) {
             assertEquals("runtime error: Query ran out of memory in \"query\" at line 5.", ds.getRemark());
         }
@@ -421,12 +436,16 @@
         DataSet ds = testValidData(testData);
         assertEquals(0, ds.getNodes().iterator().next().getKeys().size());
-
-        ds = testValidData(testData, true);
+        assertEquals(1, ds.getNodes().iterator().next().getUniqueId());
+
+        ds = testValidData(testData, Options.CONVERT_UNKNOWN_TO_TAGS);
         Node firstNode = ds.getNodes().iterator().next();
         assertEquals(1, firstNode.getKeys().size());
         assertEquals("randomvalue", firstNode.get("randomkey"));
-
-        ds = testValidData(testData, false);
+        assertEquals(1, ds.getNodes().iterator().next().getUniqueId());
+
+
+        ds = testValidData(testData, (Options) null);
         assertEquals(0, ds.getNodes().iterator().next().getKeys().size());
+        assertEquals(1, ds.getNodes().iterator().next().getUniqueId());
     }
 }
