Index: /trunk/src/org/openstreetmap/josm/gui/history/DiffTableModel.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/history/DiffTableModel.java	(revision 5626)
+++ /trunk/src/org/openstreetmap/josm/gui/history/DiffTableModel.java	(revision 5627)
@@ -6,4 +6,6 @@
 
 import javax.swing.table.AbstractTableModel;
+
+import org.openstreetmap.josm.gui.history.TwoColumnDiff.Item.DiffItemType;
 
 /**
@@ -39,3 +41,11 @@
         return rows.get(rowIndex);
     }
+
+    public int getFirstChange() {
+        for (int i=0; i<rows.size(); i++) {
+            if (rows.get(i).state != DiffItemType.SAME)
+                return i;
+        }
+        return -1;
+    }
 }
Index: /trunk/src/org/openstreetmap/josm/gui/history/HistoryBrowserModel.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/history/HistoryBrowserModel.java	(revision 5626)
+++ /trunk/src/org/openstreetmap/josm/gui/history/HistoryBrowserModel.java	(revision 5627)
@@ -42,4 +42,5 @@
 import org.openstreetmap.josm.gui.MapView;
 import org.openstreetmap.josm.gui.MapView.LayerChangeListener;
+import org.openstreetmap.josm.gui.history.TwoColumnDiff.Item.DiffItemType;
 import org.openstreetmap.josm.gui.layer.Layer;
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
@@ -86,6 +87,6 @@
     private TagTableModel currentTagTableModel;
     private TagTableModel referenceTagTableModel;
-    private RelationMemberTableModel currentRelationMemberTableModel;
-    private RelationMemberTableModel referenceRelationMemberTableModel;
+    private DiffTableModel currentRelationMemberTableModel;
+    private DiffTableModel referenceRelationMemberTableModel;
     private DiffTableModel referenceNodeListTableModel;
     private DiffTableModel currentNodeListTableModel;
@@ -100,6 +101,6 @@
         referenceNodeListTableModel = new DiffTableModel();
         currentNodeListTableModel = new DiffTableModel();
-        currentRelationMemberTableModel = new RelationMemberTableModel(PointInTimeType.CURRENT_POINT_IN_TIME);
-        referenceRelationMemberTableModel = new RelationMemberTableModel(PointInTimeType.REFERENCE_POINT_IN_TIME);
+        currentRelationMemberTableModel = new DiffTableModel();
+        referenceRelationMemberTableModel = new DiffTableModel();
 
         if (getEditLayer() != null) {
@@ -208,4 +209,5 @@
     protected void fireModelChange() {
         initNodeListTableModels();
+        initMemberListTableModels();
         setChanged();
         notifyObservers();
@@ -247,4 +249,14 @@
 
     protected void initMemberListTableModels() {
+        if(current.getType() != OsmPrimitiveType.RELATION || reference.getType() != OsmPrimitiveType.RELATION)
+            return;
+
+        TwoColumnDiff diff = new TwoColumnDiff(
+                ((HistoryRelation)reference).getMembers().toArray(),
+                ((HistoryRelation)current).getMembers().toArray());
+
+        referenceRelationMemberTableModel.setRows(diff.referenceDiff);
+        currentRelationMemberTableModel.setRows(diff.currentDiff);
+
         currentRelationMemberTableModel.fireTableDataChanged();
         referenceRelationMemberTableModel.fireTableDataChanged();
@@ -280,5 +292,5 @@
     }
 
-    public RelationMemberTableModel getRelationMemberTableModel(PointInTimeType pointInTimeType) throws IllegalArgumentException {
+    public DiffTableModel getRelationMemberTableModel(PointInTimeType pointInTimeType) throws IllegalArgumentException {
         CheckParameterUtil.ensureParameterNotNull(pointInTimeType, "pointInTimeType");
         if (pointInTimeType.equals(PointInTimeType.CURRENT_POINT_IN_TIME))
@@ -429,18 +441,18 @@
                 return isCurrentPointInTime(row);
             case 3: {
-                    HistoryOsmPrimitive p = getPrimitive(row);
-                    if (p != null && p.getTimestamp() != null)
-                        return DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT).format(p.getTimestamp());
-                    return null;
+                HistoryOsmPrimitive p = getPrimitive(row);
+                if (p != null && p.getTimestamp() != null)
+                    return DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT).format(p.getTimestamp());
+                return null;
+            }
+            case 4: {
+                HistoryOsmPrimitive p = getPrimitive(row);
+                if (p != null) {
+                    User user = p.getUser();
+                    if (user != null)
+                        return "<html>" + XmlWriter.encode(user.getName(), true) + " <font color=gray>(" + user.getId() + ")</font></html>";
                 }
-            case 4: {
-                    HistoryOsmPrimitive p = getPrimitive(row);
-                    if (p != null) {
-                        User user = p.getUser();
-                        if (user != null)
-                            return "<html>" + XmlWriter.encode(user.getName(), true) + " <font color=gray>(" + user.getId() + ")</font></html>";
-                    }
-                    return null;
-                }
+                return null;
+            }
             }
             return null;
@@ -635,106 +647,4 @@
     }
 
-    /**
-     * The table model for the relation members of the version at {@link PointInTimeType#REFERENCE_POINT_IN_TIME}
-     * or {@link PointInTimeType#CURRENT_POINT_IN_TIME}
-     *
-     */
-
-    public class RelationMemberTableModel extends AbstractTableModel {
-
-        private PointInTimeType pointInTimeType;
-
-        private RelationMemberTableModel(PointInTimeType pointInTimeType) {
-            this.pointInTimeType = pointInTimeType;
-        }
-
-        @Override
-        public int getRowCount() {
-            // Match the size of the opposite table so comparison is less confusing.
-            // (scroll bars lines up properly, etc.)
-            int n = 0;
-            if (current != null && current.getType().equals(OsmPrimitiveType.RELATION)) {
-                n = ((HistoryRelation)current).getNumMembers();
-            }
-            if (reference != null && reference.getType().equals(OsmPrimitiveType.RELATION)) {
-                n = Math.max(n,((HistoryRelation)reference).getNumMembers());
-            }
-            return n;
-        }
-
-        protected HistoryRelation getRelation() {
-            if (pointInTimeType.equals(PointInTimeType.CURRENT_POINT_IN_TIME)) {
-                if (! current.getType().equals(OsmPrimitiveType.RELATION))
-                    return null;
-                return (HistoryRelation)current;
-            }
-            if (pointInTimeType.equals(PointInTimeType.REFERENCE_POINT_IN_TIME)) {
-                if (! reference.getType().equals(OsmPrimitiveType.RELATION))
-                    return null;
-                return (HistoryRelation)reference;
-            }
-
-            // should not happen
-            return null;
-        }
-
-        protected HistoryRelation getOppositeRelation() {
-            PointInTimeType opposite = pointInTimeType.opposite();
-            if (opposite.equals(PointInTimeType.CURRENT_POINT_IN_TIME)) {
-                if (! current.getType().equals(OsmPrimitiveType.RELATION))
-                    return null;
-                return (HistoryRelation)current;
-            }
-            if (opposite.equals(PointInTimeType.REFERENCE_POINT_IN_TIME)) {
-                if (! reference.getType().equals(OsmPrimitiveType.RELATION))
-                    return null;
-                return (HistoryRelation)reference;
-            }
-
-            // should not happen
-            return null;
-        }
-
-        @Override
-        public Object getValueAt(int row, int column) {
-            HistoryRelation relation = getRelation();
-            if (relation == null)
-                return null;
-            if (row >= relation.getNumMembers()) // see getRowCount
-                return null;
-            return relation.getMembers().get(row);
-        }
-
-        @Override
-        public boolean isCellEditable(int row, int column) {
-            return false;
-        }
-
-        public boolean isSameInOppositeWay(int row) {
-            HistoryRelation thisRelation = getRelation();
-            HistoryRelation oppositeRelation = getOppositeRelation();
-            if (thisRelation == null || oppositeRelation == null)
-                return false;
-            if (row >= oppositeRelation.getNumMembers())
-                return false;
-            return
-            thisRelation.getMembers().get(row).getMemberId() == oppositeRelation.getMembers().get(row).getMemberId()
-            &&  thisRelation.getMembers().get(row).getRole().equals(oppositeRelation.getMembers().get(row).getRole());
-        }
-
-        public boolean isInOppositeWay(int row) {
-            HistoryRelation thisRelation = getRelation();
-            HistoryRelation oppositeRelation = getOppositeRelation();
-            if (thisRelation == null || oppositeRelation == null)
-                return false;
-            return oppositeRelation.getMembers().contains(thisRelation.getMembers().get(row));
-        }
-
-        @Override
-        public int getColumnCount() {
-            return 1;
-        }
-    }
-
     protected void setLatest(HistoryOsmPrimitive latest) {
         if (latest == null) {
Index: /trunk/src/org/openstreetmap/josm/gui/history/NodeListTableCellRenderer.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/history/NodeListTableCellRenderer.java	(revision 5626)
+++ /trunk/src/org/openstreetmap/josm/gui/history/NodeListTableCellRenderer.java	(revision 5627)
@@ -12,12 +12,9 @@
 import javax.swing.table.TableCellRenderer;
 
+import org.openstreetmap.josm.gui.history.TwoColumnDiff.Item.DiffItemType;
 import org.openstreetmap.josm.tools.ImageProvider;
 
 public class NodeListTableCellRenderer extends JLabel implements TableCellRenderer {
 
-    public final static Color BGCOLOR_EMPTY_ROW = new Color(234,234,234);
-    public final static Color BGCOLOR_DELETED = new Color(255,197,197);
-    public final static Color BGCOLOR_INSERTED = new Color(0xDD, 0xFF, 0xDD);
-    public final static Color BGCOLOR_CHANGED = new Color(255,234,213);
     public final static Color BGCOLOR_SELECTED = new Color(143,170,255);
 
@@ -37,21 +34,8 @@
             text = tr("Node {0}", item.value.toString());
         }
-        switch(item.state) {
-        case TwoColumnDiff.Item.EMPTY:
+        bgColor = item.state.getColor();
+        if (item.state == DiffItemType.EMPTY) {
             text = "";
-            bgColor = BGCOLOR_EMPTY_ROW;
             setIcon(null);
-            break;
-        case TwoColumnDiff.Item.CHANGED:
-            bgColor = BGCOLOR_CHANGED;
-            break;
-        case TwoColumnDiff.Item.INSERTED:
-            bgColor = BGCOLOR_INSERTED;
-            break;
-        case TwoColumnDiff.Item.DELETED:
-            bgColor = BGCOLOR_DELETED;
-            break;
-        default:
-            bgColor = BGCOLOR_EMPTY_ROW;
         }
         if (isSelected) {
Index: /trunk/src/org/openstreetmap/josm/gui/history/RelationMemberListTableCellRenderer.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/history/RelationMemberListTableCellRenderer.java	(revision 5626)
+++ /trunk/src/org/openstreetmap/josm/gui/history/RelationMemberListTableCellRenderer.java	(revision 5627)
@@ -15,4 +15,5 @@
 import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
 import org.openstreetmap.josm.data.osm.RelationMemberData;
+import org.openstreetmap.josm.gui.history.TwoColumnDiff.Item;
 import org.openstreetmap.josm.tools.ImageProvider;
 
@@ -47,19 +48,9 @@
     }
 
-    protected void renderRole( HistoryBrowserModel.RelationMemberTableModel model, RelationMemberData member, int row, boolean isSelected) {
+    protected void renderRole(Item diffItem, int row, boolean isSelected) {
         String text = "";
-        Color bgColor = Color.WHITE;
-        if (member == null) {
-            bgColor = BGCOLOR_EMPTY_ROW;
-        } else {
-            text = member.getRole();
-            if (model.isSameInOppositeWay(row)) {
-                bgColor = Color.WHITE;
-            } else if (model.isInOppositeWay(row)) {
-                bgColor = BGCOLOR_IN_OPPOSITE;
-            } else {
-                bgColor = BGCOLOR_NOT_IN_OPPOSITE;
-            }
-        }
+        Color bgColor = diffItem.state.getColor();
+        RelationMemberData member = (RelationMemberData) diffItem.value;
+        text = member == null?"":member.getRole();
         setText(text);
         setToolTipText(text);
@@ -67,22 +58,14 @@
     }
 
-    protected void renderPrimitive( HistoryBrowserModel.RelationMemberTableModel model, RelationMemberData member, int row, boolean isSelected) {
+    protected void renderPrimitive(Item diffItem, int row, boolean isSelected) {
         String text = "";
-        Color bgColor = Color.WHITE;
-        if (member == null) {
-            bgColor = BGCOLOR_EMPTY_ROW;
-        } else {
-            text = "";
+        Color bgColor = diffItem.state.getColor();
+        RelationMemberData member = (RelationMemberData) diffItem.value;
+        text = "";
+        if (member != null) {
             switch(member.getMemberType()) {
             case NODE: text = tr("Node {0}", member.getMemberId()); break;
             case WAY: text = tr("Way {0}", member.getMemberId()); break;
             case RELATION: text = tr("Relation {0}", member.getMemberId()); break;
-            }
-            if (model.isSameInOppositeWay(row)) {
-                bgColor = Color.WHITE;
-            } else if (model.isInOppositeWay(row)) {
-                bgColor = BGCOLOR_IN_OPPOSITE;
-            } else {
-                bgColor = BGCOLOR_NOT_IN_OPPOSITE;
             }
         }
@@ -96,13 +79,12 @@
             int row, int column) {
 
-        HistoryBrowserModel.RelationMemberTableModel model = gteRelationMemberTableModel(table);
-        RelationMemberData member = (RelationMemberData)value;
-        renderIcon(member);
+        Item member = (TwoColumnDiff.Item)value;
+        renderIcon((RelationMemberData) member.value);
         switch(column) {
         case 0:
-            renderRole(model, member, row, isSelected);
+            renderRole(member, row, isSelected);
             break;
         case 1:
-            renderPrimitive(model, member, row, isSelected);
+            renderPrimitive(member, row, isSelected);
             break;
         }
@@ -111,6 +93,6 @@
     }
 
-    protected HistoryBrowserModel.RelationMemberTableModel gteRelationMemberTableModel(JTable table) {
-        return (HistoryBrowserModel.RelationMemberTableModel) table.getModel();
+    protected DiffTableModel getRelationMemberTableModel(JTable table) {
+        return (DiffTableModel) table.getModel();
     }
 }
Index: /trunk/src/org/openstreetmap/josm/gui/history/RelationMemberListViewer.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/history/RelationMemberListViewer.java	(revision 5626)
+++ /trunk/src/org/openstreetmap/josm/gui/history/RelationMemberListViewer.java	(revision 5627)
@@ -5,4 +5,5 @@
 import java.awt.GridBagLayout;
 import java.awt.Insets;
+import java.awt.Rectangle;
 
 import javax.swing.JPanel;
@@ -10,4 +11,8 @@
 import javax.swing.JTable;
 import javax.swing.ListSelectionModel;
+import javax.swing.event.TableModelEvent;
+import javax.swing.event.TableModelListener;
+
+import org.openstreetmap.josm.data.osm.history.History;
 /**
  * RelationMemberListViewer is a UI component which displays the  list of relation members of two
@@ -37,12 +42,27 @@
     }
 
+    protected class MemberModelChanged implements TableModelListener {
+        private final JTable table;
+
+        protected MemberModelChanged(JTable table) {
+            this.table = table;
+        }
+
+        @Override
+        public void tableChanged(TableModelEvent e) {
+            Rectangle rect = table.getCellRect(((DiffTableModel)e.getSource()).getFirstChange(), 0, true);
+            table.scrollRectToVisible(rect);
+        }
+    }
+
     protected JTable buildReferenceMemberListTable() {
         JTable table = new JTable(
                 model.getRelationMemberTableModel(PointInTimeType.REFERENCE_POINT_IN_TIME),
                 new RelationMemberTableColumnModel()
-        );
+                );
         table.setName("table.referencememberlisttable");
         table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
         selectionSynchronizer.participateInSynchronizedSelection(table.getSelectionModel());
+        table.getModel().addTableModelListener(new MemberModelChanged(table));
         return table;
     }
@@ -52,8 +72,9 @@
                 model.getRelationMemberTableModel(PointInTimeType.CURRENT_POINT_IN_TIME),
                 new RelationMemberTableColumnModel()
-        );
+                );
         table.setName("table.currentmemberlisttable");
         table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
         selectionSynchronizer.participateInSynchronizedSelection(table.getSelectionModel());
+        table.getModel().addTableModelListener(new MemberModelChanged(table));
         return table;
     }
Index: /trunk/src/org/openstreetmap/josm/gui/history/TwoColumnDiff.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/history/TwoColumnDiff.java	(revision 5626)
+++ /trunk/src/org/openstreetmap/josm/gui/history/TwoColumnDiff.java	(revision 5627)
@@ -3,6 +3,8 @@
 /// Feel free to move me somewhere else. Maybe a bit specific for josm.tools?
 
+import java.awt.Color;
 import java.util.ArrayList;
 
+import org.openstreetmap.josm.gui.history.TwoColumnDiff.Item.DiffItemType;
 import org.openstreetmap.josm.tools.Diff;
 
@@ -24,16 +26,25 @@
 class TwoColumnDiff {
     public static class Item {
-        public static final int INSERTED = 1;
-        public static final int DELETED = 2;
-        public static final int CHANGED = 3;
-        public static final int SAME = 4;
-        public static final int EMPTY = 5; // value should be null
-        public Item(int state, Object value) {
+
+        public enum DiffItemType {
+            INSERTED(new Color(0xDD, 0xFF, 0xDD)), DELETED(new Color(255,197,197)), CHANGED(new Color(255,234,213)),
+            SAME(new Color(234,234,234)), EMPTY(new Color(234,234,234));
+
+            private final Color color;
+            private DiffItemType(Color color) {
+                this.color = color;
+            }
+            public Color getColor() {
+                return color;
+            }
+        }
+
+        public Item(DiffItemType state, Object value) {
             this.state = state;
-            this.value = state == EMPTY ? null : value;
+            this.value = state == DiffItemType.EMPTY ? null : value;
         }
 
         public final Object value;
-        public final int state;
+        public final DiffItemType state;
     }
 
@@ -72,5 +83,5 @@
             while(ia < script.line0 && ib < script.line1){
                 // System.out.println(" "+a[ia] + "\t "+b[ib]);
-                Item cell = new Item(Item.SAME, a[ia]);
+                Item cell = new Item(DiffItemType.SAME, a[ia]);
                 referenceDiff.add(cell);
                 currentDiff.add(cell);
@@ -82,14 +93,14 @@
                 if(inserted > 0 && deleted > 0) {
                     // System.out.println("="+a[ia] + "\t="+b[ib]);
-                    referenceDiff.add(new Item(Item.CHANGED, a[ia++]));
-                    currentDiff.add(new Item(Item.CHANGED, b[ib++]));
+                    referenceDiff.add(new Item(DiffItemType.CHANGED, a[ia++]));
+                    currentDiff.add(new Item(DiffItemType.CHANGED, b[ib++]));
                 } else if(inserted > 0) {
                     // System.out.println("\t+" + b[ib]);
-                    referenceDiff.add(new Item(Item.EMPTY, null));
-                    currentDiff.add(new Item(Item.INSERTED, b[ib++]));
+                    referenceDiff.add(new Item(DiffItemType.EMPTY, null));
+                    currentDiff.add(new Item(DiffItemType.INSERTED, b[ib++]));
                 } else if(deleted > 0) {
                     // System.out.println("-"+a[ia]);
-                    referenceDiff.add(new Item(Item.DELETED, a[ia++]));
-                    currentDiff.add(new Item(Item.EMPTY, null));
+                    referenceDiff.add(new Item(DiffItemType.DELETED, a[ia++]));
+                    currentDiff.add(new Item(DiffItemType.EMPTY, null));
                 }
                 inserted--;
@@ -100,6 +111,6 @@
         while(ia < a.length && ib < b.length) {
             // System.out.println((ia < a.length ? " "+a[ia]+"\t" : "\t") + (ib < b.length ? " "+b[ib] : ""));
-            referenceDiff.add(new Item(Item.SAME, a[ia++]));
-            currentDiff.add(new Item(Item.SAME, b[ib++]));
+            referenceDiff.add(new Item(DiffItemType.SAME, a[ia++]));
+            currentDiff.add(new Item(DiffItemType.SAME, b[ib++]));
         }
     }
