Index: trunk/src/org/openstreetmap/josm/Main.java
===================================================================
--- trunk/src/org/openstreetmap/josm/Main.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/Main.java	(revision 13434)
@@ -270,6 +270,7 @@
 
     /**
-     * Gets the active edit data set.
+     * Gets the active edit data set (not read-only).
      * @return That data set, <code>null</code>.
+     * @see #getActiveDataSet
      * @since 12691
      */
@@ -277,9 +278,17 @@
 
     /**
-     * Sets the active data set.
-     * @param ds New edit data set, or <code>null</code>
-     * @since 12718
-     */
-    public abstract void setEditDataSet(DataSet ds);
+     * Gets the active data set (can be read-only).
+     * @return That data set, <code>null</code>.
+     * @see #getEditDataSet
+     * @since 13434
+     */
+    public abstract DataSet getActiveDataSet();
+
+    /**
+     * Sets the active data set (and also edit data set if not read-only).
+     * @param ds New data set, or <code>null</code>
+     * @since 13434
+     */
+    public abstract void setActiveDataSet(DataSet ds);
 
     /**
Index: trunk/src/org/openstreetmap/josm/actions/AbstractInfoAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/AbstractInfoAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/AbstractInfoAction.java	(revision 13434)
@@ -101,5 +101,5 @@
     protected void launchInfoBrowsersForSelectedPrimitivesAndNote() {
         List<OsmPrimitive> primitivesToShow = new ArrayList<>();
-        DataSet ds = getLayerManager().getEditDataSet();
+        DataSet ds = getLayerManager().getActiveDataSet();
         if (ds != null) {
             primitivesToShow.addAll(ds.getAllSelected());
@@ -155,5 +155,5 @@
     @Override
     protected void updateEnabledState() {
-        DataSet ds = getLayerManager().getEditDataSet();
+        DataSet ds = getLayerManager().getActiveDataSet();
         setEnabled(ds != null && !ds.selectionEmpty());
     }
Index: trunk/src/org/openstreetmap/josm/actions/AlignInCircleAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/AlignInCircleAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/AlignInCircleAction.java	(revision 13434)
@@ -340,5 +340,5 @@
     @Override
     protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
-        setEnabled(selection != null && !selection.isEmpty());
+        updateEnabledStateOnModifiableSelection(selection);
     }
 
Index: trunk/src/org/openstreetmap/josm/actions/AlignInLineAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/AlignInLineAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/AlignInLineAction.java	(revision 13434)
@@ -434,5 +434,5 @@
     @Override
     protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
-        setEnabled(selection != null && !selection.isEmpty());
+        updateEnabledStateOnModifiableSelection(selection);
     }
 }
Index: trunk/src/org/openstreetmap/josm/actions/AutoScaleAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/AutoScaleAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/AutoScaleAction.java	(revision 13434)
@@ -76,5 +76,5 @@
      */
     public static void zoomToSelection() {
-        DataSet dataSet = MainApplication.getLayerManager().getEditDataSet();
+        DataSet dataSet = MainApplication.getLayerManager().getActiveDataSet();
         if (dataSet == null) {
             return;
@@ -286,5 +286,5 @@
         Collection<OsmPrimitive> sel = new HashSet<>();
         if ("selection".equals(mode)) {
-            DataSet dataSet = getLayerManager().getEditDataSet();
+            DataSet dataSet = getLayerManager().getActiveDataSet();
             if (dataSet != null) {
                 sel = dataSet.getSelected();
@@ -324,5 +324,5 @@
             lastZoomTime = -1;
         }
-        final DataSet dataset = getLayerManager().getEditDataSet();
+        final DataSet dataset = getLayerManager().getActiveDataSet();
         if (dataset != null) {
             List<DataSource> dataSources = new ArrayList<>(dataset.getDataSources());
@@ -337,5 +337,5 @@
                 } else {
                     lastZoomArea = -1;
-                    Area sourceArea = getLayerManager().getEditDataSet().getDataSourceArea();
+                    Area sourceArea = getLayerManager().getActiveDataSet().getDataSourceArea();
                     if (sourceArea != null) {
                         v.visit(new Bounds(sourceArea.getBounds2D()));
@@ -353,5 +353,5 @@
     @Override
     protected void updateEnabledState() {
-        DataSet ds = getLayerManager().getEditDataSet();
+        DataSet ds = getLayerManager().getActiveDataSet();
         MapFrame map = MainApplication.getMap();
         switch (mode) {
Index: trunk/src/org/openstreetmap/josm/actions/CombineWayAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/CombineWayAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/CombineWayAction.java	(revision 13434)
@@ -251,7 +251,9 @@
     protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
         int numWays = 0;
-        for (OsmPrimitive osm : selection) {
-            if (osm instanceof Way && !osm.isIncomplete() && ++numWays >= 2) {
-                break;
+        if (selection.stream().map(o -> o.getDataSet()).noneMatch(DataSet::isReadOnly)) {
+            for (OsmPrimitive osm : selection) {
+                if (osm instanceof Way && !osm.isIncomplete() && ++numWays >= 2) {
+                    break;
+                }
             }
         }
Index: trunk/src/org/openstreetmap/josm/actions/CopyAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/CopyAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/CopyAction.java	(revision 13434)
@@ -43,5 +43,5 @@
     @Override
     public void actionPerformed(ActionEvent e) {
-        DataSet set = getLayerManager().getEditDataSet();
+        DataSet set = getLayerManager().getActiveDataSet();
         Collection<OsmPrimitive> selection = set == null ? Collections.<OsmPrimitive>emptySet() : set.getSelected();
         if (selection.isEmpty()) {
@@ -50,5 +50,5 @@
         }
 
-        copy(getLayerManager().getEditLayer(), selection);
+        copy(getLayerManager().getActiveDataLayer(), selection);
     }
 
@@ -66,5 +66,5 @@
     @Override
     protected void updateEnabledState() {
-        updateEnabledStateOnCurrentSelection();
+        updateEnabledStateOnCurrentSelection(true);
     }
 
Index: trunk/src/org/openstreetmap/josm/actions/CopyCoordinatesAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/CopyCoordinatesAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/CopyCoordinatesAction.java	(revision 13434)
@@ -55,5 +55,5 @@
 
     private Collection<Node> getSelectedNodes() {
-        DataSet ds = getLayerManager().getEditDataSet();
+        DataSet ds = getLayerManager().getActiveDataSet();
         if (ds == null) {
             return Collections.emptyList();
Index: trunk/src/org/openstreetmap/josm/actions/CreateCircleAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/CreateCircleAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/CreateCircleAction.java	(revision 13434)
@@ -297,5 +297,5 @@
     @Override
     protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
-        setEnabled(selection != null && !selection.isEmpty());
+        updateEnabledStateOnModifiableSelection(selection);
     }
 }
Index: trunk/src/org/openstreetmap/josm/actions/DeleteAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/DeleteAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/DeleteAction.java	(revision 13434)
@@ -82,5 +82,5 @@
     @Override
     protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
-        setEnabled(selection != null && !selection.isEmpty());
+        updateEnabledStateOnModifiableSelection(selection);
     }
 
Index: trunk/src/org/openstreetmap/josm/actions/DistributeAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/DistributeAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/DistributeAction.java	(revision 13434)
@@ -305,5 +305,5 @@
     @Override
     protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
-        setEnabled(selection != null && !selection.isEmpty());
+        updateEnabledStateOnModifiableSelection(selection);
     }
 }
Index: trunk/src/org/openstreetmap/josm/actions/DownloadReferrersAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/DownloadReferrersAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/DownloadReferrersAction.java	(revision 13434)
@@ -66,5 +66,5 @@
     @Override
     protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
-        setEnabled(selection != null && !selection.isEmpty());
+        updateEnabledStateOnModifiableSelection(selection);
     }
 }
Index: trunk/src/org/openstreetmap/josm/actions/DuplicateAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/DuplicateAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/DuplicateAction.java	(revision 13434)
@@ -43,5 +43,5 @@
     @Override
     protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
-        setEnabled(selection != null && !selection.isEmpty());
+        updateEnabledStateOnModifiableSelection(selection);
     }
 }
Index: trunk/src/org/openstreetmap/josm/actions/FollowLineAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/FollowLineAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/FollowLineAction.java	(revision 13434)
@@ -56,5 +56,5 @@
     @Override
     protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
-        setEnabled(selection != null && !selection.isEmpty());
+        updateEnabledStateOnModifiableSelection(selection);
     }
 
Index: trunk/src/org/openstreetmap/josm/actions/HistoryInfoAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/HistoryInfoAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/HistoryInfoAction.java	(revision 13434)
@@ -38,5 +38,5 @@
     @Override
     public void actionPerformed(ActionEvent ae) {
-        DataSet set = getLayerManager().getEditDataSet();
+        DataSet set = getLayerManager().getActiveDataSet();
         if (set != null && !set.selectionEmpty()) {
             HistoryBrowserDialogManager.getInstance().showHistory(set.getAllSelected());
Index: trunk/src/org/openstreetmap/josm/actions/InfoAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/InfoAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/InfoAction.java	(revision 13434)
@@ -34,5 +34,5 @@
     @Override
     public void actionPerformed(ActionEvent ae) {
-        DataSet set = getLayerManager().getEditDataSet();
+        DataSet set = getLayerManager().getActiveDataSet();
         if (set != null) {
             new InspectPrimitiveDialog(set.getAllSelected(), set).showDialog();
@@ -42,5 +42,5 @@
     @Override
     public void updateEnabledState() {
-        updateEnabledStateOnCurrentSelection();
+        updateEnabledStateOnCurrentSelection(true);
     }
 
Index: trunk/src/org/openstreetmap/josm/actions/JoinAreasAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/JoinAreasAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/JoinAreasAction.java	(revision 13434)
@@ -1619,5 +1619,5 @@
     @Override
     protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
-        setEnabled(selection != null && !selection.isEmpty());
+        updateEnabledStateOnModifiableSelection(selection);
     }
 }
Index: trunk/src/org/openstreetmap/josm/actions/JoinNodeWayAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/JoinNodeWayAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/JoinNodeWayAction.java	(revision 13434)
@@ -215,5 +215,5 @@
     @Override
     protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
-        setEnabled(selection != null && !selection.isEmpty());
+        updateEnabledStateOnModifiableSelection(selection);
     }
 }
Index: trunk/src/org/openstreetmap/josm/actions/JosmAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/JosmAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/JosmAction.java	(revision 13434)
@@ -335,13 +335,36 @@
      * Updates enabled state according to primitives currently selected in edit data set, if any.
      * Can be called in {@link #updateEnabledState()} implementations.
+     * @see #updateEnabledStateOnCurrentSelection(boolean)
      * @since 10409
      */
     protected final void updateEnabledStateOnCurrentSelection() {
-        DataSet ds = getLayerManager().getEditDataSet();
-        if (ds == null) {
+        updateEnabledStateOnCurrentSelection(false);
+    }
+
+    /**
+     * Updates enabled state according to primitives currently selected in active data set, if any.
+     * Can be called in {@link #updateEnabledState()} implementations.
+     * @param allowReadOnly if {@code true}, read-only data sets are considered
+     * @since 13434
+     */
+    protected final void updateEnabledStateOnCurrentSelection(boolean allowReadOnly) {
+        DataSet ds = getLayerManager().getActiveDataSet();
+        if (ds != null && (allowReadOnly || !ds.isReadOnly())) {
+            updateEnabledState(ds.getSelected());
+        } else {
             setEnabled(false);
-        } else {
-            updateEnabledState(ds.getSelected());
-        }
+        }
+    }
+
+    /**
+     * Updates enabled state according to selected primitives, if any.
+     * Enables action if the colleciton is not empty and references primitives in a modifiable data layer.
+     * Can be called in {@link #updateEnabledState(Collection)} implementations.
+     * @param selection the collection of selected primitives
+     * @since 13434
+     */
+    protected final void updateEnabledStateOnModifiableSelection(Collection<? extends OsmPrimitive> selection) {
+        setEnabled(selection != null && !selection.isEmpty()
+                && selection.stream().map(OsmPrimitive::getDataSet).noneMatch(DataSet::isReadOnly));
     }
 
Index: trunk/src/org/openstreetmap/josm/actions/MergeNodesAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/MergeNodesAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/MergeNodesAction.java	(revision 13434)
@@ -28,4 +28,5 @@
 import org.openstreetmap.josm.data.coor.EastNorth;
 import org.openstreetmap.josm.data.coor.LatLon;
+import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.DefaultNameFormatter;
 import org.openstreetmap.josm.data.osm.Node;
@@ -364,5 +365,6 @@
     @Override
     protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
-        if (selection == null || selection.isEmpty()) {
+        if (selection == null || selection.isEmpty()
+                || selection.stream().map(OsmPrimitive::getDataSet).anyMatch(DataSet::isReadOnly)) {
             setEnabled(false);
             return;
Index: trunk/src/org/openstreetmap/josm/actions/MergeSelectionAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/MergeSelectionAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/MergeSelectionAction.java	(revision 13434)
@@ -76,5 +76,5 @@
     @Override
     protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
-        setEnabled(selection != null && !selection.isEmpty());
+        updateEnabledStateOnModifiableSelection(selection);
     }
 
Index: trunk/src/org/openstreetmap/josm/actions/MirrorAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/MirrorAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/MirrorAction.java	(revision 13434)
@@ -90,5 +90,5 @@
     @Override
     protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
-        setEnabled(selection != null && !selection.isEmpty());
+        updateEnabledStateOnModifiableSelection(selection);
     }
 }
Index: trunk/src/org/openstreetmap/josm/actions/MoveAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/MoveAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/MoveAction.java	(revision 13434)
@@ -175,5 +175,5 @@
     @Override
     protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
-        setEnabled(selection != null && !selection.isEmpty());
+        updateEnabledStateOnModifiableSelection(selection);
     }
 }
Index: trunk/src/org/openstreetmap/josm/actions/MoveNodeAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/MoveNodeAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/MoveNodeAction.java	(revision 13434)
@@ -11,4 +11,5 @@
 import org.openstreetmap.josm.command.MoveCommand;
 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.data.osm.OsmPrimitive;
@@ -61,5 +62,6 @@
     @Override
     protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
-        if (selection == null || selection.isEmpty()) {
+        if (selection == null || selection.isEmpty()
+                || selection.stream().map(OsmPrimitive::getDataSet).anyMatch(DataSet::isReadOnly)) {
             setEnabled(false);
             return;
Index: trunk/src/org/openstreetmap/josm/actions/OrthogonalizeAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/OrthogonalizeAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/OrthogonalizeAction.java	(revision 13434)
@@ -139,5 +139,5 @@
         @Override
         protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
-            setEnabled(selection != null && !selection.isEmpty());
+            updateEnabledStateOnModifiableSelection(selection);
         }
     }
@@ -646,5 +646,5 @@
     @Override
     protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
-        setEnabled(selection != null && !selection.isEmpty());
+        updateEnabledStateOnModifiableSelection(selection);
     }
 }
Index: trunk/src/org/openstreetmap/josm/actions/PasteTagsAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/PasteTagsAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/PasteTagsAction.java	(revision 13434)
@@ -9,5 +9,4 @@
 import java.util.Collection;
 
-import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.gui.datatransfer.OsmTransferHandler;
@@ -50,16 +49,10 @@
     @Override
     protected void updateEnabledState() {
-        DataSet ds = getLayerManager().getEditDataSet();
-        if (ds == null) {
-            setEnabled(false);
-            return;
-        }
-        // buffer listening slows down the program and is not very good for arbitrary text in buffer
-        setEnabled(!ds.selectionEmpty());
+        updateEnabledStateOnCurrentSelection();
     }
 
     @Override
     protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
