Index: trunk/src/org/openstreetmap/josm/actions/PasteTagsAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/PasteTagsAction.java	(revision 3638)
+++ trunk/src/org/openstreetmap/josm/actions/PasteTagsAction.java	(revision 3640)
@@ -23,6 +23,7 @@
 import org.openstreetmap.josm.data.osm.PrimitiveData;
 import org.openstreetmap.josm.data.osm.PrimitiveDeepCopy;
+import org.openstreetmap.josm.data.osm.PrimitiveDeepCopy.PasteBufferChangedListener;
+import org.openstreetmap.josm.data.osm.Tag;
 import org.openstreetmap.josm.data.osm.TagCollection;
-import org.openstreetmap.josm.data.osm.PrimitiveDeepCopy.PasteBufferChangedListener;
 import org.openstreetmap.josm.gui.conflict.tags.PasteTagsConflictResolverDialog;
 import org.openstreetmap.josm.tools.Shortcut;
@@ -42,5 +43,5 @@
         private final Collection<PrimitiveData> source;
         private final Collection<OsmPrimitive> target;
-        private final List<Command> commands = new ArrayList<Command>();
+        private final List<Tag> commands = new ArrayList<Tag>();
 
         public TagPaster(Collection<PrimitiveData> source, Collection<OsmPrimitive> target) {
@@ -100,20 +101,8 @@
         }
 
-        protected Command buildChangeCommand(Collection<? extends OsmPrimitive> selection, TagCollection tc) {
-            List<Command> commands = new ArrayList<Command>();
+        protected void buildChangeCommand(Collection<? extends OsmPrimitive> selection, TagCollection tc) {
             for (String key : tc.getKeys()) {
-                String value = tc.getValues(key).iterator().next();
-                value = value.equals("") ? null : value;
-                commands.add(new ChangePropertyCommand(selection,key,value));
-            }
-            if (!commands.isEmpty()) {
-                String title1 = trn("Pasting {0} tag", "Pasting {0} tags", tc.getKeys().size(), tc.getKeys().size());
-                String title2 = trn("to {0} primitive", "to {0} primtives", selection.size(), selection.size());
-                return new SequenceCommand(
-                        title1 + " " + title2,
-                        commands
-                );
-            }
-            return null;
+                commands.add(new Tag(key, tc.getValues(key).iterator().next()));
+            }
         }
 
@@ -166,12 +155,10 @@
                 if (dialog.isCanceled())
                     return;
-                Command cmd = buildChangeCommand(target, dialog.getResolution());
-                commands.add(cmd);
+                buildChangeCommand(target, dialog.getResolution());
             } else {
                 // no conflicts in the source tags to resolve. Just apply the tags
                 // to the target primitives
                 //
-                Command cmd = buildChangeCommand(target, tc);
-                commands.add(cmd);
+                buildChangeCommand(target, tc);
             }
         }
@@ -218,6 +205,5 @@
                 for (OsmPrimitiveType type:OsmPrimitiveType.values()) {
                     if (hasSourceTagsByType(type) && hasTargetPrimitives(type.getOsmClass())) {
-                        Command cmd = buildChangeCommand(target, getSourceTagsByType(type));
-                        commands.add(cmd);
+                        buildChangeCommand(target, getSourceTagsByType(type));
                     }
                 }
@@ -236,6 +222,5 @@
                 for (OsmPrimitiveType type:OsmPrimitiveType.values()) {
                     if (hasSourceTagsByType(type) && hasTargetPrimitives(type.getOsmClass())) {
-                        Command cmd = buildChangeCommand(OsmPrimitive.getFilteredList(target, type.getOsmClass()), dialog.getResolution(type));
-                        commands.add(cmd);
+                        buildChangeCommand(OsmPrimitive.getFilteredList(target, type.getOsmClass()), dialog.getResolution(type));
                     }
                 }
@@ -243,5 +228,5 @@
         }
 
