Index: src/org/openstreetmap/josm/data/osm/AbstractPrimitive.java
===================================================================
--- src/org/openstreetmap/josm/data/osm/AbstractPrimitive.java	(revision 12429)
+++ src/org/openstreetmap/josm/data/osm/AbstractPrimitive.java	(working copy)
@@ -48,11 +48,37 @@
 
     private static final AtomicLong idCounter = new AtomicLong(0);
 
+    /**
+     * Generates a new primitive unique id.
+     * @return new primitive unique (negative) id
+     */
     static long generateUniqueId() {
         return idCounter.decrementAndGet();
     }
 
     /**
+     * Returns the current primitive unique id.
+     * @return the current primitive unique (negative) id (last generated)
+     * @since xxx
+     */
+    public static long currentUniqueId() {
+        return idCounter.get();
+    }
+
+    /**
+     * Advances the current primitive unique id to skip a range of values.
+     * @param newId new unique id
+     * @throws IllegalArgumentException if newId is greater than current unique id
+     * @since xxx
+     */
+    public static void advanceUniqueId(long newId) {
+        if (newId > currentUniqueId()) {
+            throw new IllegalArgumentException("Cannot modify the id counter backwards");
+        }
+        idCounter.set(newId);
+    }
+
+    /**
      * This flag shows, that the properties have been changed by the user
      * and on upload the object will be send to the server.
      */
Index: src/org/openstreetmap/josm/data/osm/DataSet.java
===================================================================
--- src/org/openstreetmap/josm/data/osm/DataSet.java	(revision 12429)
+++ src/org/openstreetmap/josm/data/osm/DataSet.java	(working copy)
@@ -233,7 +233,7 @@
             // and then get the cloned members
             Collection<Relation> relations = copyFrom.getRelations();
             for (Relation r : relations) {
-                Relation newRelation = new Relation(r, r.isNew());
+                Relation newRelation = new Relation(r);
                 newRelation.setMembers(null);
                 primMap.put(r, newRelation);
                 addPrimitive(newRelation);
@@ -250,6 +250,7 @@
                 dataSources.add(new DataSource(source));
             }
             version = copyFrom.version;
+            uploadPolicy = copyFrom.uploadPolicy;
         } finally {
             copyFrom.getReadLock().unlock();
         }
Index: src/org/openstreetmap/josm/gui/preferences/advanced/AdvancedPreference.java
===================================================================
--- src/org/openstreetmap/josm/gui/preferences/advanced/AdvancedPreference.java	(revision 12429)
+++ src/org/openstreetmap/josm/gui/preferences/advanced/AdvancedPreference.java	(working copy)
@@ -42,6 +42,7 @@
 import org.openstreetmap.josm.data.preferences.Setting;
 import org.openstreetmap.josm.data.preferences.StringSetting;
 import org.openstreetmap.josm.gui.dialogs.LogShowDialog;
+import org.openstreetmap.josm.gui.layer.OsmDataLayer;
 import org.openstreetmap.josm.gui.preferences.DefaultTabPreferenceSetting;
 import org.openstreetmap.josm.gui.preferences.PreferenceSetting;
 import org.openstreetmap.josm.gui.preferences.PreferenceSettingFactory;
@@ -50,6 +51,7 @@
 import org.openstreetmap.josm.gui.widgets.AbstractFileChooser;
 import org.openstreetmap.josm.gui.widgets.JosmTextField;
 import org.openstreetmap.josm.tools.GBC;
