diff --git a/src/org/openstreetmap/josm/data/DataSource.java b/src/org/openstreetmap/josm/data/DataSource.java
index c3d78c4..374fd3c 100644
--- a/src/org/openstreetmap/josm/data/DataSource.java
+++ b/src/org/openstreetmap/josm/data/DataSource.java
@@ -38,6 +38,15 @@ public class DataSource {
         this.origin = origin;
     }
 
+    /**
+     * Cosntructs a new {@link DataSource}
+     * @param source The source to copy the data from.
+     * @since xxx
+     */
+    public DataSource(DataSource source) {
+        this(source.bounds, source.origin);
+    }
+
     @Override
     public int hashCode() {
         return Objects.hash(bounds, origin);
diff --git a/src/org/openstreetmap/josm/data/osm/DataSet.java b/src/org/openstreetmap/josm/data/osm/DataSet.java
index b497d0d..31709a9 100644
--- a/src/org/openstreetmap/josm/data/osm/DataSet.java
+++ b/src/org/openstreetmap/josm/data/osm/DataSet.java
@@ -137,6 +137,56 @@ public final class DataSet implements Data, Cloneable, ProjectionChangeListener
     }
 
     /**
+     * Creates a new {@link DataSet}.
+     * @param copyFrom An other {@link DataSet} to copy the contents of this dataset from.
+     * @since xxx
+     */
+    public DataSet(DataSet copyFrom) {
+        this();
+        copyFrom.getReadLock().lock();
+        try {
+            Map<OsmPrimitive, OsmPrimitive> primMap = new HashMap<>();
+            for (Node n : copyFrom.nodes) {
+                Node newNode = new Node(n);
+                primMap.put(n, newNode);
+                addPrimitive(newNode);
+            }
+            for (Way w : copyFrom.ways) {
+                Way newWay = new Way(w);
+                primMap.put(w, newWay);
+                List<Node> newNodes = new ArrayList<>();
+                for (Node n: w.getNodes()) {
+                    newNodes.add((Node) primMap.get(n));
+                }
+                newWay.setNodes(newNodes);
+                addPrimitive(newWay);
+            }
+            // Because relations can have other relations as members we first clone all relations
+            // and then get the cloned members
+            for (Relation r : copyFrom.relations) {
+                Relation newRelation = new Relation(r, r.isNew());
+                newRelation.setMembers(null);
+                primMap.put(r, newRelation);
+                addPrimitive(newRelation);
+            }
+            for (Relation r : copyFrom.relations) {
+                Relation newRelation = (Relation) primMap.get(r);
+                List<RelationMember> newMembers = new ArrayList<>();
+                for (RelationMember rm: r.getMembers()) {
+                    newMembers.add(new RelationMember(rm.getRole(), primMap.get(rm.getMember())));
+                }
+                newRelation.setMembers(newMembers);
+            }
+            for (DataSource source : copyFrom.dataSources) {
+                dataSources.add(new DataSource(source));
+            }
+            version = copyFrom.version;
+        } finally {
+            copyFrom.getReadLock().unlock();
+        }
+    }
+
+    /**
      * Returns the lock used for reading.
      * @return the lock used for reading
      */
@@ -872,54 +922,14 @@ public final class DataSet implements Data, Cloneable, ProjectionChangeListener
         }
     }
 
+    /**
+     * Return a copy of this dataset
+     * @deprecated Use the copy constructor instead. Remove in July 2016
+     */
+    @Deprecated
     @Override
     public DataSet clone() {
-        getReadLock().lock();
-        try {
-            DataSet ds = (DataSet) super.clone();
-            Main.addProjectionChangeListener(ds);
-            Map<OsmPrimitive, OsmPrimitive> primMap = new HashMap<>();
-            for (Node n : nodes) {
-                Node newNode = new Node(n);
-                primMap.put(n, newNode);
-                ds.addPrimitive(newNode);
-            }
-            for (Way w : ways) {
-                Way newWay = new Way(w);
-                primMap.put(w, newWay);
-                List<Node> newNodes = new ArrayList<>();
-                for (Node n: w.getNodes()) {
-                    newNodes.add((Node) primMap.get(n));
-                }
-                newWay.setNodes(newNodes);
-                ds.addPrimitive(newWay);
-            }
-            // Because relations can have other relations as members we first clone all relations
-            // and then get the cloned members
-            for (Relation r : relations) {
-                Relation newRelation = new Relation(r, r.isNew());
-                newRelation.setMembers(null);
-                primMap.put(r, newRelation);
-                ds.addPrimitive(newRelation);
-            }
-            for (Relation r : relations) {
-                Relation newRelation = (Relation) primMap.get(r);
-                List<RelationMember> newMembers = new ArrayList<>();
-                for (RelationMember rm: r.getMembers()) {
-                    newMembers.add(new RelationMember(rm.getRole(), primMap.get(rm.getMember())));
-                }
-                newRelation.setMembers(newMembers);
-            }
-            for (DataSource source : dataSources) {
-                ds.dataSources.add(new DataSource(source.bounds, source.origin));
-            }
-            ds.version = version;
-            return ds;
-        } catch (CloneNotSupportedException e) {
-            throw new IllegalStateException(e);
-        } finally {
-            getReadLock().unlock();
-        }
+        return new DataSet(this);
     }
 
     @Override
diff --git a/src/org/openstreetmap/josm/gui/dialogs/layer/DuplicateAction.java b/src/org/openstreetmap/josm/gui/dialogs/layer/DuplicateAction.java
index c7f16d3..2d54c21 100644
--- a/src/org/openstreetmap/josm/gui/dialogs/layer/DuplicateAction.java
+++ b/src/org/openstreetmap/josm/gui/dialogs/layer/DuplicateAction.java
@@ -10,6 +10,7 @@ import java.util.List;
 import javax.swing.AbstractAction;
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.gui.dialogs.LayerListDialog.LayerListModel;
 import org.openstreetmap.josm.gui.help.HelpUtil;
 import org.openstreetmap.josm.gui.layer.Layer;
@@ -68,7 +69,7 @@ public final class DuplicateAction extends AbstractAction implements IEnabledSta
                 newName = tr("Copy {1} of {0}", oldLayer.getName(), i);
                 i++;
             }
-            Main.main.addLayer(new OsmDataLayer(oldLayer.data.clone(), newName, null));
+            Main.main.addLayer(new OsmDataLayer(new DataSet(oldLayer.data), newName, null));
         }
     }
 
