Index: trunk/src/org/openstreetmap/josm/gui/history/HistoryViewerPanel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/history/HistoryViewerPanel.java	(revision 16608)
+++ trunk/src/org/openstreetmap/josm/gui/history/HistoryViewerPanel.java	(revision 16609)
@@ -5,4 +5,6 @@
 import java.awt.Insets;
 import java.awt.event.ActionEvent;
+import java.util.function.BiPredicate;
+import java.util.stream.IntStream;
 
 import javax.swing.AbstractAction;
@@ -10,4 +12,5 @@
 import javax.swing.JScrollPane;
 import javax.swing.JTable;
+import javax.swing.ListSelectionModel;
 
 import org.openstreetmap.josm.actions.AutoScaleAction;
@@ -94,4 +97,22 @@
     }
 
+    /**
+     * Enables semantic highlighting for the {@link org.openstreetmap.josm.data.StructUtils.SerializeOptions}
+     * @param thisSelectionModel selection model
+     * @param thisModel table model (corresponding to the selection model)
+     * @param otherModel table model for the other point in time
+     * @param isSemanticallyEquivalent predicate to determine whether the items should be highlighted
+     */
+    protected void enableSemanticSelectionSynchronization(ListSelectionModel thisSelectionModel,
+                                                          DiffTableModel thisModel, DiffTableModel otherModel,
+                                                          BiPredicate<TwoColumnDiff.Item, TwoColumnDiff.Item> isSemanticallyEquivalent) {
+        selectionSynchronizer.setSelectionIndexMapper((selection, sourceSelectionModel) -> {
+            DiffTableModel sourceModel = sourceSelectionModel == thisSelectionModel ? thisModel : otherModel;
+            DiffTableModel destinationModel = sourceSelectionModel == thisSelectionModel ? otherModel : thisModel;
+            return IntStream.range(0, destinationModel.getRowCount())
+                    .filter(i -> isSemanticallyEquivalent.test(sourceModel.getValueAt(selection, 0), destinationModel.getValueAt(i, 0)));
+        });
+    }
+
     static class ListPopupMenu extends JPopupMenu {
         private final ZoomToObjectAction zoomToObjectAction;
Index: trunk/src/org/openstreetmap/josm/gui/history/NodeListViewer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/history/NodeListViewer.java	(revision 16608)
+++ trunk/src/org/openstreetmap/josm/gui/history/NodeListViewer.java	(revision 16609)
@@ -5,4 +5,5 @@
 
 import java.awt.Point;
+import java.util.Objects;
 
 import javax.swing.JTable;
@@ -50,5 +51,12 @@
             return primitiveIdAtRow(tableModel, row);
         }));
+        enableSemanticSelectionSynchronization(table.getSelectionModel(),
+                tableModel, model.getNodeListTableModel(pointInTimeType.opposite()),
+                this::isSemanticallyEquivalent);
         return table;
+    }
+
+    private boolean isSemanticallyEquivalent(TwoColumnDiff.Item o1, TwoColumnDiff.Item o2) {
+        return o1.value != null && Objects.equals(o1.value, o2.value); //compare node IDs
     }
 
Index: trunk/src/org/openstreetmap/josm/gui/history/RelationMemberListViewer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/history/RelationMemberListViewer.java	(revision 16608)
+++ trunk/src/org/openstreetmap/josm/gui/history/RelationMemberListViewer.java	(revision 16609)
@@ -36,4 +36,7 @@
         table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
         selectionSynchronizer.participateInSynchronizedSelection(table.getSelectionModel());
+        enableSemanticSelectionSynchronization(table.getSelectionModel(),
+                tableModel, model.getRelationMemberTableModel(pointInTimeType.opposite()),
+                this::isSemanticallyEquivalent);
         table.getTableHeader().setReorderingAllowed(false);
         table.addMouseListener(new InternalPopupMenuLauncher());
@@ -47,4 +50,12 @@
         }));
         return table;
+    }
+
+    private boolean isSemanticallyEquivalent(TwoColumnDiff.Item o1, TwoColumnDiff.Item o2) {
+        RelationMemberData rm1 = (RelationMemberData) o1.value;
+        RelationMemberData rm2 = (RelationMemberData) o2.value;
+        return rm1 != null && rm2 != null
+                && rm1.getMemberId() == rm2.getMemberId()
+                && rm1.getMemberType() == rm2.getMemberType();
     }
 
Index: trunk/src/org/openstreetmap/josm/gui/history/SelectionSynchronizer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/history/SelectionSynchronizer.java	(revision 16608)
+++ trunk/src/org/openstreetmap/josm/gui/history/SelectionSynchronizer.java	(revision 16609)
@@ -4,7 +4,9 @@
 import java.util.Arrays;
 import java.util.HashSet;
+import java.util.Objects;
 import java.util.Set;
+import java.util.function.BiFunction;
+import java.util.stream.IntStream;
 
-import javax.swing.DefaultListSelectionModel;
 import javax.swing.ListSelectionModel;
 import javax.swing.event.ListSelectionEvent;
@@ -23,4 +25,5 @@
     private final Set<ListSelectionModel> participants;
     private boolean preventRecursion;
+    private BiFunction<Integer, ListSelectionModel, IntStream> selectionIndexMapper = (i, model) -> IntStream.of(i);
 
     /**
@@ -47,4 +50,8 @@
     }
 
+    void setSelectionIndexMapper(BiFunction<Integer, ListSelectionModel, IntStream> selectionIndexMapper) {
+        this.selectionIndexMapper = Objects.requireNonNull(selectionIndexMapper);
+    }
+
     @Override
     public void valueChanged(ListSelectionEvent e) {
@@ -53,11 +60,12 @@
         }
         preventRecursion = true;
-        DefaultListSelectionModel referenceModel = (DefaultListSelectionModel) e.getSource();
+        ListSelectionModel referenceModel = (ListSelectionModel) e.getSource();
         int[] selectedIndices = TableHelper.getSelectedIndices(referenceModel);
         for (ListSelectionModel model : participants) {
-            if (model == e.getSource()) {
+            if (model == referenceModel) {
                 continue;
             }
-            TableHelper.setSelectedIndices(model, Arrays.stream(selectedIndices));
+            TableHelper.setSelectedIndices(model,
+                    Arrays.stream(selectedIndices).flatMap(i -> selectionIndexMapper.apply(i, referenceModel)));
         }
         preventRecursion = false;