-        public List<Command> execute() {
+        public List<Tag> execute() {
             commands.clear();
             if (isHeteogeneousSource()) {
@@ -256,10 +241,25 @@
 
     public void actionPerformed(ActionEvent e) {
-        if (getCurrentDataSet().getSelected().isEmpty())
+        Collection<OsmPrimitive> selection = getCurrentDataSet().getSelected();
+
+        if (selection.isEmpty())
             return;
-        TagPaster tagPaster = new TagPaster(Main.pasteBuffer.getDirectlyAdded(), getCurrentDataSet().getSelected());
-        for (Command c:tagPaster.execute()) {
-            Main.main.undoRedo.add(c);
-        }
+
+        TagPaster tagPaster = new TagPaster(Main.pasteBuffer.getDirectlyAdded(), selection);
+
+        List<Command> commands = new ArrayList<Command>();
+        for (Tag tag: tagPaster.execute()) {
+            commands.add(new ChangePropertyCommand(selection, tag.getKey(), "".equals(tag.getValue())?null:tag.getValue()));
+        }
+        if (!commands.isEmpty()) {
+            String title1 = trn("Pasting {0} tag", "Pasting {0} tags", commands.size(), commands.size());
+            String title2 = trn("to {0} primitive", "to {0} primtives", selection.size(), selection.size());
+            Main.main.undoRedo.add(
+                    new SequenceCommand(
+                            title1 + " " + title2,
+                            commands
+                    ));
+        }
+
     }
 
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java	(revision 3638)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java	(revision 3640)
@@ -54,4 +54,5 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.actions.CopyAction;
+import org.openstreetmap.josm.actions.PasteTagsAction.TagPaster;
 import org.openstreetmap.josm.command.AddCommand;
 import org.openstreetmap.josm.command.ChangeCommand;
@@ -132,25 +133,5 @@
             @Override
             public void updateTags(List<Tag> tags) {
-                Map<String, TagModel> modelTags = new HashMap<String, TagModel>();
-                for (int i=0; i<tagEditorPanel.getModel().getRowCount(); i++) {
-                    TagModel tagModel = tagEditorPanel.getModel().get(i);
-                    modelTags.put(tagModel.getName(), tagModel);
-                }
-                for (Tag tag: tags) {
-                    TagModel existing = modelTags.get(tag.getKey());
-
-                    if (tag.getValue().isEmpty()) {
-                        if (existing != null) {
-                            tagEditorPanel.getModel().delete(tag.getKey());
-                        }
-                    } else {
-                        if (existing != null) {
-                            tagEditorPanel.getModel().updateTagValue(existing, tag.getValue());
-                        } else {
-                            tagEditorPanel.getModel().add(tag.getKey(), tag.getValue());
-                        }
-                    }
-
-                }
+                GenericRelationEditor.this.updateTags(tags);
             }
 
@@ -429,4 +410,5 @@
         new PasteMembersAction();
         new CopyMembersAction();
+        new PasteTagsAction();
 
         return pnl3;
@@ -650,4 +632,32 @@
     }
 
+    protected void updateTags(List<Tag> tags) {
+
+        if (tags.isEmpty())
+            return;
+
+        Map<String, TagModel> modelTags = new HashMap<String, TagModel>();
+        for (int i=0; i<tagEditorPanel.getModel().getRowCount(); i++) {
+            TagModel tagModel = tagEditorPanel.getModel().get(i);
+            modelTags.put(tagModel.getName(), tagModel);
+        }
+        for (Tag tag: tags) {
+            TagModel existing = modelTags.get(tag.getKey());
+
+            if (tag.getValue().isEmpty()) {
+                if (existing != null) {
+                    tagEditorPanel.getModel().delete(tag.getKey());
+                }
+            } else {
+                if (existing != null) {
+                    tagEditorPanel.getModel().updateTagValue(existing, tag.getValue());
+                } else {
+                    tagEditorPanel.getModel().add(tag.getKey(), tag.getValue());
+                }
+            }
+
+        }
+    }
+
     static class AddAbortException extends Exception  {
     }
@@ -1565,4 +1575,20 @@
     }
 
+    class PasteTagsAction extends AbstractAction {
+
+        public PasteTagsAction() {
+            registerCopyPasteAction(this, "PASTE_TAGS", Shortcut.registerShortcut("system:pastestyle", tr("Edit: {0}", tr("Paste Tags")), KeyEvent.VK_V, Shortcut.GROUP_MENU, Shortcut.SHIFT_DEFAULT).getKeyStroke());
+        }
+
+        @Override
+        public void actionPerformed(ActionEvent e) {
+            Relation relation = new Relation();
+            tagEditorPanel.getModel().applyToPrimitive(relation);
+            TagPaster tagPaster = new TagPaster(Main.pasteBuffer.getDirectlyAdded(), Collections.<OsmPrimitive>singletonList(relation));
+            updateTags(tagPaster.execute());
+        }
+
+    }
+
     class MemberTableDblClickAdapter extends MouseAdapter {
         @Override
Index: trunk/src/org/openstreetmap/josm/gui/tagging/TagEditorModel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/tagging/TagEditorModel.java	(revision 3638)
+++ trunk/src/org/openstreetmap/josm/gui/tagging/TagEditorModel.java	(revision 3640)
@@ -209,5 +209,9 @@
         if (tag == null) {
             tag = new TagModel(name, value);
-            tags.add(tag);
+            int index = tags.size();
+            while (index >= 1 && tags.get(index - 1).getName().isEmpty() && tags.get(index - 1).getValue().isEmpty()) {
+                index--; // If last line(s) is empty, add new tag before it
+            }
+            tags.add(index, tag);
         } else {
             tag.addValue(value);
