diff --git a/src/org/openstreetmap/josm/gui/datatransfer/TagTransferable.java b/src/org/openstreetmap/josm/gui/datatransfer/TagTransferable.java
new file mode 100644
index 0000000..b13f856
--- /dev/null
+++ b/src/org/openstreetmap/josm/gui/datatransfer/TagTransferable.java
@@ -0,0 +1,62 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.datatransfer;
+
+import java.awt.datatransfer.DataFlavor;
+import java.awt.datatransfer.Transferable;
+import java.awt.datatransfer.UnsupportedFlavorException;
+import java.io.IOException;
+import java.util.Map.Entry;
+import java.util.stream.Stream;
+
+import org.openstreetmap.josm.gui.datatransfer.data.TagTransferData;
+
+/**
+ * This is a transferable that only transfers the tags.
+ * @author Michael Zangl
+ * @since xxx
+ */
+public class TagTransferable implements Transferable {
+    private TagTransferData data;
+
+    /**
+     * Transfer the tag transfer data.
+     * @param data The data.
+     */
+    public TagTransferable(TagTransferData data) {
+        this.data = data;
+    }
+
+    @Override
+    public DataFlavor[] getTransferDataFlavors() {
+        return new DataFlavor[] { TagTransferData.FLAVOR, DataFlavor.stringFlavor };
+    }
+
+    @Override
+    public boolean isDataFlavorSupported(DataFlavor flavor) {
+        return Stream.of(getTransferDataFlavors()).anyMatch(f -> f.equals(flavor));
+    }
+
+    @Override
+    public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
+        if (DataFlavor.stringFlavor.equals(flavor)) {
+            return getStringData();
+        } else if (TagTransferData.FLAVOR.equals(flavor)) {
+            return data;
+        } else {
+            throw new UnsupportedFlavorException(flavor);
+        }
+    }
+
+    private String getStringData() {
+        StringBuilder string = new StringBuilder();
+        for (Entry<String, String> e : data.getTags().entrySet()) {
+            if (string.length() > 0) {
+                string.append("\n");
+            }
+            string.append(e.getKey());
+            string.append("=");
+            string.append(e.getValue());
+        }
+        return string.toString();
+    }
+}
diff --git a/src/org/openstreetmap/josm/gui/datatransfer/data/TagTransferData.java b/src/org/openstreetmap/josm/gui/datatransfer/data/TagTransferData.java
index d05c010..db1fd10 100644
--- a/src/org/openstreetmap/josm/gui/datatransfer/data/TagTransferData.java
+++ b/src/org/openstreetmap/josm/gui/datatransfer/data/TagTransferData.java
@@ -39,6 +39,15 @@ public class TagTransferData implements Serializable {
     }
 
     /**
+     * Create a new {@link TagTransferData} object with the given tags.
+     * @param tags The tags.
+     * @since xxx
+     */
+    public TagTransferData(Map<String, String> tags) {
+        this.tags.putAll(tags);
+    }
+
+    /**
      * Gets all tags contained in this data.
      * @return The tags.
      */
diff --git a/src/org/openstreetmap/josm/gui/history/HistoryBrowserModel.java b/src/org/openstreetmap/josm/gui/history/HistoryBrowserModel.java
index 08719e1..e30b43f 100644
--- a/src/org/openstreetmap/josm/gui/history/HistoryBrowserModel.java
+++ b/src/org/openstreetmap/josm/gui/history/HistoryBrowserModel.java
@@ -581,6 +581,16 @@ public class HistoryBrowserModel extends ChangeNotifier implements ActiveLayerCh
 
         @Override
         public Object getValueAt(int row, int column) {
+            return getKeyAt(row);
+        }
+
+        /**
+         * Get the key for the given row.
+         * @param row The row
+         * @return The key in that row.
+         * @since xxx
+         */
+        public String getKeyAt(int row) {
             return keys.get(row);
         }
 
@@ -636,7 +646,7 @@ public class HistoryBrowserModel extends ChangeNotifier implements ActiveLayerCh
 
         @Override
         public int getColumnCount() {
-            return 1;
+            return 2;
         }
     }
 