+import org.openstreetmap.josm.tools.Territories;
 import org.openstreetmap.josm.tools.Utils;
 
 /**
@@ -322,6 +324,14 @@
         }
 
         menu.addSeparator();
+        menu.add(new AbstractAction(tr("Edit boundaries database")) {
+            @Override
+            public void actionPerformed(ActionEvent ae) {
+                Main.getLayerManager().addLayer(
+                    new OsmDataLayer(Territories.getDataSet(), Territories.FILENAME, null));
+            }
+        });
+        menu.addSeparator();
         menu.add(getProfileMenu());
         menu.addSeparator();
         menu.add(new AbstractAction(tr("Reset preferences")) {
Index: src/org/openstreetmap/josm/io/OsmReader.java
===================================================================
--- src/org/openstreetmap/josm/io/OsmReader.java	(revision 12429)
+++ src/org/openstreetmap/josm/io/OsmReader.java	(working copy)
@@ -11,6 +11,7 @@
 import java.util.Collection;
 import java.util.List;
 import java.util.Objects;
+import java.util.OptionalLong;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -30,6 +31,7 @@
 import org.openstreetmap.josm.data.osm.DataSet.UploadPolicy;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.NodeData;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
 import org.openstreetmap.josm.data.osm.PrimitiveData;
 import org.openstreetmap.josm.data.osm.Relation;
@@ -213,8 +215,23 @@
         jumpToEnd();
     }
 
+    @SuppressWarnings("unchecked")
+    protected <T extends OsmPrimitive> T buildPrimitive(PrimitiveData pd) throws XMLStreamException {
+        readCommon(pd);
+        OsmPrimitive p;
+        if (pd.getUniqueId() < AbstractPrimitive.currentUniqueId()) {
+            p = pd.getType().newInstance(pd.getUniqueId(), true);
+        } else {
+            p = pd.getType().newVersionedInstance(pd.getId(), pd.getVersion());
+        }
+        p.setVisible(pd.isVisible());
+        p.load(pd);
+        externalIdMap.put(pd.getPrimitiveId(), p);
+        return (T) p;
+    }
+
     protected Node parseNode() throws XMLStreamException {
-        NodeData nd = new NodeData();
+        NodeData nd = new NodeData(0);
         String lat = parser.getAttributeValue(null, "lat");
         String lon = parser.getAttributeValue(null, "lon");
         LatLon ll = null;
@@ -226,15 +243,11 @@
                 Main.trace(e);
             }
         }
-        readCommon(nd);
+        Node n = buildPrimitive(nd);
         if (lat != null && lon != null && (ll == null || !ll.isValid())) {
             throwException(tr("Illegal value for attributes ''lat'', ''lon'' on node with ID {0}. Got ''{1}'', ''{2}''.",
                     Long.toString(nd.getId()), lat, lon));
         }
-        Node n = new Node(nd.getId(), nd.getVersion());
-        n.setVisible(nd.isVisible());
-        n.load(nd);
-        externalIdMap.put(nd.getPrimitiveId(), n);
         while (true) {
             int event = parser.next();
             if (event == XMLStreamConstants.START_ELEMENT) {
@@ -249,13 +262,8 @@
     }
 
     protected Way parseWay() throws XMLStreamException {
-        WayData wd = new WayData();
-        readCommon(wd);
-        Way w = new Way(wd.getId(), wd.getVersion());
-        w.setVisible(wd.isVisible());
-        w.load(wd);
-        externalIdMap.put(wd.getPrimitiveId(), w);
-
+        WayData wd = new WayData(0);
+        Way w = buildPrimitive(wd);
         Collection<Long> nodeIds = new ArrayList<>();
         while (true) {
             int event = parser.next();
@@ -299,13 +307,8 @@
     }
 
     protected Relation parseRelation() throws XMLStreamException {
-        RelationData rd = new RelationData();
-        readCommon(rd);
-        Relation r = new Relation(rd.getId(), rd.getVersion());
-        r.setVisible(rd.isVisible());
-        r.load(rd);
-        externalIdMap.put(rd.getPrimitiveId(), r);
-
+        RelationData rd = new RelationData(0);
+        Relation r = buildPrimitive(rd);
         Collection<RelationMemberData> members = new ArrayList<>();
         while (true) {
             int event = parser.next();
@@ -647,6 +650,10 @@
         } catch (IOException e) {
             throw new IllegalDataException(e);
         } finally {
+            OptionalLong minId = externalIdMap.values().stream().mapToLong(AbstractPrimitive::getUniqueId).min();
+            if (minId.isPresent() && minId.getAsLong() < AbstractPrimitive.currentUniqueId()) {
+                AbstractPrimitive.advanceUniqueId(minId.getAsLong());
+            }
             progressMonitor.finishTask();
             progressMonitor.removeCancelListener(cancelListener);
         }
Index: src/org/openstreetmap/josm/tools/Territories.java
===================================================================
--- src/org/openstreetmap/josm/tools/Territories.java	(revision 12429)
+++ src/org/openstreetmap/josm/tools/Territories.java	(working copy)
@@ -27,6 +27,9 @@
  */
 public final class Territories {
 
+    /** Internal OSM filename */
+    public static final String FILENAME = "boundaries.osm";
+
     private static final String ISO3166_1 = "ISO3166-1:alpha2";
     private static final String ISO3166_2 = "ISO3166-2";
 
@@ -78,7 +81,7 @@
      */
     public static synchronized void initialize() {
         iso3166Cache = new HashMap<>();
-        try (CachedFile cf = new CachedFile("resource://data/boundaries.osm");
+        try (CachedFile cf = new CachedFile("resource://data/" + FILENAME);
                 InputStream is = cf.getInputStream()) {
             dataSet = OsmReader.parseDataSet(is, null);
             Collection<OsmPrimitive> candidates = new ArrayList<>(dataSet.getWays());