-        setEnabled(selection != null && !selection.isEmpty());
+        updateEnabledStateOnModifiableSelection(selection);
     }
 }
Index: trunk/src/org/openstreetmap/josm/actions/PurgeAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/PurgeAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/PurgeAction.java	(revision 13434)
@@ -196,5 +196,5 @@
     @Override
     protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
-        setEnabled(selection != null && !selection.isEmpty());
+        updateEnabledStateOnModifiableSelection(selection);
     }
 }
Index: trunk/src/org/openstreetmap/josm/actions/ReverseWayAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/ReverseWayAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/ReverseWayAction.java	(revision 13434)
@@ -168,5 +168,6 @@
     @Override
     protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
-        setEnabled(selection.stream().anyMatch(o -> o instanceof Way && !o.isIncomplete()));
+        setEnabled(selection.stream().anyMatch(
+                o -> o instanceof Way && !o.isIncomplete() && !o.getDataSet().isReadOnly()));
     }
 }
Index: trunk/src/org/openstreetmap/josm/actions/SelectAllAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/SelectAllAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/SelectAllAction.java	(revision 13434)
@@ -30,5 +30,5 @@
         if (!isEnabled())
             return;
-        DataSet ds = getLayerManager().getEditDataSet();
+        DataSet ds = getLayerManager().getActiveDataSet();
         ds.setSelected(ds.getPrimitives(OsmPrimitive::isSelectable));
     }
@@ -36,9 +36,8 @@
     /**
      * Refreshes the enabled state
-     *
      */
     @Override
     protected void updateEnabledState() {
-        setEnabled(getLayerManager().getEditLayer() != null);
+        setEnabled(getLayerManager().getActiveDataSet() != null);
     }
 }
Index: trunk/src/org/openstreetmap/josm/actions/SelectByInternalPointAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/SelectByInternalPointAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/SelectByInternalPointAction.java	(revision 13434)
@@ -38,5 +38,5 @@
      */
     public static Collection<OsmPrimitive> getSurroundingObjects(EastNorth internalPoint) {
-        return getSurroundingObjects(MainApplication.getLayerManager().getEditDataSet(), internalPoint, false);
+        return getSurroundingObjects(MainApplication.getLayerManager().getActiveDataSet(), internalPoint, false);
     }
 
@@ -103,5 +103,5 @@
     public static void performSelection(EastNorth internalPoint, boolean doAdd, boolean doRemove) {
         final Collection<OsmPrimitive> surroundingObjects = getSurroundingObjects(internalPoint);
-        final DataSet ds = MainApplication.getLayerManager().getEditDataSet();
+        final DataSet ds = MainApplication.getLayerManager().getActiveDataSet();
         if (surroundingObjects.isEmpty()) {
             return;
Index: trunk/src/org/openstreetmap/josm/actions/SelectNonBranchingWaySequencesAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/SelectNonBranchingWaySequencesAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/SelectNonBranchingWaySequencesAction.java	(revision 13434)
@@ -30,5 +30,5 @@
     @Override
     public void actionPerformed(ActionEvent ev) {
-        DataSet ds = getLayerManager().getEditDataSet();
+        DataSet ds = getLayerManager().getActiveDataSet();
         SelectNonBranchingWaySequences ws = new SelectNonBranchingWaySequences(ds.getSelectedWays());
         ws.extend(ds);
@@ -41,5 +41,5 @@
     @Override
     protected void updateEnabledState() {
-        setEnabled(getLayerManager().getEditDataSet() != null);
+        setEnabled(getLayerManager().getActiveDataSet() != null);
     }
 }
Index: trunk/src/org/openstreetmap/josm/actions/ShowStatusReportAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/ShowStatusReportAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/ShowStatusReportAction.java	(revision 13434)
@@ -27,5 +27,4 @@
 import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.DatasetConsistencyTest;
-import org.openstreetmap.josm.spi.preferences.Setting;
 import org.openstreetmap.josm.data.preferences.sources.MapPaintPrefHelper;
 import org.openstreetmap.josm.data.preferences.sources.PresetPrefHelper;
@@ -39,4 +38,5 @@
 import org.openstreetmap.josm.plugins.PluginHandler;
 import org.openstreetmap.josm.spi.preferences.Config;
+import org.openstreetmap.josm.spi.preferences.Setting;
 import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.PlatformHookUnixoid;
@@ -178,5 +178,5 @@
         }
         if (Main.main != null) {
-            DataSet dataset = MainApplication.getLayerManager().getEditDataSet();
+            DataSet dataset = MainApplication.getLayerManager().getActiveDataSet();
             if (dataset != null) {
                 String result = DatasetConsistencyTest.runTests(dataset);
Index: trunk/src/org/openstreetmap/josm/actions/SimplifyWayAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/SimplifyWayAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/SimplifyWayAction.java	(revision 13434)
@@ -301,5 +301,5 @@
     @Override
     protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
-        setEnabled(selection != null && !selection.isEmpty());
+        updateEnabledStateOnModifiableSelection(selection);
     }
 }
Index: trunk/src/org/openstreetmap/josm/actions/SplitWayAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/SplitWayAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/SplitWayAction.java	(revision 13434)
@@ -26,4 +26,5 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.command.SplitWayCommand;
+import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.DefaultNameFormatter;
 import org.openstreetmap.josm.data.osm.Node;
@@ -294,15 +295,8 @@
     @Override
     protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
-        if (selection == null) {
-            setEnabled(false);
-            return;
-        }
-        for (OsmPrimitive primitive: selection) {
-            if (primitive instanceof Node) {
-                setEnabled(true); // Selection still can be wrong, but let SplitWayAction process and tell user what's wrong
-                return;
-            }
-        }
-        setEnabled(false);
+        // Selection still can be wrong, but let SplitWayAction process and tell user what's wrong
+        setEnabled(selection != null && !selection.isEmpty()
+                && selection.stream().map(OsmPrimitive::getDataSet).noneMatch(DataSet::isReadOnly)
+                && selection.stream().anyMatch(o -> o instanceof Node && !o.isIncomplete()));
     }
 }
Index: trunk/src/org/openstreetmap/josm/actions/TaggingPresetSearchAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/TaggingPresetSearchAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/TaggingPresetSearchAction.java	(revision 13434)
@@ -31,5 +31,5 @@
     public void actionPerformed(ActionEvent e) {
 
-        if (MainApplication.getLayerManager().getEditLayer() == null)
+        if (MainApplication.getLayerManager().getActiveDataSet() == null)
             return;
 
Index: trunk/src/org/openstreetmap/josm/actions/UnGlueAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/UnGlueAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/UnGlueAction.java	(revision 13434)
@@ -654,5 +654,5 @@
     @Override
     protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
-        setEnabled(selection != null && !selection.isEmpty());
+        updateEnabledStateOnModifiableSelection(selection);
     }
 
Index: trunk/src/org/openstreetmap/josm/actions/UnJoinNodeWayAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/UnJoinNodeWayAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/UnJoinNodeWayAction.java	(revision 13434)
@@ -177,5 +177,5 @@
     @Override
     protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
-        setEnabled(selection != null && !selection.isEmpty());
+        updateEnabledStateOnModifiableSelection(selection);
     }
 }
Index: trunk/src/org/openstreetmap/josm/actions/UnselectAllAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/UnselectAllAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/UnselectAllAction.java	(revision 13434)
@@ -30,5 +30,5 @@
         if (!isEnabled())
             return;
-        getLayerManager().getEditDataSet().setSelected();
+        getLayerManager().getActiveDataSet().setSelected();
     }
 
@@ -38,5 +38,5 @@
     @Override
     protected void updateEnabledState() {
-        setEnabled(getLayerManager().getEditLayer() != null);
+        setEnabled(getLayerManager().getActiveDataSet() != null);
     }
 }
Index: trunk/src/org/openstreetmap/josm/actions/UploadSelectionAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/UploadSelectionAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/UploadSelectionAction.java	(revision 13434)
@@ -63,5 +63,5 @@
     @Override
     protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
-        setEnabled(selection != null && !selection.isEmpty());
+        updateEnabledStateOnModifiableSelection(selection);
     }
 
Index: trunk/src/org/openstreetmap/josm/actions/ValidateAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/ValidateAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/ValidateAction.java	(revision 13434)
@@ -76,7 +76,7 @@
         Collection<OsmPrimitive> selection;
         if (getSelectedItems) {
-            selection = getLayerManager().getEditDataSet().getAllSelected();
+            selection = getLayerManager().getActiveDataSet().getAllSelected();
             if (selection.isEmpty()) {
-                selection = getLayerManager().getEditDataSet().allNonDeletedPrimitives();
+                selection = getLayerManager().getActiveDataSet().allNonDeletedPrimitives();
                 lastSelection = null;
             } else {
@@ -87,5 +87,5 @@
         } else {
             selection = Optional.ofNullable(lastSelection).orElseGet(
-                    () -> getLayerManager().getEditDataSet().allNonDeletedPrimitives());
+                    () -> getLayerManager().getActiveDataSet().allNonDeletedPrimitives());
         }
 
@@ -95,5 +95,5 @@
     @Override
     public void updateEnabledState() {
-        setEnabled(getLayerManager().getEditLayer() != null);
+        setEnabled(getLayerManager().getActiveDataSet() != null);
     }
 