diff --git a/src/org/openstreetmap/josm/gui/history/SelectionSynchronizer.java b/src/org/openstreetmap/josm/gui/history/SelectionSynchronizer.java
index 00fa272..e60a354 100644
--- a/src/org/openstreetmap/josm/gui/history/SelectionSynchronizer.java
+++ b/src/org/openstreetmap/josm/gui/history/SelectionSynchronizer.java
@@ -12,6 +12,7 @@ import javax.swing.event.ListSelectionListener;
 public class SelectionSynchronizer implements ListSelectionListener {
 
     private final Set<ListSelectionModel> participants;
+    private boolean preventRecursion = false;
 
     /**
      * Constructs a new {@code SelectionSynchronizer}.
@@ -31,6 +32,10 @@ public class SelectionSynchronizer implements ListSelectionListener {
 
     @Override
     public void valueChanged(ListSelectionEvent e) {
+        if (preventRecursion) {
+            return;
+        }
+        preventRecursion = true;
         DefaultListSelectionModel referenceModel = (DefaultListSelectionModel) e.getSource();
         int i = referenceModel.getMinSelectionIndex();
         for (ListSelectionModel model : participants) {
@@ -39,5 +44,6 @@ public class SelectionSynchronizer implements ListSelectionListener {
             }
             model.setSelectionInterval(i, i);
         }
+        preventRecursion = false;
     }
 }
diff --git a/src/org/openstreetmap/josm/gui/history/TagInfoTransferHandler.java b/src/org/openstreetmap/josm/gui/history/TagInfoTransferHandler.java
new file mode 100644
index 0000000..31b7683
--- /dev/null
+++ b/src/org/openstreetmap/josm/gui/history/TagInfoTransferHandler.java
@@ -0,0 +1,47 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.history;
+
+import java.awt.datatransfer.Clipboard;
+
+import javax.swing.JComponent;
+import javax.swing.JTable;
+import javax.swing.TransferHandler;
+import javax.swing.table.TableModel;
+
+import org.openstreetmap.josm.data.osm.TagMap;
+import org.openstreetmap.josm.gui.datatransfer.ClipboardUtils;
+import org.openstreetmap.josm.gui.datatransfer.TagTransferable;
+import org.openstreetmap.josm.gui.datatransfer.data.TagTransferData;
+import org.openstreetmap.josm.gui.history.HistoryBrowserModel.TagTableModel;
+
+/**
+ * This transfer handler allows to select and copy tags from a table with the {@link TagTableColumnModel}.
+ * @author Michael Zangl
+ * @since xxx
+ */
+public class TagInfoTransferHandler extends TransferHandler {
+
+    @Override
+    public void exportToClipboard(JComponent comp, Clipboard clip, int action) throws IllegalStateException {
+        if (comp instanceof JTable) {
+            TableModel model = ((JTable) comp).getModel();
+            if (model instanceof TagTableModel) {
+                exportFromModel((JTable) comp, (TagTableModel) model);
+            }
+        }
+    }
+
+    private void exportFromModel(JTable comp, TagTableModel model) {
+        int[] selected = comp.getSelectedRows();
+        TagMap tags = new TagMap();
+        for (int row : selected) {
+            String key = model.getKeyAt(row);
+            String value = model.getValue(key);
+            if (value != null) {
+                tags.put(key, value);
+            }
+        }
+        TagTransferData data = new TagTransferData(tags);
+        ClipboardUtils.copy(new TagTransferable(data));
+    }
+}
diff --git a/src/org/openstreetmap/josm/gui/history/TagInfoViewer.java b/src/org/openstreetmap/josm/gui/history/TagInfoViewer.java
index d354dde..4000099 100644
--- a/src/org/openstreetmap/josm/gui/history/TagInfoViewer.java
+++ b/src/org/openstreetmap/josm/gui/history/TagInfoViewer.java
@@ -1,6 +1,9 @@
 // License: GPL. For details, see LICENSE file.
 package org.openstreetmap.josm.gui.history;
 
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+
 import javax.swing.JTable;
 import javax.swing.ListSelectionModel;
 
@@ -15,6 +18,30 @@ import javax.swing.ListSelectionModel;
  *
  */
 public class TagInfoViewer extends HistoryViewerPanel {
+    private static final class RepaintOnFocusChange implements FocusListener {
+        @Override
+        public void focusLost(FocusEvent e) {
+            repaintSelected(e);
+        }
+
+        @Override
+        public void focusGained(FocusEvent e) {
+            repaintSelected(e);
+        }
+
+        private void repaintSelected(FocusEvent e) {
+            // we would only need the selected rows, but this is easier:
+            e.getComponent().repaint();
+        }
+    }
+
+    /**
+     * Constructs a new {@code TagInfoViewer}.
+     * @param model The history browsing model
+     */
+    public TagInfoViewer(HistoryBrowserModel model) {
+        super(model);
+    }
 
     @Override
     protected JTable buildReferenceTable() {
@@ -23,8 +50,7 @@ public class TagInfoViewer extends HistoryViewerPanel {
                 new TagTableColumnModel()
         );
         table.setName("table.referencetagtable");
-        table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
-        selectionSynchronizer.participateInSynchronizedSelection(table.getSelectionModel());
+        setUpDataTransfer(table);
         return table;
     }
 
@@ -35,16 +61,14 @@ public class TagInfoViewer extends HistoryViewerPanel {
                 new TagTableColumnModel()
         );
         table.setName("table.currenttagtable");
-        table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
-        selectionSynchronizer.participateInSynchronizedSelection(table.getSelectionModel());
+        setUpDataTransfer(table);
         return table;
     }
 
-    /**
-     * Constructs a new {@code TagInfoViewer}.
-     * @param model The history browsing model
-     */
-    public TagInfoViewer(HistoryBrowserModel model) {
-        super(model);
+    private void setUpDataTransfer(JTable table) {
+        table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+        selectionSynchronizer.participateInSynchronizedSelection(table.getSelectionModel());
+        table.setTransferHandler(new TagInfoTransferHandler());
+        table.addFocusListener(new RepaintOnFocusChange());
     }
 }
diff --git a/src/org/openstreetmap/josm/gui/history/TagTableCellRenderer.java b/src/org/openstreetmap/josm/gui/history/TagTableCellRenderer.java
index a773cae..d6fa655 100644
--- a/src/org/openstreetmap/josm/gui/history/TagTableCellRenderer.java
+++ b/src/org/openstreetmap/josm/gui/history/TagTableCellRenderer.java
@@ -16,7 +16,14 @@ import org.openstreetmap.josm.gui.util.GuiHelper;
  *
  */
 public class TagTableCellRenderer extends JLabel implements TableCellRenderer {
-    public static final Color BGCOLOR_SELECTED = new Color(143, 170, 255);
+    /**
+     * The background color for a selected row that has the focus.
+     */
+    public static final Color BGCOLOR_SELECTED_FOCUS = new Color(0xff8faaff);
+    /**
+     * The background color for a selected row while the table is not focused.
+     */
+    public static final Color BGCOLOR_SELECTED = new Color(0xffafc2ff);
 
     /**
      * Constructs a new {@code TagTableCellRenderer}.
@@ -25,7 +32,7 @@ public class TagTableCellRenderer extends JLabel implements TableCellRenderer {
         setOpaque(true);
     }
 
-    protected void setBackgroundReadable(String key, HistoryBrowserModel.TagTableModel model, boolean isSelected, boolean isValue) {
+    protected void setBackgroundReadable(String key, HistoryBrowserModel.TagTableModel model, boolean isSelected, boolean hasFocus, boolean isValue) {
         Color bgColor = UIManager.getColor("Table.background");
         if (!model.hasTag(key) && model.isCurrentPointInTime()
                 || !model.oppositeHasTag(key) && model.isReferencePointInTime()) {
@@ -37,7 +44,11 @@ public class TagTableCellRenderer extends JLabel implements TableCellRenderer {
             bgColor = TwoColumnDiff.Item.DiffItemType.CHANGED.getColor();
         }
         if (isSelected) {
-            bgColor = BGCOLOR_SELECTED;
+            if (hasFocus) {
+                bgColor = BGCOLOR_SELECTED_FOCUS;
+            } else {
+                bgColor = BGCOLOR_SELECTED;
+            }
         }
 
         GuiHelper.setBackgroundReadable(this, bgColor);
@@ -53,22 +64,24 @@ public class TagTableCellRenderer extends JLabel implements TableCellRenderer {
         String key = (String) value;
         HistoryBrowserModel.TagTableModel model = getTagTableModel(table);
 
-        switch(column) {
-        case 0:
-            // the name column
-            setText(model.hasTag(key) ? key : "");
-            setToolTipText(getText());
-            setBackgroundReadable(key, model, isSelected, false);
-            break;
-        case 1:
-            // the value column
-            setText(model.hasTag(key) ? model.getValue(key) : "");
-            setToolTipText(getText());
-            setBackgroundReadable(key, model, isSelected, true);
-            break;
-        default: // Do nothing
+        String text = "";
+        if (model.hasTag(key)) {
+            switch(column) {
+            case TagTableColumnModel.COLUMN_KEY:
+                // the name column
+                text = key;
+                break;
+            case TagTableColumnModel.COLUMN_VALUE:
+                // the value column
+                text = model.getValue(key);
+                break;
+            default: // Do nothing
+            }
         }
 
+        setText(text);
+        setToolTipText(text);
+        setBackgroundReadable(key, model, isSelected, table.hasFocus(), column == TagTableColumnModel.COLUMN_VALUE);
         return this;
     }
 
diff --git a/src/org/openstreetmap/josm/gui/history/TagTableColumnModel.java b/src/org/openstreetmap/josm/gui/history/TagTableColumnModel.java
index 0c8eb16..3289439 100644
--- a/src/org/openstreetmap/josm/gui/history/TagTableColumnModel.java
+++ b/src/org/openstreetmap/josm/gui/history/TagTableColumnModel.java
@@ -11,6 +11,8 @@ import javax.swing.table.TableColumn;
  * @since 1709
  */
 public class TagTableColumnModel extends DefaultTableColumnModel {
+    protected static final int COLUMN_KEY = 0;
+    protected static final int COLUMN_VALUE = 1;
 
     /**
      * Constructs a new {@code TagTableColumnModel}.
