Index: /trunk/src/org/openstreetmap/josm/actions/CopyAction.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/CopyAction.java	(revision 1513)
+++ /trunk/src/org/openstreetmap/josm/actions/CopyAction.java	(revision 1514)
@@ -18,4 +18,5 @@
 import org.openstreetmap.josm.data.SelectionChangedListener;
 import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.DataSource;
 import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.data.osm.RelationMember;
@@ -45,5 +46,5 @@
     public void actionPerformed(ActionEvent e) {
         if(noSelection()) return;
-        
+
         Main.pasteBuffer = copyData();
         Main.main.menu.paste.setEnabled(true); /* now we have a paste buffer we can make paste available */
@@ -53,5 +54,5 @@
         }
     }
-    
+
     public static DataSet copyData() {
         /* New pasteBuffer - will be assigned to the global one at the end */
@@ -59,7 +60,7 @@
         final HashMap<OsmPrimitive,OsmPrimitive> map = new HashMap<OsmPrimitive,OsmPrimitive>();
         /* temporarily maps old nodes to new so we can do a true deep copy */
-        
+
         if(noSelection()) return pasteBuffer;
-        
+
         /* scan the selected objects, mapping them to copies; when copying a way or relation,
          * the copy references the copies of their child objects */
@@ -87,5 +88,4 @@
                     nodes.add((Node)map.get(n));
                 }
-                wnew.nodes.clear();
                 wnew.nodes.addAll(nodes);
                 pasteBuffer.addPrimitive(wnew);
@@ -109,7 +109,15 @@
                 for (OsmPrimitive osm : Main.ds.getSelected())
                     osm.visit(this);
+
+                // Used internally only (in PasteTagsAction), therefore no need to translate these
+                if(Main.ds.getSelectedNodes().size() > 0)
+                    pasteBuffer.dataSources.add(new DataSource(null, "Copied Nodes"));
+                if(Main.ds.getSelectedWays().size() > 0)
+                    pasteBuffer.dataSources.add(new DataSource(null, "Copied Ways"));
+                if(Main.ds.getSelectedRelations().size() > 0)
+                    pasteBuffer.dataSources.add(new DataSource(null, "Copied Relations"));
             }
         }.visitAll();
-        
+
         return pasteBuffer;
     }
@@ -118,5 +126,5 @@
         setEnabled(! newSelection.isEmpty());
     }
-    
+
     private static boolean noSelection() {
         Collection<OsmPrimitive> sel = Main.ds.getSelected();
Index: /trunk/src/org/openstreetmap/josm/actions/PasteTagsAction.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/actions/PasteTagsAction.java	(revision 1513)
+++ /trunk/src/org/openstreetmap/josm/actions/PasteTagsAction.java	(revision 1514)
@@ -19,4 +19,5 @@
 import org.openstreetmap.josm.data.SelectionChangedListener;
 import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.DataSource;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.tools.Shortcut;
@@ -36,15 +37,16 @@
         /* scan the paste buffer, and add tags to each of the selected objects.
          * If a tag already exists, it is overwritten */
-        if (selectionSubset != null && ! selectionSubset.isEmpty()) {
-            for (Iterator<? extends OsmPrimitive> it = pasteBufferSubset.iterator(); it.hasNext();) {
-                OsmPrimitive osm = it.next();
-                Map<String, String> m = osm.keys;
-                if(m != null)
-                {
-                    for (String key : m.keySet()) {
-                        if (! key.equals("created_by"))
-                            clist.add(new ChangePropertyCommand(selectionSubset, key, osm.keys.get(key)));
-                    }
-                }
+        if (selectionSubset == null || selectionSubset.isEmpty())
+            return;
+
+        for (Iterator<? extends OsmPrimitive> it = pasteBufferSubset.iterator(); it.hasNext();) {
+            OsmPrimitive osm = it.next();
+            Map<String, String> m = osm.keys;
+            if(m == null)
+                continue;
+
+            for (String key : m.keySet()) {
+                if (! key.equals("created_by"))
+                    clist.add(new ChangePropertyCommand(selectionSubset, key, osm.keys.get(key)));
             }
         }
@@ -53,7 +55,27 @@
     public void actionPerformed(ActionEvent e) {
         Collection<Command> clist = new LinkedList<Command>();
-        pasteKeys(clist, Main.pasteBuffer.nodes, Main.ds.getSelectedNodes());
-        pasteKeys(clist, Main.pasteBuffer.ways, Main.ds.getSelectedWays());
-        pasteKeys(clist, Main.pasteBuffer.relations, Main.ds.getSelectedRelations());
+        String pbSource = "Multiple Sources";
+        if(Main.pasteBuffer.dataSources.size() == 1)
+            pbSource = ((DataSource) Main.pasteBuffer.dataSources.toArray()[0]).origin;
+
+        boolean pbNodes = Main.pasteBuffer.nodes.size() > 0;
+        boolean pbWays  = Main.pasteBuffer.ways.size() > 0;
+
+        boolean seNodes = Main.ds.getSelectedNodes().size() > 0;
+        boolean seWays  = Main.ds.getSelectedWays().size() > 0;
+        boolean seRels  = Main.ds.getSelectedRelations().size() > 0;
+
+        if(!seNodes && seWays && !seRels && pbNodes && pbSource.equals("Copied Nodes")) {
+            // Copy from nodes to ways
+            pasteKeys(clist, Main.pasteBuffer.nodes, Main.ds.getSelectedWays());
+        } else if(seNodes && !seWays && !seRels && pbWays && pbSource.equals("Copied Ways")) {
+            // Copy from ways to nodes
+            pasteKeys(clist, Main.pasteBuffer.ways, Main.ds.getSelectedNodes());
+        } else {
+            // Copy from equal to equal
+            pasteKeys(clist, Main.pasteBuffer.nodes, Main.ds.getSelectedNodes());
+            pasteKeys(clist, Main.pasteBuffer.ways, Main.ds.getSelectedWays());
+            pasteKeys(clist, Main.pasteBuffer.relations, Main.ds.getSelectedRelations());
+        }
         Main.main.undoRedo.add(new SequenceCommand(tr("Paste Tags"), clist));
         Main.ds.setSelected(Main.ds.getSelected()); // to force selection listeners, in particular the tag panel, to update