@@ -105,7 +105,5 @@
 
     /**
-     * Asynchronous task for running a collection of tests against a collection
-     * of primitives
-     *
+     * Asynchronous task for running a collection of tests against a collection of primitives
      */
     static class ValidationTask extends PleaseWaitRunnable {
@@ -117,5 +115,5 @@
 
         /**
-         *
+         * Constructs a new {@code ValidationTask}
          * @param tests  the tests to run
          * @param validatedPrimitives the collection of primitives to validate.
Index: trunk/src/org/openstreetmap/josm/actions/WireframeToggleAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/WireframeToggleAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/WireframeToggleAction.java	(revision 13434)
@@ -38,5 +38,5 @@
     @Override
     protected void updateEnabledState() {
-        setEnabled(getLayerManager().getEditLayer() != null);
+        setEnabled(getLayerManager().getActiveDataSet() != null);
     }
 
Index: trunk/src/org/openstreetmap/josm/actions/ZoomToAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/ZoomToAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/ZoomToAction.java	(revision 13434)
@@ -105,5 +105,5 @@
 
     protected final void updateEnabledState() {
-        if (Main.main == null || MainApplication.getLayerManager().getEditLayer() != this.table.getLayer()) {
+        if (Main.main == null || MainApplication.getLayerManager().getActiveDataLayer() != this.table.getLayer()) {
             setEnabled(false);
             putValue(SHORT_DESCRIPTION, descriptionInactiveLayer);
Index: trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTask.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTask.java	(revision 13434)
@@ -16,4 +16,5 @@
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+import java.util.stream.Stream;
 
 import org.openstreetmap.josm.data.Bounds;
@@ -227,10 +228,35 @@
         }
 
+        /**
+         * Returns the number of modifiable data layers
+         * @return number of modifiable data layers
+         * @deprecated Use {@link #getNumModifiableDataLayers}
+         */
+        @Deprecated
         protected int getNumDataLayers() {
-            return MainApplication.getLayerManager().getLayersOfType(OsmDataLayer.class).size();
-        }
-
-        protected OsmDataLayer getFirstDataLayer() {
-            return Utils.find(MainApplication.getLayerManager().getLayers(), OsmDataLayer.class);
+            return (int) getNumModifiableDataLayers();
+        }
+
+        private static Stream<OsmDataLayer> getModifiableDataLayers() {
+            return MainApplication.getLayerManager().getLayersOfType(OsmDataLayer.class)
+                    .stream().filter(l -> !l.isReadOnly());
+        }
+
+        /**
+         * Returns the number of modifiable data layers
+         * @return number of modifiable data layers
+         * @since 13434
+         */
+        protected long getNumModifiableDataLayers() {
+            return getModifiableDataLayers().count();
+        }
+
+        /**
+         * Returns the first modifiable data layer
+         * @return the first modifiable data layer
+         * @since 13434
+         */
+        protected OsmDataLayer getFirstModifiableDataLayer() {
+            return getModifiableDataLayers().findFirst().orElse(null);
         }
 
@@ -257,5 +283,5 @@
 
         protected OsmDataLayer addNewLayerIfRequired(String newLayerName) {
-            int numDataLayers = getNumDataLayers();
+            long numDataLayers = getNumModifiableDataLayers();
             if (newLayer || numDataLayers == 0 || (numDataLayers > 1 && getEditLayer() == null)) {
                 // the user explicitly wants a new layer, we don't have any layer at all
@@ -272,5 +298,5 @@
             OsmDataLayer layer = addNewLayerIfRequired(newLayerName);
             if (layer == null) {
-                layer = Optional.ofNullable(getEditLayer()).orElseGet(this::getFirstDataLayer);
+                layer = Optional.ofNullable(getEditLayer()).orElseGet(this::getFirstModifiableDataLayer);
                 Collection<OsmPrimitive> primitivesToUpdate = searchPrimitivesToUpdate(bounds, layer.data);
                 layer.mergeFrom(dataSet);
Index: trunk/src/org/openstreetmap/josm/actions/mapmode/AddNoteAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/mapmode/AddNoteAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/mapmode/AddNoteAction.java	(revision 13434)
@@ -17,4 +17,6 @@
 import org.openstreetmap.josm.gui.NoteInputDialog;
 import org.openstreetmap.josm.gui.Notification;
+import org.openstreetmap.josm.gui.layer.Layer;
+import org.openstreetmap.josm.gui.layer.NoteLayer;
 import org.openstreetmap.josm.gui.util.KeyPressReleaseListener;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
@@ -100,3 +102,8 @@
         // Do nothing
     }
+
+    @Override
+    public boolean layerIsSupported(Layer l) {
+        return l instanceof NoteLayer;
+    }
 }
Index: trunk/src/org/openstreetmap/josm/actions/mapmode/DeleteAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/mapmode/DeleteAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/mapmode/DeleteAction.java	(revision 13434)
@@ -320,5 +320,5 @@
     @Override
     public boolean layerIsSupported(Layer l) {
-        return l instanceof OsmDataLayer;
+        return isEditableDataLayer(l);
     }
 
Index: trunk/src/org/openstreetmap/josm/actions/mapmode/DrawAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/mapmode/DrawAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/mapmode/DrawAction.java	(revision 13434)
@@ -1373,5 +1373,5 @@
     @Override
     public boolean layerIsSupported(Layer l) {
-        return l instanceof OsmDataLayer;
+        return isEditableDataLayer(l);
     }
 
Index: trunk/src/org/openstreetmap/josm/actions/mapmode/DrawSnapHelper.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/mapmode/DrawSnapHelper.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/mapmode/DrawSnapHelper.java	(revision 13434)
@@ -448,5 +448,5 @@
         projectionSource = null;
         if (DrawAction.SNAP_TO_PROJECTIONS.get()) {
-            DataSet ds = drawAction.getLayerManager().getEditDataSet();
+            DataSet ds = drawAction.getLayerManager().getActiveDataSet();
             Collection<Way> selectedWays = ds.getSelectedWays();
             if (selectedWays.size() == 1) {
Index: trunk/src/org/openstreetmap/josm/actions/mapmode/ExtrudeAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/mapmode/ExtrudeAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/mapmode/ExtrudeAction.java	(revision 13434)
@@ -54,5 +54,4 @@
 import org.openstreetmap.josm.gui.layer.Layer;
 import org.openstreetmap.josm.gui.layer.MapViewPaintable;
-import org.openstreetmap.josm.gui.layer.OsmDataLayer;
 import org.openstreetmap.josm.gui.util.GuiHelper;
 import org.openstreetmap.josm.gui.util.KeyPressReleaseListener;
@@ -292,5 +291,5 @@
     @Override
     public boolean layerIsSupported(Layer l) {
-        return l instanceof OsmDataLayer;
+        return isEditableDataLayer(l);
     }
 
Index: trunk/src/org/openstreetmap/josm/actions/mapmode/ImproveWayAccuracyAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/mapmode/ImproveWayAccuracyAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/mapmode/ImproveWayAccuracyAction.java	(revision 13434)
@@ -47,5 +47,4 @@
 import org.openstreetmap.josm.gui.layer.AbstractMapViewPaintable;
 import org.openstreetmap.josm.gui.layer.Layer;
-import org.openstreetmap.josm.gui.layer.OsmDataLayer;
 import org.openstreetmap.josm.gui.util.ModifierExListener;
 import org.openstreetmap.josm.tools.ImageProvider;
@@ -210,5 +209,5 @@
     @Override
     public boolean layerIsSupported(Layer l) {
-        return l instanceof OsmDataLayer;
+        return isEditableDataLayer(l);
     }
 
Index: trunk/src/org/openstreetmap/josm/actions/mapmode/MapMode.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/mapmode/MapMode.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/mapmode/MapMode.java	(revision 13434)
@@ -16,4 +16,5 @@
 import org.openstreetmap.josm.gui.MapFrame;
 import org.openstreetmap.josm.gui.layer.Layer;
+import org.openstreetmap.josm.gui.layer.OsmDataLayer;
 import org.openstreetmap.josm.spi.preferences.Config;
 import org.openstreetmap.josm.spi.preferences.PreferenceChangeEvent;
@@ -240,3 +241,14 @@
         return Collections.emptySet();
     }
+
+    /**
+     * Determines if the given layer is a data layer that can be modified.
+     * Useful for {@link #layerIsSupported(Layer)} implementations.
+     * @param l layer
+     * @return {@code true} if the given layer is a data layer that can be modified
+     * @since 13434
+     */
+    protected boolean isEditableDataLayer(Layer l) {
+        return l instanceof OsmDataLayer && !((OsmDataLayer) l).isReadOnly();
+    }
 }
Index: trunk/src/org/openstreetmap/josm/actions/mapmode/ParallelWayAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/mapmode/ParallelWayAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/mapmode/ParallelWayAction.java	(revision 13434)
@@ -35,7 +35,7 @@
 import org.openstreetmap.josm.data.preferences.BooleanProperty;
 import org.openstreetmap.josm.data.preferences.CachingProperty;
-import org.openstreetmap.josm.data.preferences.NamedColorProperty;
 import org.openstreetmap.josm.data.preferences.DoubleProperty;
 import org.openstreetmap.josm.data.preferences.IntegerProperty;
+import org.openstreetmap.josm.data.preferences.NamedColorProperty;
 import org.openstreetmap.josm.data.preferences.StrokeProperty;
 import org.openstreetmap.josm.gui.MainApplication;
@@ -46,5 +46,4 @@
 import org.openstreetmap.josm.gui.layer.AbstractMapViewPaintable;
 import org.openstreetmap.josm.gui.layer.Layer;
-import org.openstreetmap.josm.gui.layer.OsmDataLayer;
 import org.openstreetmap.josm.gui.util.ModifierExListener;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
@@ -212,6 +211,6 @@
 
     @Override
-    public boolean layerIsSupported(Layer layer) {
-        return layer instanceof OsmDataLayer;
+    public boolean layerIsSupported(Layer l) {
+        return isEditableDataLayer(l);
     }
 
Index: trunk/src/org/openstreetmap/josm/actions/mapmode/SelectAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/mapmode/SelectAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/mapmode/SelectAction.java	(revision 13434)
@@ -92,5 +92,5 @@
     enum SelectActionCursor {
 
-        rect(NORMAL, /* ICON(cursor/modifier/)*/ "selection"), 
+        rect(NORMAL, /* ICON(cursor/modifier/)*/ "selection"),
         rect_add(NORMAL, /* ICON(cursor/modifier/)*/ "select_add"),
         rect_rm(NORMAL, /* ICON(cursor/modifier/)*/ "select_remove"),
@@ -102,8 +102,8 @@
         node_rm(NORMAL, /* ICON(cursor/modifier/)*/ "select_node_remove"),
         virtual_node(NORMAL, /* ICON(cursor/modifier/)*/ "addnode"),
-        scale(/* ICON(cursor/)*/ "scale", null), 
+        scale(/* ICON(cursor/)*/ "scale", null),
         rotate(/* ICON(cursor/)*/ "rotate", null),
         merge(/* ICON(cursor/)*/ "crosshair", null),
-        lasso(NORMAL, /* ICON(cursor/modifier/)*/ "rope"), 
+        lasso(NORMAL, /* ICON(cursor/modifier/)*/ "rope"),
         merge_to_node(/* ICON(cursor/)*/ "crosshair", /* ICON(cursor/modifier/)*/"joinnode"),
         move(Cursor.MOVE_CURSOR);
@@ -265,6 +265,7 @@
 
         virtualManager.clear();
-        if (mode == Mode.MOVE && !dragInProgress() && virtualManager.activateVirtualNodeNearPoint(e.getPoint())) {
-            DataSet ds = getLayerManager().getEditDataSet();
+        if ((mode == Mode.MOVE || mode == Mode.SELECT)
+                && !dragInProgress() && virtualManager.activateVirtualNodeNearPoint(e.getPoint())) {
+            DataSet ds = getLayerManager().getActiveDataSet();
             if (ds != null && drawTargetHighlight) {
                 ds.setHighlightedVirtualNodes(virtualManager.virtualWays);
@@ -278,5 +279,5 @@
 
         // return early if there can't be any highlights
-        if (!drawTargetHighlight || mode != Mode.MOVE || !c.isPresent())
+        if (!drawTargetHighlight || (mode != Mode.MOVE && mode != Mode.SELECT) || !c.isPresent())
             return repaintIfRequired(newHighlight);
 
@@ -354,5 +355,5 @@
     private boolean removeHighlighting() {
         boolean needsRepaint = false;
-        DataSet ds = getLayerManager().getEditDataSet();
+        DataSet ds = getLayerManager().getActiveDataSet();
         if (ds != null && !ds.getHighlightedVirtualNodes().isEmpty()) {
             needsRepaint = true;
@@ -583,5 +584,5 @@
 
             // Select Draw Tool if no selection has been made
-            if (!cancelDrawMode && getLayerManager().getEditDataSet().selectionEmpty()) {
+            if (!cancelDrawMode && getLayerManager().getActiveDataSet().selectionEmpty()) {
                 map.selectDrawTool(true);
                 updateStatusLine();
@@ -662,13 +663,14 @@
      */
     private void determineMapMode(boolean hasSelectionNearby) {
-        if (shift && ctrl) {
-            mode = Mode.ROTATE;
-        } else if (alt && ctrl) {
-            mode = Mode.SCALE;
-        } else if (hasSelectionNearby || dragInProgress()) {
-            mode = Mode.MOVE;
-        } else {
-            mode = Mode.SELECT;
-        }
+        if (getLayerManager().getEditDataSet() != null) {
+            if (shift && ctrl) {
+                mode = Mode.ROTATE;
+            } else if (alt && ctrl) {
+                mode = Mode.SCALE;
+            } else if (hasSelectionNearby || dragInProgress()) {
+                mode = Mode.MOVE;
+            }
+        }
+        mode = Mode.SELECT;
     }
 
@@ -956,5 +958,5 @@
 
     private void selectPrims(Collection<OsmPrimitive> prims, boolean released, boolean area) {
-        DataSet ds = getLayerManager().getEditDataSet();
+        DataSet ds = getLayerManager().getActiveDataSet();
 
         // not allowed together: do not change dataset selection, return early
@@ -1120,5 +1122,5 @@
             // updateKeyModifiers() already called before!
 
-            DataSet ds = getLayerManager().getEditDataSet();
+            DataSet ds = getLayerManager().getActiveDataSet();
             OsmPrimitive first = cycleList.iterator().next(), foundInDS = null;
             OsmPrimitive nxt = first;
Index: trunk/src/org/openstreetmap/josm/actions/relation/AddSelectionToRelations.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/relation/AddSelectionToRelations.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/relation/AddSelectionToRelations.java	(revision 13434)
@@ -14,4 +14,5 @@
 import org.openstreetmap.josm.command.SequenceCommand;
 import org.openstreetmap.josm.data.SelectionChangedListener;
+import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.Relation;
@@ -39,5 +40,5 @@
         Collection<Command> cmds = new LinkedList<>();
         for (Relation orig : relations) {
-            Command c = GenericRelationEditor.addPrimitivesToRelation(orig, MainApplication.getLayerManager().getEditDataSet().getSelected());
+            Command c = GenericRelationEditor.addPrimitivesToRelation(orig, MainApplication.getLayerManager().getActiveDataSet().getSelected());
             if (c != null) {
                 cmds.add(c);
@@ -57,11 +58,18 @@
     @Override
     public void updateEnabledState() {
-        putValue(NAME, trn("Add selection to {0} relation", "Add selection to {0} relations",
-                relations.size(), relations.size()));
+        int size = relations.size();
+        putValue(NAME, trn("Add selection to {0} relation", "Add selection to {0} relations", size, size));
+        DataSet ds = MainApplication.getLayerManager().getActiveDataSet();
+        if (ds != null) {
+            selectionChanged(ds.getSelected());
+        } else {
+            setEnabled(false);
+        }
     }
 
     @Override
     public void selectionChanged(final Collection<? extends OsmPrimitive> newSelection) {
-        GuiHelper.runInEDT(() -> setEnabled(newSelection != null && !newSelection.isEmpty()));
+        GuiHelper.runInEDT(() -> setEnabled(newSelection != null && !newSelection.isEmpty() && !relations.isEmpty()
+                && relations.stream().map(Relation::getDataSet).noneMatch(DataSet::isReadOnly)));
     }
 }
Index: trunk/src/org/openstreetmap/josm/actions/relation/DeleteRelationsAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/relation/DeleteRelationsAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/relation/DeleteRelationsAction.java	(revision 13434)
@@ -8,4 +8,5 @@
 
 import org.openstreetmap.josm.actions.mapmode.DeleteAction;
+import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.gui.MainApplication;
@@ -47,3 +48,8 @@
         deleteRelation(relations);
     }
+
+    @Override
+    protected void updateEnabledState() {
+        setEnabled(!relations.isEmpty() && relations.stream().map(Relation::getDataSet).noneMatch(DataSet::isReadOnly));
+    }
 }
Index: trunk/src/org/openstreetmap/josm/actions/relation/DuplicateRelationAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/relation/DuplicateRelationAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/relation/DuplicateRelationAction.java	(revision 13434)
@@ -52,5 +52,5 @@
     protected void updateEnabledState() {
         // only one selected relation can be edited
-        setEnabled(relations.size() == 1);
+        setEnabled(relations.size() == 1 && !relations.iterator().next().getDataSet().isReadOnly());
     }
 }
Index: trunk/src/org/openstreetmap/josm/actions/relation/EditRelationAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/relation/EditRelationAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/relation/EditRelationAction.java	(revision 13434)
@@ -13,4 +13,5 @@
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.Relation;
@@ -88,8 +89,10 @@
     protected void updateEnabledState() {
         boolean enabled = false;
-        for (Relation r : relations) {
-            if (!r.isDeleted()) {
-                enabled = true;
-                break;
+        if (relations.stream().map(r -> r.getDataSet()).noneMatch(DataSet::isReadOnly)) {
+            for (Relation r : relations) {
+                if (!r.isDeleted()) {
+                    enabled = true;
+                    break;
+                }
             }
         }
Index: trunk/src/org/openstreetmap/josm/actions/relation/SelectMembersAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/relation/SelectMembersAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/relation/SelectMembersAction.java	(revision 13434)
@@ -43,7 +43,7 @@
         }
         if (add) {
-            MainApplication.getLayerManager().getEditLayer().data.addSelected(members);
+            MainApplication.getLayerManager().getActiveDataSet().addSelected(members);
         } else {
-            MainApplication.getLayerManager().getEditLayer().data.setSelected(members);
+            MainApplication.getLayerManager().getActiveDataSet().setSelected(members);
         }
     }
Index: trunk/src/org/openstreetmap/josm/actions/relation/SelectRelationAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/relation/SelectRelationAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/relation/SelectRelationAction.java	(revision 13434)
@@ -6,6 +6,6 @@
 import java.awt.event.ActionEvent;
 
+import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.gui.MainApplication;
-import org.openstreetmap.josm.gui.layer.OsmDataLayer;
 import org.openstreetmap.josm.tools.ImageProvider;
 
@@ -34,10 +34,10 @@
     public void actionPerformed(ActionEvent e) {
         if (!isEnabled() || relations.isEmpty()) return;
-        OsmDataLayer editLayer = MainApplication.getLayerManager().getEditLayer();
-        if (editLayer == null || editLayer.data == null) return;
+        DataSet ds = MainApplication.getLayerManager().getActiveDataSet();
+        if (ds == null) return;
         if (add) {
-            editLayer.data.addSelected(relations);
+            ds.addSelected(relations);
         } else {
-            editLayer.data.setSelected(relations);
+            ds.setSelected(relations);
         }
     }
Index: trunk/src/org/openstreetmap/josm/actions/search/SearchAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/search/SearchAction.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/actions/search/SearchAction.java	(revision 13434)
@@ -761,5 +761,5 @@
 
         static SearchTask newSearchTask(SearchSetting setting, SearchReceiver resultReceiver) {
-            final DataSet ds = MainApplication.getLayerManager().getEditDataSet();
+            final DataSet ds = MainApplication.getLayerManager().getActiveDataSet();
             return newSearchTask(setting, ds, resultReceiver);
         }
@@ -879,9 +879,8 @@
     /**
      * Refreshes the enabled state
-     *
      */
     @Override
     protected void updateEnabledState() {
-        setEnabled(getLayerManager().getEditLayer() != null);
+        setEnabled(getLayerManager().getActiveDataSet() != null);
     }
 
Index: trunk/src/org/openstreetmap/josm/command/conflict/ConflictResolveCommand.java
===================================================================
--- trunk/src/org/openstreetmap/josm/command/conflict/ConflictResolveCommand.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/command/conflict/ConflictResolveCommand.java	(revision 13434)
@@ -72,5 +72,5 @@
             }
 
-            Main.main.setEditDataSet(ds);
+            Main.main.setActiveDataSet(ds);
         }
         reconstituteConflicts();
Index: trunk/src/org/openstreetmap/josm/command/conflict/RelationMemberConflictResolverCommand.java
===================================================================
--- trunk/src/org/openstreetmap/josm/command/conflict/RelationMemberConflictResolverCommand.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/command/conflict/RelationMemberConflictResolverCommand.java	(revision 13434)
@@ -72,14 +72,14 @@
     @Override
     public void undoCommand() {
-        DataSet editDs = getAffectedDataSet();
-        if (!Main.main.containsDataSet(editDs)) {
+        DataSet ds = getAffectedDataSet();
+        if (!Main.main.containsDataSet(ds)) {
             Logging.warn(tr("Cannot undo command ''{0}'' because layer ''{1}'' is not present any more",
                     this.toString(),
-                    editDs.getName()
+                    ds.getName()
             ));
             return;
         }
 
-        Main.main.setEditDataSet(editDs);
+        Main.main.setActiveDataSet(ds);
 
         // restore the former state
@@ -89,6 +89,6 @@
         // restore a conflict if necessary
         //
-        if (!editDs.getConflicts().hasConflictForMy(conflict.getMy())) {
-            editDs.getConflicts().add(conflict);
+        if (!ds.getConflicts().hasConflictForMy(conflict.getMy())) {
+            ds.getConflicts().add(conflict);
         }
     }
Index: trunk/src/org/openstreetmap/josm/data/osm/DataSet.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/DataSet.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/data/osm/DataSet.java	(revision 13434)
@@ -17,4 +17,5 @@
 import java.util.Set;
 import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReadWriteLock;
@@ -103,5 +104,5 @@
  * @author imi
  */
-public final class DataSet extends QuadBucketPrimitiveStore implements Data, ProjectionChangeListener {
+public final class DataSet extends QuadBucketPrimitiveStore implements Data, ProjectionChangeListener, ReadOnly {
 
     /**
@@ -143,4 +144,20 @@
             return xmlFlag;
         }
+
+        /**
+         * Returns the {@code UploadPolicy} for the given <code>upload='...'</code> XML-attribute
+         * @param xmlFlag <code>upload='...'</code> XML-attribute to convert
+         * @return {@code UploadPolicy} value
+         * @throws IllegalArgumentException for invalid values
+         * @since 13434
+         */
+        public static UploadPolicy of(String xmlFlag) {
+            for (UploadPolicy policy : values()) {
+                if (policy.getXmlFlag().equalsIgnoreCase(xmlFlag)) {
+                    return policy;
+                }
+            }
+            throw new IllegalArgumentException(xmlFlag);
+        }
     }
 
@@ -171,4 +188,6 @@
     private String name;
     private UploadPolicy uploadPolicy;
+    /** Flag used to know if the dataset should not be editable */
+    private final AtomicBoolean isReadOnly = new AtomicBoolean(false);
 
     private final ReadWriteLock lock = new ReentrantReadWriteLock();
@@ -259,4 +278,5 @@
             version = copyFrom.version;
             uploadPolicy = copyFrom.uploadPolicy;
+            isReadOnly.set(copyFrom.isReadOnly.get());
         } finally {
             copyFrom.getReadLock().unlock();
@@ -353,6 +373,8 @@
      *
      * @param version the API version, i.e. "0.6"
+     * @throws IllegalStateException if the dataset is read-only
      */
     public void setVersion(String version) {
+        checkModifiable();
         this.version = version;
     }
@@ -533,8 +555,10 @@
      *
      * @param primitive the primitive.
+     * @throws IllegalStateException if the dataset is read-only
      */
     @Override
     public void addPrimitive(OsmPrimitive primitive) {
         Objects.requireNonNull(primitive, "primitive");
+        checkModifiable();
         beginUpdate();
         try {
@@ -561,6 +585,8 @@
      *
      * @param primitiveId the id of the primitive
+     * @throws IllegalStateException if the dataset is read-only
      */
     public void removePrimitive(PrimitiveId primitiveId) {
+        checkModifiable();
         beginUpdate();
         try {
@@ -587,4 +613,5 @@
     @Override
     protected void removePrimitive(OsmPrimitive primitive) {
+        checkModifiable();
         beginUpdate();
         try {
@@ -998,6 +1025,8 @@
      * @param node the node
      * @return The set of ways that have been modified
+     * @throws IllegalStateException if the dataset is read-only
      */
     public Set<Way> unlinkNodeFromWays(Node node) {
+        checkModifiable();
         Set<Way> result = new HashSet<>();
         beginUpdate();
@@ -1025,6 +1054,8 @@
      * @param primitive the primitive
      * @return The set of relations that have been modified
+     * @throws IllegalStateException if the dataset is read-only
      */
     public Set<Relation> unlinkPrimitiveFromRelations(OsmPrimitive primitive) {
+        checkModifiable();
         Set<Relation> result = new HashSet<>();
         beginUpdate();
@@ -1059,6 +1090,8 @@
      * @param referencedPrimitive the referenced primitive
      * @return The set of primitives that have been modified
+     * @throws IllegalStateException if the dataset is read-only
      */
     public Set<OsmPrimitive> unlinkReferencesToPrimitive(OsmPrimitive referencedPrimitive) {
+        checkModifiable();
         Set<OsmPrimitive> result = new HashSet<>();
         beginUpdate();
@@ -1131,4 +1164,5 @@
      * }
      * </pre>
+     * @see #endUpdate()
      */
     public void beginUpdate() {
@@ -1138,4 +1172,15 @@
 
     /**
+     * Must be called after a previous call to {@link #beginUpdate()} to fire change events.
+     * <br>
+     * Typical usecase should look like this:
+     * <pre>
+     * ds.beginUpdate();
+     * try {
+     *   ...
+     * } finally {
+     *   ds.endUpdate();
+     * }
+     * </pre>
      * @see DataSet#beginUpdate()
      */
@@ -1273,7 +1318,9 @@
      * Removes all primitives from the dataset and resets the currently selected primitives
      * to the empty collection. Also notifies selection change listeners if necessary.
+     * @throws IllegalStateException if the dataset is read-only
      */
     @Override
     public void clear() {
+        checkModifiable();
         beginUpdate();
         try {
@@ -1292,7 +1339,8 @@
      * Marks all "invisible" objects as deleted. These objects should be always marked as
      * deleted when downloaded from the server. They can be undeleted later if necessary.
-     *
+     * @throws IllegalStateException if the dataset is read-only
      */
     public void deleteInvisible() {
+        checkModifiable();
         for (OsmPrimitive primitive:allPrimitives) {
             if (!primitive.isVisible()) {
@@ -1314,7 +1362,9 @@
      * @param from The source DataSet
      * @param progressMonitor The progress monitor
+     * @throws IllegalStateException if the dataset is read-only
      */
     public synchronized void mergeFrom(DataSet from, ProgressMonitor progressMonitor) {
         if (from != null) {
+            checkModifiable();
             new DataSetMerger(this, from).merge(progressMonitor);
             synchronized (from) {
@@ -1402,3 +1452,32 @@
         mappaintCacheIdx++;
     }
+
+    @Override
+    public void setReadOnly() {
+        if (!isReadOnly.compareAndSet(false, true)) {
+            Logging.warn("Trying to set readOnly flag on a readOnly dataset ", getName());
+        }
+    }
+
+    @Override
+    public void unsetReadOnly() {
+        if (!isReadOnly.compareAndSet(true, false)) {
+            Logging.warn("Trying to unset readOnly flag on a non-readOnly dataset ", getName());
+        }
+    }
+
+    @Override
+    public boolean isReadOnly() {
+        return isReadOnly.get();
+    }
+
+    /**
+     * Checks the dataset is modifiable (not read-only).
+     * @throws IllegalStateException if the dataset is read-only
+     */
+    private void checkModifiable() {
+        if (isReadOnly()) {
+            throw new IllegalStateException("DataSet is read-only");
+        }
+    }
 }
Index: trunk/src/org/openstreetmap/josm/data/osm/FilterModel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/FilterModel.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/data/osm/FilterModel.java	(revision 13434)
@@ -98,5 +98,5 @@
      */
     public void executeFilters() {
-        DataSet ds = Main.main.getEditDataSet();
+        DataSet ds = Main.main.getActiveDataSet();
         changed = false;
         if (ds == null) {
Index: trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(revision 13434)
@@ -275,4 +275,12 @@
     }
 
+    /**
+     * Throws exception if primitive is in a read-only dataset
+     */
+    protected final void checkDatasetNotReadOnly() {
+        if (dataSet != null && dataSet.isReadOnly())
+            throw new DataIntegrityProblemException("Primitive cannot be modified in read-only dataset: " + toString());
+    }
+
     protected boolean writeLock() {
         if (dataSet != null) {
@@ -305,4 +313,5 @@
     @Override
     public void setOsmId(long id, int version) {
+        checkDatasetNotReadOnly();
         boolean locked = writeLock();
         try {
@@ -343,4 +352,5 @@
     @Override
     public void setUser(User user) {
+        checkDatasetNotReadOnly();
         boolean locked = writeLock();
         try {
@@ -353,4 +363,5 @@
     @Override
     public void setChangesetId(int changesetId) {
+        checkDatasetNotReadOnly();
         boolean locked = writeLock();
         try {
@@ -367,4 +378,5 @@
     @Override
     public void setTimestamp(Date timestamp) {
+        checkDatasetNotReadOnly();
         boolean locked = writeLock();
         try {
@@ -534,4 +546,5 @@
     @Override
     public void setModified(boolean modified) {
+        checkDatasetNotReadOnly();
         boolean locked = writeLock();
         try {
@@ -548,4 +561,5 @@
     @Override
     public void setVisible(boolean visible) {
+        checkDatasetNotReadOnly();
         boolean locked = writeLock();
         try {
@@ -559,4 +573,5 @@
     @Override
     public void setDeleted(boolean deleted) {
+        checkDatasetNotReadOnly();
         boolean locked = writeLock();
         try {
@@ -577,4 +592,5 @@
     @Override
     protected final void setIncomplete(boolean incomplete) {
+        checkDatasetNotReadOnly();
         boolean locked = writeLock();
         try {
@@ -891,4 +907,5 @@
     @Override
     public final void setKeys(TagMap keys) {
+        checkDatasetNotReadOnly();
         boolean locked = writeLock();
         try {
@@ -901,4 +918,5 @@
     @Override
     public final void setKeys(Map<String, String> keys) {
+        checkDatasetNotReadOnly();
         boolean locked = writeLock();
         try {
@@ -911,4 +929,5 @@
     @Override
     public final void put(String key, String value) {
+        checkDatasetNotReadOnly();
         boolean locked = writeLock();
         try {
@@ -921,4 +940,5 @@
     @Override
     public final void remove(String key) {
+        checkDatasetNotReadOnly();
         boolean locked = writeLock();
         try {
@@ -931,4 +951,5 @@
     @Override
     public final void removeAll() {
+        checkDatasetNotReadOnly();
         boolean locked = writeLock();
         try {
@@ -966,4 +987,5 @@
      */
     protected void addReferrer(OsmPrimitive referrer) {
+        checkDatasetNotReadOnly();
         if (referrers == null) {
             referrers = referrer;
@@ -986,4 +1008,5 @@
      */
     protected void removeReferrer(OsmPrimitive referrer) {
+        checkDatasetNotReadOnly();
         if (referrers instanceof OsmPrimitive) {
             if (referrers == referrer) {
@@ -1148,4 +1171,5 @@
      */
     public void mergeFrom(OsmPrimitive other) {
+        checkDatasetNotReadOnly();
         boolean locked = writeLock();
         try {
@@ -1239,4 +1263,5 @@
      */
     public void load(PrimitiveData data) {
+        checkDatasetNotReadOnly();
         // Write lock is provided by subclasses
         setKeys(data.hasKeys() ? data.getKeys() : null);
Index: trunk/src/org/openstreetmap/josm/data/osm/ReadOnly.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/ReadOnly.java	(revision 13434)
+++ trunk/src/org/openstreetmap/josm/data/osm/ReadOnly.java	(revision 13434)
@@ -0,0 +1,25 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.data.osm;
+
+/**
+ * To be implemented by modifiable objects to offer a "read-only" mode.
+ * @since 13434
+ */
+public interface ReadOnly {
+
+    /**
+     * Enables the read-only mode.
+     */
+    void setReadOnly();
+
+    /**
+     * Disables the read-only mode.
+     */
+    void unsetReadOnly();
+
+    /**
+     * Determines if this is read-only (thus it cannot be modified).
+     * @return {@code true} if this is read-only
+     */
+    boolean isReadOnly();
+}
Index: trunk/src/org/openstreetmap/josm/data/osm/Relation.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/Relation.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/data/osm/Relation.java	(revision 13434)
@@ -46,4 +46,5 @@
      */
     public void setMembers(List<RelationMember> members) {
+        checkDatasetNotReadOnly();
         boolean locked = writeLock();
         try {
@@ -88,4 +89,5 @@
      */
     public void addMember(RelationMember member) {
+        checkDatasetNotReadOnly();
         boolean locked = writeLock();
         try {
@@ -105,4 +107,5 @@
      */
     public void addMember(int index, RelationMember member) {
+        checkDatasetNotReadOnly();
         boolean locked = writeLock();
         try {
@@ -127,4 +130,5 @@
      */
     public RelationMember setMember(int index, RelationMember member) {
+        checkDatasetNotReadOnly();
         boolean locked = writeLock();
         try {
@@ -150,4 +154,5 @@
      */
     public RelationMember removeMember(int index) {
+        checkDatasetNotReadOnly();
         boolean locked = writeLock();
         try {
@@ -376,4 +381,5 @@
      */
     public void removeMembersFor(Collection<? extends OsmPrimitive> primitives) {
+        checkDatasetNotReadOnly();
         if (primitives == null || primitives.isEmpty())
             return;
Index: trunk/src/org/openstreetmap/josm/data/osm/Way.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/Way.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/data/osm/Way.java	(revision 13434)
@@ -53,4 +53,5 @@
      */
     public void setNodes(List<Node> nodes) {
+        checkDatasetNotReadOnly();
         boolean locked = writeLock();
         try {
@@ -361,4 +362,5 @@
      */
     public void removeNode(Node n) {
+        checkDatasetNotReadOnly();
         if (n == null || isIncomplete()) return;
         boolean locked = writeLock();
@@ -389,4 +391,5 @@
      */
     public void removeNodes(Set<? extends Node> selection) {
+        checkDatasetNotReadOnly();
         if (selection == null || isIncomplete()) return;
         boolean locked = writeLock();
@@ -425,4 +428,5 @@
      */
     public void addNode(Node n) {
+        checkDatasetNotReadOnly();
         if (n == null) return;
 
@@ -452,4 +456,5 @@
      */
     public void addNode(int offs, Node n) {
+        checkDatasetNotReadOnly();
         if (n == null) return;
 
Index: trunk/src/org/openstreetmap/josm/data/osm/event/DatasetEventManager.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/event/DatasetEventManager.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/data/osm/event/DatasetEventManager.java	(revision 13434)
@@ -182,10 +182,10 @@
     @Override
     public void activeOrEditLayerChanged(ActiveLayerChangeEvent e) {
-        DataSet oldData = e.getPreviousEditDataSet();
+        DataSet oldData = e.getPreviousDataSet();
         if (oldData != null) {
             oldData.removeDataSetListener(myListener);
         }
 
-        DataSet newData = e.getSource().getEditDataSet();
+        DataSet newData = e.getSource().getActiveDataSet();
         if (newData != null) {
             newData.addDataSetListener(myListener);
Index: trunk/src/org/openstreetmap/josm/data/osm/event/SelectionEventManager.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/event/SelectionEventManager.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/data/osm/event/SelectionEventManager.java	(revision 13434)
@@ -184,5 +184,5 @@
     @Override
     public void activeOrEditLayerChanged(ActiveLayerChangeEvent e) {
-        DataSet oldDataSet = e.getPreviousEditDataSet();
+        DataSet oldDataSet = e.getPreviousDataSet();
         if (oldDataSet != null) {
             // Fake a selection removal
@@ -194,5 +194,5 @@
             oldDataSet.removeSelectionListener(this);
         }
-        DataSet newDataSet = e.getSource().getEditDataSet();
+        DataSet newDataSet = e.getSource().getActiveDataSet();
         if (newDataSet != null) {
             newDataSet.addSelectionListener(this);
Index: trunk/src/org/openstreetmap/josm/data/projection/Projections.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/projection/Projections.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/data/projection/Projections.java	(revision 13434)
@@ -320,5 +320,5 @@
                 cproj.update(pd.definition);
             } catch (ProjectionConfigurationException ex) {
-                throw new RuntimeException("Error loading " + code, ex);
+                throw new JosmRuntimeException("Error loading " + code, ex);
             }
             proj = cproj;
Index: trunk/src/org/openstreetmap/josm/data/validation/TestError.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/validation/TestError.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/data/validation/TestError.java	(revision 13434)
@@ -12,4 +12,5 @@
 
 import org.openstreetmap.josm.command.Command;
+import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
@@ -358,5 +359,6 @@
      */
     public boolean isFixable() {
-        return fixingCommand != null || ((tester != null) && tester.isFixable(this));
+        return (fixingCommand != null || ((tester != null) && tester.isFixable(this)))
+                && primitives.stream().map(OsmPrimitive::getDataSet).noneMatch(DataSet::isReadOnly);
     }
 
Index: trunk/src/org/openstreetmap/josm/gui/MainApplication.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/MainApplication.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/gui/MainApplication.java	(revision 13434)
@@ -527,5 +527,5 @@
             return ((DrawAction) map.mapMode).getInProgressSelection();
         } else {
-            DataSet ds = layerManager.getEditDataSet();
+            DataSet ds = layerManager.getActiveDataSet();
             if (ds == null) return null;
             return ds.getSelected();
@@ -539,5 +539,10 @@
 
     @Override
-    public void setEditDataSet(DataSet ds) {
+    public DataSet getActiveDataSet() {
+        return getLayerManager().getActiveDataSet();
+    }
+
+    @Override
+    public void setActiveDataSet(DataSet ds) {
         Optional<OsmDataLayer> layer = getLayerManager().getLayersOfType(OsmDataLayer.class).stream()
                 .filter(l -> l.data.equals(ds)).findFirst();
Index: trunk/src/org/openstreetmap/josm/gui/MapStatus.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/MapStatus.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/gui/MapStatus.java	(revision 13434)
@@ -327,5 +327,5 @@
                 boolean middleMouseDown = (ms.modifiers & MouseEvent.BUTTON2_DOWN_MASK) != 0;
 
-                ds = mv.getLayerManager().getEditDataSet();
+                ds = mv.getLayerManager().getActiveDataSet();
                 if (ds != null) {
                     // This is not perfect, if current dataset was changed during execution, the lock would be useless
@@ -512,5 +512,5 @@
          */
         private void popupCycleSelection(Collection<OsmPrimitive> osms, int mods) {
-            DataSet ds = MainApplication.getLayerManager().getEditDataSet();
+            DataSet ds = MainApplication.getLayerManager().getActiveDataSet();
             // Find some items that are required for cycling through
             OsmPrimitive firstItem = null;
@@ -603,5 +603,5 @@
          */
         private void popupSetLabelColors(JLabel lbl, OsmPrimitive osm) {
-            DataSet ds = MainApplication.getLayerManager().getEditDataSet();
+            DataSet ds = MainApplication.getLayerManager().getActiveDataSet();
             if (ds.isSelected(osm)) {
                 lbl.setBackground(SystemColor.textHighlight);
@@ -676,5 +676,5 @@
                 @Override
                 public void mouseClicked(MouseEvent e) {
-                    DataSet ds = MainApplication.getLayerManager().getEditDataSet();
+                    DataSet ds = MainApplication.getLayerManager().getActiveDataSet();
                     // Let the user toggle the selection
                     ds.toggleSelected(osm);
Index: trunk/src/org/openstreetmap/josm/gui/MapView.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/MapView.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/gui/MapView.java	(revision 13434)
@@ -381,10 +381,10 @@
 
     /**
-     * Replies true if the active data layer (edit layer) is visible.
+     * Replies true if the active data layer is visible.
      *
-     * @return true if the active data layer (edit layer) is visible, false otherwise
+     * @return true if the active data layer is visible, false otherwise
      */
     public boolean isActiveLayerVisible() {
-        OsmDataLayer e = layerManager.getEditLayer();
+        OsmDataLayer e = layerManager.getActiveDataLayer();
         return e != null && e.isVisible();
     }
Index: trunk/src/org/openstreetmap/josm/gui/NavigatableComponent.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/NavigatableComponent.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/gui/NavigatableComponent.java	(revision 13434)
@@ -939,5 +939,5 @@
     private Map<Double, List<Node>> getNearestNodesImpl(Point p, Predicate<OsmPrimitive> predicate) {
         Map<Double, List<Node>> nearestMap = new TreeMap<>();
-        DataSet ds = MainApplication.getLayerManager().getEditDataSet();
+        DataSet ds = MainApplication.getLayerManager().getActiveDataSet();
 
         if (ds != null) {
@@ -1148,5 +1148,5 @@
     private Map<Double, List<WaySegment>> getNearestWaySegmentsImpl(Point p, Predicate<OsmPrimitive> predicate) {
         Map<Double, List<WaySegment>> nearestMap = new TreeMap<>();
-        DataSet ds = MainApplication.getLayerManager().getEditDataSet();
+        DataSet ds = MainApplication.getLayerManager().getActiveDataSet();
 
         if (ds != null) {
@@ -1509,5 +1509,5 @@
     public final OsmPrimitive getNearestNodeOrWay(Point p, Predicate<OsmPrimitive> predicate, boolean useSelected) {
         Collection<OsmPrimitive> sel;
-        DataSet ds = MainApplication.getLayerManager().getEditDataSet();
+        DataSet ds = MainApplication.getLayerManager().getActiveDataSet();
         if (useSelected && ds != null) {
             sel = ds.getSelected();
Index: trunk/src/org/openstreetmap/josm/gui/SelectionManager.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/SelectionManager.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/gui/SelectionManager.java	(revision 13434)
@@ -183,5 +183,5 @@
     @Override
     public void mousePressed(MouseEvent e) {
-        if (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() > 1 && MainApplication.getLayerManager().getEditDataSet() != null) {
+        if (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() > 1 && MainApplication.getLayerManager().getActiveDataSet() != null) {
             SelectByInternalPointAction.performSelection(MainApplication.getMap().mapView.getEastNorth(e.getX(), e.getY()),
                     (e.getModifiersEx() & MouseEvent.SHIFT_DOWN_MASK) != 0,
@@ -374,5 +374,5 @@
         }
 
-        DataSet ds = MainApplication.getLayerManager().getEditDataSet();
+        DataSet ds = MainApplication.getLayerManager().getActiveDataSet();
         if (clicked) {
             Point center = new Point(selectionResult.xpoints[0], selectionResult.ypoints[0]);
Index: trunk/src/org/openstreetmap/josm/gui/autofilter/AutoFilterManager.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/autofilter/AutoFilterManager.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/gui/autofilter/AutoFilterManager.java	(revision 13434)
@@ -22,6 +22,4 @@
 
 import org.openstreetmap.josm.actions.mapmode.MapMode;
-import org.openstreetmap.josm.spi.preferences.PreferenceChangeEvent;
-import org.openstreetmap.josm.spi.preferences.PreferenceChangedListener;
 import org.openstreetmap.josm.data.osm.BBox;
 import org.openstreetmap.josm.data.osm.DataSet;
@@ -56,4 +54,6 @@
 import org.openstreetmap.josm.gui.widgets.OSDLabel;
 import org.openstreetmap.josm.spi.preferences.Config;
+import org.openstreetmap.josm.spi.preferences.PreferenceChangeEvent;
+import org.openstreetmap.josm.spi.preferences.PreferenceChangedListener;
 import org.openstreetmap.josm.tools.Logging;
 
@@ -194,5 +194,5 @@
 
     private static Set<String> getTagValues(String key) {
-        DataSet ds = MainApplication.getLayerManager().getEditDataSet();
+        DataSet ds = MainApplication.getLayerManager().getActiveDataSet();
         Set<String> values = new TreeSet<>();
         if (ds != null) {
@@ -371,7 +371,7 @@
             model.executeFilters();
             if (model.isChanged()) {
-                OsmDataLayer editLayer = MainApplication.getLayerManager().getEditLayer();
-                if (editLayer != null) {
-                    editLayer.invalidate();
+                OsmDataLayer dataLayer = MainApplication.getLayerManager().getActiveDataLayer();
+                if (dataLayer != null) {
+                    dataLayer.invalidate();
                 }
             }
@@ -422,5 +422,5 @@
     @Override
     public void layerRemoving(LayerRemoveEvent e) {
-        if (MainApplication.getLayerManager().getEditLayer() == null) {
+        if (MainApplication.getLayerManager().getActiveDataLayer() == null) {
             resetCurrentAutoFilter();
         }
Index: trunk/src/org/openstreetmap/josm/gui/bbox/SlippyMapBBoxChooser.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/bbox/SlippyMapBBoxChooser.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/gui/bbox/SlippyMapBBoxChooser.java	(revision 13434)
@@ -48,4 +48,5 @@
 import org.openstreetmap.josm.data.imagery.TileLoaderFactory;
 import org.openstreetmap.josm.data.osm.BBox;
+import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.preferences.BooleanProperty;
 import org.openstreetmap.josm.data.preferences.StringProperty;
@@ -53,5 +54,4 @@
 import org.openstreetmap.josm.gui.layer.AbstractCachedTileSourceLayer;
 import org.openstreetmap.josm.gui.layer.MainLayerManager;
-import org.openstreetmap.josm.gui.layer.OsmDataLayer;
 import org.openstreetmap.josm.gui.layer.TMSLayer;
 import org.openstreetmap.josm.spi.preferences.Config;
@@ -237,9 +237,9 @@
         Graphics2D g2d = (Graphics2D) g;
 
-        // draw shaded area for non-downloaded region of current "edit layer", but only if there *is* a current "edit layer",
+        // draw shaded area for non-downloaded region of current data set, but only if there *is* a current data set,
         // and it has defined bounds. Routine is analogous to that in OsmDataLayer's paint routine (but just different
         // enough to make sharing code impractical)
-        final OsmDataLayer editLayer = MainApplication.getLayerManager().getEditLayer();
-        if (editLayer != null && this.showDownloadAreaButtonModel.isSelected() && !editLayer.data.getDataSources().isEmpty()) {
+        final DataSet ds = MainApplication.getLayerManager().getActiveDataSet();
+        if (ds != null && this.showDownloadAreaButtonModel.isSelected() && !ds.getDataSources().isEmpty()) {
             // initialize area with current viewport
             Rectangle b = this.getBounds();
@@ -249,5 +249,5 @@
 
             // combine successively downloaded areas after converting to screen-space
-            for (Bounds bounds : editLayer.data.getDataSourceBounds()) {
+            for (Bounds bounds : ds.getDataSourceBounds()) {
                 if (bounds.isCollapsed()) {
                     continue;
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/ChangesetDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/ChangesetDialog.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/ChangesetDialog.java	(revision 13434)
@@ -53,5 +53,4 @@
 import org.openstreetmap.josm.gui.help.HelpUtil;
 import org.openstreetmap.josm.gui.io.CloseChangesetTask;
-import org.openstreetmap.josm.gui.layer.OsmDataLayer;
 import org.openstreetmap.josm.gui.util.GuiHelper;
 import org.openstreetmap.josm.gui.widgets.ListPopupMenu;
@@ -123,9 +122,9 @@
         ChangesetCache.getInstance().addChangesetCacheListener(inActiveDataLayerModel);
         MainApplication.getLayerManager().addActiveLayerChangeListener(inActiveDataLayerModel);
-        OsmDataLayer editLayer = MainApplication.getLayerManager().getEditLayer();
-        if (editLayer != null) {
-            editLayer.data.addDataSetListener(inActiveDataLayerModel);
-            inActiveDataLayerModel.initFromDataSet(editLayer.data);
-            inSelectionModel.initFromPrimitives(editLayer.data.getAllSelected());
+        DataSet ds = MainApplication.getLayerManager().getActiveDataSet();
+        if (ds != null) {
+            ds.addDataSetListener(inActiveDataLayerModel);
+            inActiveDataLayerModel.initFromDataSet(ds);
+            inSelectionModel.initFromPrimitives(ds.getAllSelected());
         }
     }
@@ -133,14 +132,12 @@
     protected void unregisterAsListener() {
         // remove the list model for the current edit layer as listener
-        //
         ChangesetCache.getInstance().removeChangesetCacheListener(inActiveDataLayerModel);
         MainApplication.getLayerManager().removeActiveLayerChangeListener(inActiveDataLayerModel);
-        OsmDataLayer editLayer = MainApplication.getLayerManager().getEditLayer();
-        if (editLayer != null) {
-            editLayer.data.removeDataSetListener(inActiveDataLayerModel);
-        }
-
-        // remove the list model for the changesets in the current selection as
-        // listener
+        DataSet ds = MainApplication.getLayerManager().getActiveDataSet();
+        if (ds != null) {
+            ds.removeDataSetListener(inActiveDataLayerModel);
+        }
+
+        // remove the list model for the changesets in the current selection as listener
         SelectionEventManager.getInstance().removeSelectionListener(inSelectionModel);
         ChangesetCache.getInstance().removeChangesetCacheListener(inSelectionModel);
@@ -235,8 +232,8 @@
 
     protected void initWithCurrentData() {
-        OsmDataLayer editLayer = MainApplication.getLayerManager().getEditLayer();
-        if (editLayer != null) {
-            inSelectionModel.initFromPrimitives(editLayer.data.getAllSelected());
-            inActiveDataLayerModel.initFromDataSet(editLayer.data);
+        DataSet ds = MainApplication.getLayerManager().getActiveDataSet();
+        if (ds != null) {
+            inSelectionModel.initFromPrimitives(ds.getAllSelected());
+            inActiveDataLayerModel.initFromDataSet(ds);
         }
     }
@@ -266,7 +263,7 @@
             if (sel.isEmpty())
                 return;
-            if (MainApplication.getLayerManager().getEditDataSet() == null)
-                return;
-            new SelectObjectsAction().selectObjectsByChangesetIds(MainApplication.getLayerManager().getEditDataSet(), sel);
+            if (MainApplication.getLayerManager().getActiveDataSet() == null)
+                return;
+            new SelectObjectsAction().selectObjectsByChangesetIds(MainApplication.getLayerManager().getActiveDataSet(), sel);
         }
 
@@ -314,5 +311,6 @@
         @Override
         public void actionPerformed(ActionEvent e) {
-            if (MainApplication.getLayerManager().getEditLayer() == null)
+            DataSet ds = MainApplication.getLayerManager().getActiveDataSet();
+            if (ds == null)
                 return;
             ChangesetListModel model = getCurrentChangesetListModel();
@@ -321,5 +319,4 @@
                 return;
 
-            DataSet ds = MainApplication.getLayerManager().getEditLayer().data;
             selectObjectsByChangesetIds(ds, sel);
         }
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/ConflictDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/ConflictDialog.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/ConflictDialog.java	(revision 13434)
@@ -160,5 +160,5 @@
     public void hideNotify() {
         MainApplication.getLayerManager().removeActiveLayerChangeListener(this);
-        removeEditLayerListeners(MainApplication.getLayerManager().getEditLayer());
+        removeDataLayerListeners(MainApplication.getLayerManager().getEditLayer());
     }
 
@@ -269,10 +269,10 @@
     @Override
     public void activeOrEditLayerChanged(ActiveLayerChangeEvent e) {
-        removeEditLayerListeners(e.getPreviousEditLayer());
-        addEditLayerListeners(e.getSource().getEditLayer());
+        removeDataLayerListeners(e.getPreviousDataLayer());
+        addDataLayerListeners(e.getSource().getActiveDataLayer());
         refreshView();
     }
 
-    private void addEditLayerListeners(OsmDataLayer newLayer) {
+    private void addDataLayerListeners(OsmDataLayer newLayer) {
         if (newLayer != null) {
             newLayer.getConflicts().addConflictListener(this);
@@ -281,5 +281,5 @@
     }
 
-    private void removeEditLayerListeners(OsmDataLayer oldLayer) {
+    private void removeDataLayerListeners(OsmDataLayer oldLayer) {
         if (oldLayer != null) {
             oldLayer.getConflicts().removeConflictListener(this);
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/InspectPrimitiveDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/InspectPrimitiveDialog.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/InspectPrimitiveDialog.java	(revision 13434)
@@ -114,5 +114,5 @@
 
     protected static String buildMapPaintText() {
-        final Collection<OsmPrimitive> sel = MainApplication.getLayerManager().getEditDataSet().getAllSelected();
+        final Collection<OsmPrimitive> sel = MainApplication.getLayerManager().getActiveDataSet().getAllSelected();
         ElemStyles elemstyles = MapPaintStyles.getStyles();
         NavigatableComponent nc = MainApplication.getMap().mapView;
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/RelationListDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/RelationListDialog.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/RelationListDialog.java	(revision 13434)
@@ -342,5 +342,5 @@
 
         protected void setCurrentRelationAsSelection() {
-            MainApplication.getLayerManager().getEditDataSet().setSelected(displaylist.getSelectedValue());
+            MainApplication.getLayerManager().getActiveDataSet().setSelected(displaylist.getSelectedValue());
         }
 
@@ -351,7 +351,7 @@
         @Override
         public void mouseClicked(MouseEvent e) {
-            if (MainApplication.getLayerManager().getEditLayer() == null) return;
-            if (isDoubleClick(e)) {
-                if (e.isControlDown()) {
+            DataSet ds = MainApplication.getLayerManager().getActiveDataSet();
+            if (ds != null && isDoubleClick(e)) {
+                if (e.isControlDown() && !ds.isReadOnly()) {
                     editCurrentRelation();
                 } else {
@@ -733,5 +733,4 @@
             return;
         // trigger a sort of the relation list because the display name may have changed
-        //
         List<Relation> sel = model.getSelectedRelations();
         model.sort();
@@ -742,5 +741,5 @@
     @Override
     public void dataChanged(DataChangedEvent event) {
-        initFromLayer(MainApplication.getLayerManager().getEditLayer());
+        initFromLayer(MainApplication.getLayerManager().getActiveDataLayer());
     }
 
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/SelectionListDialog.java	(revision 13434)
@@ -73,5 +73,4 @@
 import org.openstreetmap.josm.gui.layer.MainLayerManager.ActiveLayerChangeEvent;
 import org.openstreetmap.josm.gui.layer.MainLayerManager.ActiveLayerChangeListener;
-import org.openstreetmap.josm.gui.layer.OsmDataLayer;
 import org.openstreetmap.josm.gui.util.GuiHelper;
 import org.openstreetmap.josm.gui.util.HighlightHelper;
@@ -200,11 +199,11 @@
             if (idx < 0) return;
             if (isDoubleClick(e)) {
-                OsmDataLayer layer = MainApplication.getLayerManager().getEditLayer();
-                if (layer == null) return;
+                DataSet ds = MainApplication.getLayerManager().getActiveDataSet();
+                if (ds == null) return;
                 OsmPrimitive osm = model.getElementAt(idx);
-                Collection<OsmPrimitive> sel = layer.data.getSelected();
+                Collection<OsmPrimitive> sel = ds.getSelected();
                 if (sel.size() != 1 || !sel.iterator().next().equals(osm)) {
                     // Select primitive if it's not the whole current selection
-                    layer.data.setSelected(Collections.singleton(osm));
+                    ds.setSelected(Collections.singleton(osm));
                 } else if (osm instanceof Relation) {
                     // else open relation editor if applicable
@@ -296,5 +295,5 @@
 
         protected void updateEnabledState() {
-            setEnabled(MainApplication.getLayerManager().getEditLayer() != null);
+            setEnabled(MainApplication.getLayerManager().getActiveDataSet() != null);
         }
 
@@ -321,7 +320,7 @@
             Collection<OsmPrimitive> sel = model.getSelected();
             if (sel.isEmpty()) return;
-            OsmDataLayer editLayer = MainApplication.getLayerManager().getEditLayer();
-            if (editLayer == null) return;
-            editLayer.data.setSelected(sel);
+            DataSet ds = MainApplication.getLayerManager().getActiveDataSet();
+            if (ds == null) return;
+            ds.setSelected(sel);
             model.selectionModel.setSelectionInterval(0, sel.size()-1);
         }
@@ -830,5 +829,5 @@
         @Override
         public void actionPerformed(ActionEvent e) {
-            MainApplication.getLayerManager().getEditDataSet().setSelected(sel);
+            MainApplication.getLayerManager().getActiveDataSet().setSelected(sel);
         }
     }
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/UserListDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/UserListDialog.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/UserListDialog.java	(revision 13434)
@@ -32,4 +32,5 @@
 import org.openstreetmap.josm.actions.AbstractInfoAction;
 import org.openstreetmap.josm.data.osm.DataSelectionListener;
+import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.User;
@@ -347,5 +348,6 @@
                 users.add(data.get(index).user);
             }
-            Collection<OsmPrimitive> selected = MainApplication.getLayerManager().getEditDataSet().getAllSelected();
+            DataSet ds = MainApplication.getLayerManager().getActiveDataSet();
+            Collection<OsmPrimitive> selected = ds.getAllSelected();
             Collection<OsmPrimitive> byUser = new LinkedList<>();
             for (OsmPrimitive p : selected) {
@@ -354,5 +356,5 @@
                 }
             }
-            MainApplication.getLayerManager().getEditDataSet().setSelected(byUser);
+            ds.setSelected(byUser);
         }
 
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/ValidatorDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/ValidatorDialog.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/ValidatorDialog.java	(revision 13434)
@@ -132,5 +132,5 @@
             @Override
             public void actionPerformed(ActionEvent e) {
-                final DataSet ds = MainApplication.getLayerManager().getEditDataSet();
+                final DataSet ds = MainApplication.getLayerManager().getActiveDataSet();
                 if (ds == null) {
                     return;
@@ -181,5 +181,5 @@
     public void showNotify() {
         DataSet.addSelectionListener(this);
-        DataSet ds = MainApplication.getLayerManager().getEditDataSet();
+        DataSet ds = MainApplication.getLayerManager().getActiveDataSet();
         if (ds != null) {
             updateSelection(ds.getAllSelected());
@@ -350,5 +350,5 @@
             }
         }
-        DataSet ds = MainApplication.getLayerManager().getEditDataSet();
+        DataSet ds = MainApplication.getLayerManager().getActiveDataSet();
         if (ds != null) {
             ds.setSelected(sel);
@@ -494,5 +494,5 @@
 
             if (isDblClick) {
-                DataSet ds = MainApplication.getLayerManager().getEditDataSet();
+                DataSet ds = MainApplication.getLayerManager().getActiveDataSet();
                 if (ds != null) {
                     ds.setSelected(sel);
@@ -630,5 +630,5 @@
             try {
                 monitor.setTicksCount(testErrors.size());
-                final DataSet ds = MainApplication.getLayerManager().getEditDataSet();
+                final DataSet ds = MainApplication.getLayerManager().getActiveDataSet();
                 int i = 0;
                 SwingUtilities.invokeAndWait(ds::beginUpdate);
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/ChangesetContentPanel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/ChangesetContentPanel.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/ChangesetContentPanel.java	(revision 13434)
@@ -36,4 +36,5 @@
 import org.openstreetmap.josm.actions.downloadtasks.ChangesetContentDownloadTask;
 import org.openstreetmap.josm.data.osm.Changeset;
+import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.PrimitiveId;
@@ -49,5 +50,4 @@
 import org.openstreetmap.josm.gui.layer.MainLayerManager.ActiveLayerChangeEvent;
 import org.openstreetmap.josm.gui.layer.MainLayerManager.ActiveLayerChangeListener;
-import org.openstreetmap.josm.gui.layer.OsmDataLayer;
 import org.openstreetmap.josm.gui.util.GuiHelper;
 import org.openstreetmap.josm.gui.widgets.JMultilineLabel;
@@ -279,5 +279,5 @@
 
         @Override
-        public void actionPerformed(ActionEvent arg0) {
+        public void actionPerformed(ActionEvent e) {
             Set<HistoryOsmPrimitive> selected = model.getSelectedPrimitives();
             if (selected.isEmpty()) return;
@@ -301,5 +301,5 @@
 
         @Override
-        public void actionPerformed(ActionEvent arg0) {
+        public void actionPerformed(ActionEvent e) {
             final List<PrimitiveId> primitiveIds = model.getSelectedPrimitives().stream().map(HistoryOsmPrimitive::getPrimitiveId)
                     .collect(Collectors.toList());
@@ -323,11 +323,11 @@
                 return null;
             }
-            OsmDataLayer layer = MainApplication.getLayerManager().getEditLayer();
-            if (layer == null) {
+            DataSet ds = MainApplication.getLayerManager().getActiveDataSet();
+            if (ds == null) {
                 return null;
             }
             Set<OsmPrimitive> target = new HashSet<>();
             for (HistoryOsmPrimitive p : model.getSelectedPrimitives()) {
-                OsmPrimitive op = layer.data.getPrimitiveById(p.getPrimitiveId());
+                OsmPrimitive op = ds.getPrimitiveById(p.getPrimitiveId());
                 if (op != null) {
                     target.add(op);
@@ -338,5 +338,5 @@
 
         public final void updateEnabledState() {
-            setEnabled(MainApplication.getLayerManager().getEditLayer() != null && model.hasSelectedPrimitives());
+            setEnabled(MainApplication.getLayerManager().getActiveDataSet() != null && model.hasSelectedPrimitives());
         }
 
@@ -350,5 +350,4 @@
             updateEnabledState();
         }
-
     }
 
@@ -363,5 +362,5 @@
 
         @Override
-        public void actionPerformed(ActionEvent arg0) {
+        public void actionPerformed(ActionEvent e) {
             final Set<OsmPrimitive> target = getTarget();
             if (target == null) {
@@ -372,5 +371,5 @@
                 return;
             }
-            MainApplication.getLayerManager().getEditLayer().data.setSelected(target);
+            MainApplication.getLayerManager().getActiveDataSet().setSelected(target);
         }
     }
@@ -386,5 +385,5 @@
 
         @Override
-        public void actionPerformed(ActionEvent arg0) {
+        public void actionPerformed(ActionEvent e) {
             final Set<OsmPrimitive> target = getTarget();
             if (target == null) {
@@ -395,5 +394,5 @@
                 return;
             }
-            MainApplication.getLayerManager().getEditLayer().data.setSelected(target);
+            MainApplication.getLayerManager().getActiveDataSet().setSelected(target);
             AutoScaleAction.zoomToSelection();
         }
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/ChangesetDetailPanel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/ChangesetDetailPanel.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/ChangesetDetailPanel.java	(revision 13434)
@@ -35,4 +35,5 @@
 import org.openstreetmap.josm.data.osm.Changeset;
 import org.openstreetmap.josm.data.osm.ChangesetCache;
+import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.gui.HelpAwareOptionPane;
@@ -42,5 +43,4 @@
 import org.openstreetmap.josm.gui.layer.MainLayerManager.ActiveLayerChangeEvent;
 import org.openstreetmap.josm.gui.layer.MainLayerManager.ActiveLayerChangeListener;
-import org.openstreetmap.josm.gui.layer.OsmDataLayer;
 import org.openstreetmap.josm.gui.widgets.JosmTextArea;
 import org.openstreetmap.josm.gui.widgets.JosmTextField;
@@ -72,5 +72,5 @@
     private final ZoomInCurrentLayerAction       actZoomInCurrentLayerAction = new ZoomInCurrentLayerAction();
     // CHECKSTYLE.ON: SingleSpaceSeparator
-    
+
     private JButton btnOpenChangesetPopupMenu;
 
@@ -374,5 +374,5 @@
                             + "edit layer ''{1}''.</html>",
                             currentChangeset.getId(),
-                            Utils.escapeReservedCharactersHTML(MainApplication.getLayerManager().getEditLayer().getName())
+                            Utils.escapeReservedCharactersHTML(MainApplication.getLayerManager().getActiveDataSet().getName())
                     ),
                     tr("Nothing to select"),
@@ -383,13 +383,13 @@
 
         @Override
-        public void actionPerformed(ActionEvent arg0) {
+        public void actionPerformed(ActionEvent e) {
             if (!isEnabled())
                 return;
-            OsmDataLayer layer = MainApplication.getLayerManager().getEditLayer();
-            if (layer == null) {
+            DataSet ds = MainApplication.getLayerManager().getActiveDataSet();
+            if (ds == null) {
                 return;
             }
             Set<OsmPrimitive> target = new HashSet<>();
-            for (OsmPrimitive p: layer.data.allPrimitives()) {
+            for (OsmPrimitive p: ds.allPrimitives()) {
                 if (p.isUsable() && p.getChangesetId() == currentChangeset.getId()) {
                     target.add(p);
@@ -400,9 +400,9 @@
                 return;
             }
-            layer.data.setSelected(target);
+            ds.setSelected(target);
         }
 
         public void updateEnabledState() {
-            setEnabled(MainApplication.getLayerManager().getEditLayer() != null && currentChangeset != null);
+            setEnabled(MainApplication.getLayerManager().getActiveDataSet() != null && currentChangeset != null);
         }
 
@@ -433,5 +433,5 @@
                             + "edit layer ''{1}''.</html>",
                             currentChangeset.getId(),
-                            MainApplication.getLayerManager().getEditLayer().getName()
+                            MainApplication.getLayerManager().getActiveDataSet().getName()
                     ),
                     tr("Nothing to zoom to"),
@@ -442,13 +442,13 @@
 
         @Override
-        public void actionPerformed(ActionEvent arg0) {
+        public void actionPerformed(ActionEvent e) {
             if (!isEnabled())
                 return;
-            OsmDataLayer layer = MainApplication.getLayerManager().getEditLayer();
-            if (layer == null) {
+            DataSet ds = MainApplication.getLayerManager().getActiveDataSet();
+            if (ds == null) {
                 return;
             }
             Set<OsmPrimitive> target = new HashSet<>();
-            for (OsmPrimitive p: layer.data.allPrimitives()) {
+            for (OsmPrimitive p: ds.allPrimitives()) {
                 if (p.isUsable() && p.getChangesetId() == currentChangeset.getId()) {
                     target.add(p);
@@ -459,10 +459,10 @@
                 return;
             }
-            layer.data.setSelected(target);
+            ds.setSelected(target);
             AutoScaleAction.zoomToSelection();
         }
 
         public void updateEnabledState() {
-            setEnabled(MainApplication.getLayerManager().getEditLayer() != null && currentChangeset != null);
+            setEnabled(MainApplication.getLayerManager().getActiveDataSet() != null && currentChangeset != null);
         }
 
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/ChangesetsInActiveDataLayerListModel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/ChangesetsInActiveDataLayerListModel.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/ChangesetsInActiveDataLayerListModel.java	(revision 13434)
@@ -4,4 +4,5 @@
 import javax.swing.DefaultListSelectionModel;
 
+import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.event.AbstractDatasetChangedEvent;
 import org.openstreetmap.josm.data.osm.event.DataChangedEvent;
@@ -15,5 +16,4 @@
 import org.openstreetmap.josm.gui.layer.MainLayerManager.ActiveLayerChangeEvent;
 import org.openstreetmap.josm.gui.layer.MainLayerManager.ActiveLayerChangeListener;
-import org.openstreetmap.josm.gui.layer.OsmDataLayer;
 
 /**
@@ -81,7 +81,7 @@
         // just init the model content. Don't register as DataSetListener. The mode
         // is already registered to receive DataChangedEvents from the current edit layer
-        OsmDataLayer editLayer = e.getSource().getEditLayer();
-        if (editLayer != null) {
-            initFromDataSet(editLayer.data);
+        DataSet ds = e.getSource().getActiveDataSet();
+        if (ds != null) {
+            initFromDataSet(ds);
         } else {
             initFromDataSet(null);
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/properties/PropertiesDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/properties/PropertiesDialog.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/properties/PropertiesDialog.java	(revision 13434)
@@ -64,4 +64,5 @@
 import org.openstreetmap.josm.command.Command;
 import org.openstreetmap.josm.data.SelectionChangedListener;
+import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.DefaultNameFormatter;
 import org.openstreetmap.josm.data.osm.IRelation;
@@ -91,4 +92,5 @@
 import org.openstreetmap.josm.gui.layer.MainLayerManager.ActiveLayerChangeEvent;
 import org.openstreetmap.josm.gui.layer.MainLayerManager.ActiveLayerChangeListener;
+import org.openstreetmap.josm.gui.layer.OsmDataLayer;
 import org.openstreetmap.josm.gui.tagging.presets.TaggingPreset;
 import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetHandler;
@@ -231,5 +233,5 @@
 
     private final PreferenceChangedListener preferenceListener = e -> {
-                if (MainApplication.getLayerManager().getEditDataSet() != null) {
+                if (MainApplication.getLayerManager().getActiveDataSet() != null) {
                     // Re-load data when display preference change
                     updateSelection();
@@ -487,9 +489,9 @@
         Relation relation = (Relation) membershipData.getValueAt(row, 0);
         MainApplication.getMap().relationListDialog.selectRelation(relation);
-        RelationEditor.getEditor(
-                MainApplication.getLayerManager().getEditLayer(),
-                relation,
-                ((MemberInfo) membershipData.getValueAt(row, 1)).role
-        ).setVisible(true);
+        OsmDataLayer layer = MainApplication.getLayerManager().getActiveDataLayer();
+        if (!layer.isReadOnly()) {
+            RelationEditor.getEditor(
+                    layer, relation, ((MemberInfo) membershipData.getValueAt(row, 1)).role).setVisible(true);
+        }
     }
 
@@ -534,5 +536,5 @@
     public void setVisible(boolean b) {
         super.setVisible(b);
-        if (b && MainApplication.getLayerManager().getEditDataSet() != null) {
+        if (b && MainApplication.getLayerManager().getActiveDataSet() != null) {
             updateSelection();
         }
@@ -644,10 +646,12 @@
         membershipTable.setVisible(membershipData.getRowCount() > 0);
 
+        DataSet ds = Main.main.getActiveDataSet();
+        boolean isReadOnly = ds != null && ds.isReadOnly();
         boolean hasSelection = !newSel.isEmpty();
         boolean hasTags = hasSelection && tagData.getRowCount() > 0;
         boolean hasMemberships = hasSelection && membershipData.getRowCount() > 0;
-        addAction.setEnabled(hasSelection);
-        editAction.setEnabled(hasTags || hasMemberships);
-        deleteAction.setEnabled(hasTags || hasMemberships);
+        addAction.setEnabled(!isReadOnly && hasSelection);
+        editAction.setEnabled(!isReadOnly && (hasTags || hasMemberships));
+        deleteAction.setEnabled(!isReadOnly && (hasTags || hasMemberships));
         tagTable.setVisible(hasTags);
         tagTable.getTableHeader().setVisible(hasTags);
@@ -1055,8 +1059,9 @@
         @Override
         protected final void updateEnabledState() {
-            setEnabled(
-                    (tagTable != null && tagTable.getSelectedRowCount() >= 1)
+            DataSet ds = Main.main.getActiveDataSet();
+            setEnabled(ds != null && !ds.isReadOnly() &&
+                    ((tagTable != null && tagTable.getSelectedRowCount() >= 1)
                     || (membershipTable != null && membershipTable.getSelectedRowCount() > 0)
-                    );
+                    ));
         }
 
@@ -1110,8 +1115,9 @@
         @Override
         protected void updateEnabledState() {
-            setEnabled(
-                    (tagTable != null && tagTable.getSelectedRowCount() == 1)
+            DataSet ds = Main.main.getActiveDataSet();
+            setEnabled(ds != null && !ds.isReadOnly() &&
+                    ((tagTable != null && tagTable.getSelectedRowCount() == 1)
                     ^ (membershipTable != null && membershipTable.getSelectedRowCount() == 1)
-                    );
+                    ));
         }
 
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/properties/TagEditHelper.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/properties/TagEditHelper.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/properties/TagEditHelper.java	(revision 13434)
@@ -447,5 +447,5 @@
             mainPanel.add(p, BorderLayout.CENTER);
 
-            AutoCompletionManager autocomplete = AutoCompletionManager.of(MainApplication.getLayerManager().getEditLayer().data);
+            AutoCompletionManager autocomplete = AutoCompletionManager.of(Main.main.getActiveDataSet());
             List<AutoCompletionItem> keyList = autocomplete.getTagKeys(DEFAULT_AC_ITEM_COMPARATOR);
 
@@ -564,4 +564,5 @@
         public void setupDialog() {
             super.setupDialog();
+            buttons.get(0).setEnabled(!Main.main.getActiveDataSet().isReadOnly());
             final Dimension size = getSize();
             // Set resizable only in width
@@ -699,5 +700,5 @@
 
             cacheRecentTags();
-            AutoCompletionManager autocomplete = AutoCompletionManager.of(Main.main.getEditDataSet());
+            AutoCompletionManager autocomplete = AutoCompletionManager.of(Main.main.getActiveDataSet());
             List<AutoCompletionItem> keyList = autocomplete.getTagKeys(DEFAULT_AC_ITEM_COMPARATOR);
 
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTableModel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTableModel.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTableModel.java	(revision 13434)
@@ -114,5 +114,5 @@
     @Override
     public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) {
-        if (MainApplication.getLayerManager().getEditLayer() != this.layer) return;
+        if (MainApplication.getLayerManager().getActiveDataLayer() != this.layer) return;
         // just trigger a repaint
         Collection<RelationMember> sel = getSelectedMembers();
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/relation/SelectionTableModel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/relation/SelectionTableModel.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/relation/SelectionTableModel.java	(revision 13434)
@@ -107,5 +107,5 @@
     @Override
     public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) {
-        if (layer == MainApplication.getLayerManager().getEditLayer()) {
+        if (layer == MainApplication.getLayerManager().getActiveDataLayer()) {
             cache.clear();
             cache.addAll(newSelection);
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/validator/ValidatorTreePanel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/validator/ValidatorTreePanel.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/validator/ValidatorTreePanel.java	(revision 13434)
@@ -416,5 +416,5 @@
     @Override
     public void destroy() {
-        DataSet ds = MainApplication.getLayerManager().getEditDataSet();
+        DataSet ds = MainApplication.getLayerManager().getActiveDataSet();
         if (ds != null) {
             ds.removeDataSetListener(this);
Index: trunk/src/org/openstreetmap/josm/gui/history/HistoryBrowserModel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/history/HistoryBrowserModel.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/gui/history/HistoryBrowserModel.java	(revision 13434)
@@ -12,4 +12,5 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.UserIdentityManager;
+import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
@@ -102,7 +103,7 @@
 
         if (Main.main != null) {
-            OsmDataLayer editLayer = MainApplication.getLayerManager().getEditLayer();
-            if (editLayer != null) {
-                editLayer.data.addDataSetListener(this);
+            DataSet ds = MainApplication.getLayerManager().getActiveDataSet();
+            if (ds != null) {
+                ds.addDataSetListener(this);
             }
         }
@@ -169,7 +170,7 @@
         if (history.getNumVersions() > 0) {
             HistoryOsmPrimitive newLatest = null;
-            OsmDataLayer editLayer = MainApplication.getLayerManager().getEditLayer();
-            if (editLayer != null) {
-                OsmPrimitive p = editLayer.data.getPrimitiveById(history.getId(), history.getType());
+            DataSet ds = MainApplication.getLayerManager().getActiveDataSet();
+            if (ds != null) {
+                OsmPrimitive p = ds.getPrimitiveById(history.getId(), history.getType());
                 if (canShowAsLatest(p)) {
                     newLatest = new HistoryPrimitiveBuilder().build(p);
@@ -530,7 +531,7 @@
      */
     public void unlinkAsListener() {
-        OsmDataLayer editLayer = MainApplication.getLayerManager().getEditLayer();
-        if (editLayer != null) {
-            editLayer.data.removeDataSetListener(this);
+        DataSet ds = MainApplication.getLayerManager().getActiveDataSet();
+        if (ds != null) {
+            ds.removeDataSetListener(this);
         }
         MainApplication.getLayerManager().removeActiveLayerChangeListener(this);
Index: trunk/src/org/openstreetmap/josm/gui/history/NodeListViewer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/history/NodeListViewer.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/gui/history/NodeListViewer.java	(revision 13434)
@@ -22,4 +22,5 @@
 
 import org.openstreetmap.josm.actions.AutoScaleAction;
+import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
@@ -29,5 +30,4 @@
 import org.openstreetmap.josm.data.osm.history.HistoryDataSet;
 import org.openstreetmap.josm.gui.MainApplication;
-import org.openstreetmap.josm.gui.layer.OsmDataLayer;
 import org.openstreetmap.josm.gui.util.AdjustmentSynchronizer;
 import org.openstreetmap.josm.gui.util.GuiHelper;
@@ -249,7 +249,7 @@
             OsmPrimitive p = getPrimitiveToZoom();
             if (p != null) {
-                OsmDataLayer editLayer = MainApplication.getLayerManager().getEditLayer();
-                if (editLayer != null) {
-                    editLayer.data.setSelected(p.getPrimitiveId());
+                DataSet ds = MainApplication.getLayerManager().getActiveDataSet();
+                if (ds != null) {
+                    ds.setSelected(p.getPrimitiveId());
                     AutoScaleAction.autoScale("selection");
                 }
@@ -265,12 +265,12 @@
             if (primitiveId == null)
                 return null;
-            OsmDataLayer editLayer = MainApplication.getLayerManager().getEditLayer();
-            if (editLayer == null)
+            DataSet ds = MainApplication.getLayerManager().getActiveDataSet();
+            if (ds == null)
                 return null;
-            return editLayer.data.getPrimitiveById(primitiveId);
+            return ds.getPrimitiveById(primitiveId);
         }
 
         public void updateEnabledState() {
-            setEnabled(MainApplication.getLayerManager().getEditLayer() != null && getPrimitiveToZoom() != null);
+            setEnabled(MainApplication.getLayerManager().getActiveDataSet() != null && getPrimitiveToZoom() != null);
         }
     }
Index: trunk/src/org/openstreetmap/josm/gui/layer/AbstractModifiableLayer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/AbstractModifiableLayer.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/gui/layer/AbstractModifiableLayer.java	(revision 13434)
@@ -2,4 +2,5 @@
 package org.openstreetmap.josm.gui.layer;
 
+import org.openstreetmap.josm.data.osm.ReadOnly;
 import org.openstreetmap.josm.gui.io.AbstractIOTask;
 import org.openstreetmap.josm.gui.io.AbstractUploadDialog;
@@ -10,5 +11,5 @@
  * @since 7358
  */
-public abstract class AbstractModifiableLayer extends Layer implements UploadToServer, SaveToFile {
+public abstract class AbstractModifiableLayer extends Layer implements UploadToServer, SaveToFile, ReadOnly {
 
     /**
@@ -20,10 +21,4 @@
     }
 
-    /**
-     * Determines if the layer is able to upload data and implements the
-     * {@code UploadToServer} interface.
-     *
-     * @return true if the layer is able to upload data; false, otherwise
-     */
     @Override
     public boolean isUploadable() {
@@ -32,11 +27,4 @@
     }
 
-    /**
-     * Determines if the data managed by this layer needs to be uploaded to
-     * the server because it contains modified data.
-     *
-     * @return true if the data managed by this layer needs to be uploaded to
-     * the server because it contains modified data; false, otherwise
-     */
     @Override
     public boolean requiresUploadToServer() {
@@ -45,12 +33,4 @@
     }
 
-    /**
-     * Determines if the data managed by this layer needs to be saved to
-     * a file. Only replies true if a file is assigned to this layer and
-     * if the data managed by this layer has been modified since the last
-     * save operation to the file.
-     *
-     * @return true if the data managed by this layer needs to be saved to a file
-     */
     @Override
     public boolean requiresSaveToFile() {
@@ -59,10 +39,4 @@
     }
 
-    /**
-     * Determines if upload of data managed by this layer is discouraged.
-     * This feature allows to use "private" data layers.
-     *
-     * @return true if upload is discouraged for this layer; false, otherwise
-     */
     @Override
     public boolean isUploadDiscouraged() {
@@ -77,7 +51,4 @@
     public abstract boolean isModified();
 
-    /**
-     * Initializes the layer after a successful save of data to a file.
-     */
     @Override
     public void onPostSaveToFile() {
@@ -93,9 +64,4 @@
     }
 
-    /**
-     * Creates a new {@code AbstractIOTask} for uploading data.
-     * @param monitor The progress monitor
-     * @return a new {@code AbstractIOTask} for uploading data, or {@code null} if not applicable
-     */
     @Override
     public AbstractIOTask createUploadTask(ProgressMonitor monitor) {
@@ -104,8 +70,4 @@
     }
 
-    /**
-     * Returns the upload dialog for this layer.
-     * @return the upload dialog for this layer, or {@code null} if not applicable
-     */
     @Override
     public AbstractUploadDialog getUploadDialog() {
@@ -113,3 +75,25 @@
         return null;
     }
+
+    @Override
+    public boolean isUploadInProgress() {
+        // Override if needed
+        return false;
+    }
+
+    @Override
+    public void setReadOnly() {
+        // Override if needed
+    }
+
+    @Override
+    public void unsetReadOnly() {
+        // Override if needed
+    }
+
+    @Override
+    public boolean isReadOnly() {
+        // Override if needed
+        return false;
+    }
 }
Index: trunk/src/org/openstreetmap/josm/gui/layer/MainLayerManager.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/MainLayerManager.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/gui/layer/MainLayerManager.java	(revision 13434)
@@ -48,10 +48,10 @@
 
     /**
-     * This event is fired whenever the active or the edit layer changes.
+     * This event is fired whenever the active or the data layer changes.
      * @author Michael Zangl
      */
     public static class ActiveLayerChangeEvent extends LayerManagerEvent {
 
-        private final OsmDataLayer previousEditLayer;
+        private final OsmDataLayer previousDataLayer;
 
         private final Layer previousActiveLayer;
@@ -60,20 +60,31 @@
          * Create a new {@link ActiveLayerChangeEvent}
          * @param source The source
-         * @param previousEditLayer the previous edit layer
+         * @param previousDataLayer the previous data layer
          * @param previousActiveLayer the previous active layer
          */
-        ActiveLayerChangeEvent(MainLayerManager source, OsmDataLayer previousEditLayer,
+        ActiveLayerChangeEvent(MainLayerManager source, OsmDataLayer previousDataLayer,
                 Layer previousActiveLayer) {
             super(source);
-            this.previousEditLayer = previousEditLayer;
+            this.previousDataLayer = previousDataLayer;
             this.previousActiveLayer = previousActiveLayer;
         }
 
         /**
-         * Gets the edit layer that was previously used.
-         * @return The old edit layer, <code>null</code> if there is none.
-         */
+         * Gets the data layer that was previously used.
+         * @return The old data layer, <code>null</code> if there is none.
+         * @deprecated use {@link #getPreviousDataLayer}
+         */
+        @Deprecated
         public OsmDataLayer getPreviousEditLayer() {
-            return previousEditLayer;
+            return getPreviousDataLayer();
+        }
+
+        /**
+         * Gets the data layer that was previously used.
+         * @return The old data layer, <code>null</code> if there is none.
+         * @since 13434
+         */
+        public OsmDataLayer getPreviousDataLayer() {
+            return previousDataLayer;
         }
 
@@ -88,9 +99,20 @@
         /**
          * Gets the data set that was previously used.
-         * @return The data set of {@link #getPreviousEditLayer()}.
-         */
+         * @return The data set of {@link #getPreviousDataLayer()}.
+         * @deprecated use {@link #getPreviousDataSet}
+         */
+        @Deprecated
         public DataSet getPreviousEditDataSet() {
-            if (previousEditLayer != null) {
-                return previousEditLayer.data;
+            return getPreviousDataSet();
+        }
+
+        /**
+         * Gets the data set that was previously used.
+         * @return The data set of {@link #getPreviousDataLayer()}.
+         * @since 13434
+         */
+        public DataSet getPreviousDataSet() {
+            if (previousDataLayer != null) {
+                return previousDataLayer.data;
             } else {
                 return null;
@@ -151,7 +173,7 @@
 
     /**
-     * The edit layer is the current active data layer.
-     */
-    private OsmDataLayer editLayer;
+     * The current active data layer. It might be editable or not, based on its read-only status.
+     */
+    private OsmDataLayer dataLayer;
 
     private final List<ActiveLayerChangeListener> activeLayerChangeListeners = new CopyOnWriteArrayList<>();
@@ -214,5 +236,5 @@
 
     /**
-     * Set the active layer, unless the layer is read-only.
+     * Set the active layer, unless the layer is being uploaded.
      * If the layer is an OsmDataLayer, the edit layer is also changed.
      * @param layer The active layer.
@@ -221,5 +243,5 @@
         // we force this on to the EDT Thread to make events fire from there.
         // The synchronization lock needs to be held by the EDT.
-        if (layer instanceof OsmDataLayer && ((OsmDataLayer) layer).isReadOnly()) {
+        if (layer instanceof OsmDataLayer && ((OsmDataLayer) layer).isUploadInProgress()) {
             GuiHelper.runInEDT(() ->
                     JOptionPane.showMessageDialog(
@@ -240,10 +262,10 @@
 
     private void setActiveLayer(Layer layer, boolean forceEditLayerUpdate) {
-        ActiveLayerChangeEvent event = new ActiveLayerChangeEvent(this, editLayer, activeLayer);
+        ActiveLayerChangeEvent event = new ActiveLayerChangeEvent(this, dataLayer, activeLayer);
         activeLayer = layer;
         if (activeLayer instanceof OsmDataLayer) {
-            editLayer = (OsmDataLayer) activeLayer;
+            dataLayer = (OsmDataLayer) activeLayer;
         } else if (forceEditLayerUpdate) {
-            editLayer = null;
+            dataLayer = null;
         }
         fireActiveLayerChange(event);
@@ -252,5 +274,5 @@
     private void fireActiveLayerChange(ActiveLayerChangeEvent event) {
         GuiHelper.assertCallFromEdt();
-        if (event.getPreviousActiveLayer() != activeLayer || event.getPreviousEditLayer() != editLayer) {
+        if (event.getPreviousActiveLayer() != activeLayer || event.getPreviousDataLayer() != dataLayer) {
             for (ActiveLayerChangeListener l : activeLayerChangeListeners) {
                 l.activeOrEditLayerChanged(event);
@@ -277,5 +299,5 @@
     @Override
     protected Collection<Layer> realRemoveSingleLayer(Layer layer) {
-        if ((layer instanceof OsmDataLayer) && (((OsmDataLayer) layer).isReadOnly())) {
+        if ((layer instanceof OsmDataLayer) && (((OsmDataLayer) layer).isUploadInProgress())) {
             GuiHelper.runInEDT(() -> JOptionPane.showMessageDialog(MainApplication.parent,
                     tr("Trying to delete the layer with background upload. Please wait until the upload is finished.")));
@@ -285,5 +307,5 @@
         }
 
-        if (layer == activeLayer || layer == editLayer) {
+        if (layer == activeLayer || layer == dataLayer) {
             Layer nextActive = suggestNextActiveLayer(layer);
             setActiveLayer(nextActive, true);
@@ -337,5 +359,5 @@
     public synchronized Layer getActiveLayer() {
         if (activeLayer instanceof OsmDataLayer) {
-            if (!((OsmDataLayer) activeLayer).isReadOnly()) {
+            if (!((OsmDataLayer) activeLayer).isUploadInProgress()) {
                 return activeLayer;
             } else {
@@ -351,8 +373,9 @@
      *
      * @return the current edit layer. May be null.
+     * @see #getActiveDataLayer
      */
     public synchronized OsmDataLayer getEditLayer() {
-        if (editLayer != null && !editLayer.isReadOnly())
-            return editLayer;
+        if (dataLayer != null && !dataLayer.isReadOnly())
+            return dataLayer;
         else
             return null;
@@ -360,10 +383,39 @@
 
     /**
-     * Gets the data set of the active edit layer.
+     * Replies the active data layer. The layer can be read-only.
+     *
+     * @return the current data layer. May be null or read-only.
+     * @see #getEditLayer
+     * @since 13434
+     */
+    public synchronized OsmDataLayer getActiveDataLayer() {
+        if (dataLayer != null)
+            return dataLayer;
+        else
+            return null;
+    }
+
+    /**
+     * Gets the data set of the active edit layer, if not readOnly.
      * @return That data set, <code>null</code> if there is no edit layer.
+     * @see #getActiveDataSet
      */
     public synchronized DataSet getEditDataSet() {
-        if (editLayer != null) {
-            return editLayer.data;
+        if (dataLayer != null && !dataLayer.isReadOnly()) {
+            return dataLayer.data;
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Gets the data set of the active data layer. The dataset can be read-only.
+     * @return That data set, <code>null</code> if there is no active data layer.
+     * @see #getEditDataSet
+     * @since 13434
+     */
+    public synchronized DataSet getActiveDataSet() {
+        if (dataLayer != null) {
+            return dataLayer.data;
         } else {
             return null;
@@ -413,6 +465,6 @@
      */
     public void invalidateEditLayer() {
-        if (editLayer != null) {
-            editLayer.invalidate();
+        if (dataLayer != null) {
+            dataLayer.invalidate();
         }
     }
@@ -445,12 +497,12 @@
      */
     public void prepareLayerForUpload(OsmDataLayer layer) {
-
         GuiHelper.assertCallFromEdt();
+        layer.setUploadInProgress();
         layer.setReadOnly();
 
         // Reset only the edit layer as empty
-        if (editLayer == layer) {
-            ActiveLayerChangeEvent activeLayerChangeEvent = new ActiveLayerChangeEvent(this, editLayer, activeLayer);
-            editLayer = null;
+        if (dataLayer == layer) {
+            ActiveLayerChangeEvent activeLayerChangeEvent = new ActiveLayerChangeEvent(this, dataLayer, activeLayer);
+            dataLayer = null;
             fireActiveLayerChange(activeLayerChangeEvent);
         }
@@ -467,9 +519,10 @@
         GuiHelper.assertCallFromEdt();
         layer.unsetReadOnly();
+        layer.unsetUploadInProgress();
 
         // Set the layer as edit layer if the edit layer is empty.
-        if (editLayer == null) {
-            ActiveLayerChangeEvent layerChangeEvent = new ActiveLayerChangeEvent(this, editLayer, activeLayer);
-            editLayer = layer;
+        if (dataLayer == null) {
+            ActiveLayerChangeEvent layerChangeEvent = new ActiveLayerChangeEvent(this, dataLayer, activeLayer);
+            dataLayer = layer;
             fireActiveLayerChange(layerChangeEvent);
         }
Index: trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java	(revision 13434)
@@ -131,6 +131,6 @@
     private boolean requiresSaveToFile;
     private boolean requiresUploadToServer;
-    /** Flag used to know if the layer should not be editable */
-    private final AtomicBoolean isReadOnly = new AtomicBoolean(false);
+    /** Flag used to know if the layer is being uploaded */
+    private final AtomicBoolean isUploadInProgress = new AtomicBoolean(false);
 
     /**
@@ -425,7 +425,10 @@
         }
 
-        if (isReadOnly()) {
-            // If the layer is read only then change the default icon to a clock
+        if (isUploadInProgress()) {
+            // If the layer is being uploaded then change the default icon to a clock
             base = new ImageProvider("clock").setMaxSize(ImageSizes.LAYER);
+        } else if (isReadOnly()) {
+            // If the layer is read only then change the default icon to a lock
+            base = new ImageProvider("lock").setMaxSize(ImageSizes.LAYER);
         }
         return base.get();
@@ -1170,28 +1173,34 @@
     }
 
-    /**
-     * Sets the isReadOnly flag for the OsmDataLayer as true
-     */
+    @Override
     public void setReadOnly() {
-        if (!isReadOnly.compareAndSet(false, true)) {
-            Logging.warn("Trying to set readOnly flag on a readOnly layer ", this.getName());
-        }
-    }
-
-    /**
-     * Sets the isReadOnly flag for the OsmDataLayer as false
-     */
+        data.setReadOnly();
+    }
+
+    @Override
     public void unsetReadOnly() {
-        if (!isReadOnly.compareAndSet(true, false)) {
-            Logging.warn("Trying to unset readOnly flag on a non-readOnly layer ", this.getName());
-        }
-    }
-
-    /**
-     * Returns the value of the isReadOnly flag for the OsmDataLayer
-     * @return isReadOnly
-     */
+        data.unsetReadOnly();
+    }
+
+    @Override
     public boolean isReadOnly() {
-        return isReadOnly.get();
+        return data.isReadOnly();
+    }
+
+    public void setUploadInProgress() {
+        if (!isUploadInProgress.compareAndSet(false, true)) {
+            Logging.warn("Trying to set uploadInProgress flag on layer already being uploaded ", getName());
+        }
+    }
+
+    public void unsetUploadInProgress() {
+        if (!isUploadInProgress.compareAndSet(true, false)) {
+            Logging.warn("Trying to unset uploadInProgress flag on layer not being uploaded ", getName());
+        }
+    }
+
+    @Override
+    public boolean isUploadInProgress() {
+        return isUploadInProgress.get();
     }
 }
Index: trunk/src/org/openstreetmap/josm/gui/layer/UploadToServer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/UploadToServer.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/gui/layer/UploadToServer.java	(revision 13434)
@@ -40,4 +40,12 @@
 
     /**
+     * Determines if upload of data managed by this layer is currently in progress.
+     *
+     * @return {@code true} if upload is in progress
+     * @since 13434
+     */
+    boolean isUploadInProgress();
+
+    /**
      * Initializes the layer after a successful upload to the server.
      */
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/MapPaintMenu.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/MapPaintMenu.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/MapPaintMenu.java	(revision 13434)
@@ -67,5 +67,5 @@
         public void updateEnabledState() {
             setEnabled(MainApplication.isDisplayingMapView()
-                    && (MainApplication.getLayerManager().getEditLayer() != null || mapHasGpxorMarkerLayer()));
+                    && (MainApplication.getLayerManager().getActiveDataSet() != null || mapHasGpxorMarkerLayer()));
         }
 
Index: trunk/src/org/openstreetmap/josm/gui/tagging/ac/AutoCompletionManager.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/tagging/ac/AutoCompletionManager.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/gui/tagging/ac/AutoCompletionManager.java	(revision 13434)
@@ -145,7 +145,8 @@
      * Constructs a new {@code AutoCompletionManager}.
      * @param ds data set
+     * @throws NullPointerException if ds is null
      */
     public AutoCompletionManager(DataSet ds) {
-        this.ds = ds;
+        this.ds = Objects.requireNonNull(ds);
         this.dirty = true;
     }
Index: trunk/src/org/openstreetmap/josm/gui/tagging/presets/TaggingPresetSearchPrimitiveDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/tagging/presets/TaggingPresetSearchPrimitiveDialog.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/gui/tagging/presets/TaggingPresetSearchPrimitiveDialog.java	(revision 13434)
@@ -7,9 +7,8 @@
 import java.awt.event.KeyEvent;
 import java.util.HashSet;
-import java.util.Set;
 
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.actions.JosmAction;
-import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.gui.ExtendedDialog;
 import org.openstreetmap.josm.gui.MainApplication;
@@ -44,5 +43,5 @@
         @Override
         public void actionPerformed(ActionEvent e) {
-            if (MainApplication.getLayerManager().getEditLayer() != null) {
+            if (MainApplication.getLayerManager().getActiveDataSet() != null) {
                 TaggingPresetSearchPrimitiveDialog.getInstance().showDialog();
             }
@@ -51,5 +50,5 @@
         @Override
         protected void updateEnabledState() {
-            setEnabled(getLayerManager().getEditLayer() != null);
+            setEnabled(getLayerManager().getActiveDataSet() != null);
         }
     }
@@ -87,6 +86,6 @@
             TaggingPreset preset = selector.getSelectedPresetAndUpdateClassification();
             if (preset != null) {
-                final Set<OsmPrimitive> matching = new HashSet<>(Main.main.getEditDataSet().getPrimitives(preset));
-                Main.main.getEditDataSet().setSelected(matching);
+                DataSet ds = Main.main.getActiveDataSet();
+                ds.setSelected(new HashSet<>(ds.getPrimitives(preset)));
             }
         }
Index: trunk/src/org/openstreetmap/josm/gui/util/HighlightHelper.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/util/HighlightHelper.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/gui/util/HighlightHelper.java	(revision 13434)
@@ -132,5 +132,5 @@
      */
     public static void clearAllHighlighted() {
-        DataSet ds = MainApplication.getLayerManager().getEditDataSet();
+        DataSet ds = MainApplication.getLayerManager().getActiveDataSet();
         if (ds != null) {
             for (OsmPrimitive p: ds.allNonDeletedPrimitives()) {
Index: trunk/src/org/openstreetmap/josm/io/OsmReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OsmReader.java	(revision 13433)
+++ trunk/src/org/openstreetmap/josm/io/OsmReader.java	(revision 13434)
@@ -141,10 +141,12 @@
         String upload = parser.getAttributeValue(null, "upload");
         if (upload != null) {
-            for (UploadPolicy policy : UploadPolicy.values()) {
-                if (policy.getXmlFlag().equalsIgnoreCase(upload)) {
-                    ds.setUploadPolicy(policy);
-                    break;
-                }
-            }
+            try {
+                ds.setUploadPolicy(UploadPolicy.of(upload));
+            } catch (IllegalArgumentException e) {
+                throwException(MessageFormat.format("Illegal value for attribute ''upload''. Got ''{0}''.", upload), e);
+            }
+        }
+        if ("true".equalsIgnoreCase(parser.getAttributeValue(null, "read-only"))) {
+            ds.setReadOnly();
         }
         String generator = parser.getAttributeValue(null, "generator");
@@ -181,6 +183,7 @@
                     parseUnknown();
                 }
-            } else if (event == XMLStreamConstants.END_ELEMENT)
+            } else if (event == XMLStreamConstants.END_ELEMENT) {
                 return;
+            }
         }
     }
@@ -618,6 +621,14 @@
             progressMonitor.worked(1);
 
+            boolean readOnly = getDataSet().isReadOnly();
+
             progressMonitor.indeterminateSubTask(tr("Preparing data set..."));
+            if (readOnly) {
+                getDataSet().unsetReadOnly();
+            }
             prepareDataSet();
+            if (readOnly) {
+                getDataSet().setReadOnly();
+            }
             progressMonitor.worked(1);
 
@@ -628,4 +639,8 @@
                     pp.postprocessDataSet(getDataSet(), progressMonitor);
                 }
+            }
+            // Make sure postprocessors did not change the read-only state
+            if (readOnly && !getDataSet().isReadOnly()) {
+                getDataSet().setReadOnly();
             }
             return getDataSet();
