Index: trunk/src/org/openstreetmap/josm/data/osm/history/History.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/history/History.java	(revision 2241)
+++ trunk/src/org/openstreetmap/josm/data/osm/history/History.java	(revision 2242)
@@ -10,4 +10,6 @@
 import java.util.List;
 import java.util.NoSuchElementException;
+
+import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
 
 public class History{
@@ -195,3 +197,9 @@
         return versions.isEmpty();
     }
+
+    public OsmPrimitiveType getType() {
+        if (isEmpty())
+            throw new NoSuchElementException(tr("No type found. History is empty."));
+        return versions.get(0).getType();
+    }
 }
Index: trunk/src/org/openstreetmap/josm/data/osm/history/HistoryNode.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/history/HistoryNode.java	(revision 2241)
+++ trunk/src/org/openstreetmap/josm/data/osm/history/HistoryNode.java	(revision 2242)
@@ -5,4 +5,5 @@
 
 import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
+import org.openstreetmap.josm.data.coor.LatLon;
 
 
@@ -13,6 +14,9 @@
  */
 public class HistoryNode extends HistoryOsmPrimitive {
-    public HistoryNode(long id, long version, boolean visible, String user, long uid, long changesetId, Date timestamp) {
+    private LatLon coor;
+    public HistoryNode(long id, long version, boolean visible, String user, long uid, long changesetId, Date timestamp,
+    double lat, double lon) {
         super(id, version, visible, user, uid, changesetId, timestamp);
+        coor = new LatLon(lat, lon);
     }
 
@@ -21,3 +25,7 @@
         return OsmPrimitiveType.NODE;
     }
+
+    public LatLon getCoordinate() {
+        return coor;
+    }
 }
Index: trunk/src/org/openstreetmap/josm/data/osm/history/HistoryOsmPrimitive.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/history/HistoryOsmPrimitive.java	(revision 2241)
+++ trunk/src/org/openstreetmap/josm/data/osm/history/HistoryOsmPrimitive.java	(revision 2242)
@@ -39,5 +39,5 @@
     /**
      * constructor
-     * 
+     *
      * @param id the id (>0 required)
      * @param version the version (> 0 required)
@@ -47,5 +47,5 @@
      * @param changesetId the changeset id (> 0 required)
      * @param timestamp the timestamp (! null required)
-     * 
+     *
      * @throws IllegalArgumentException thrown if preconditions are violated
      */
@@ -53,5 +53,6 @@
         ensurePositiveLong(id, "id");
         ensurePositiveLong(version, "version");
-        ensurePositiveLong(uid, "uid");
+        if(uid != -1) /* allow -1 for anonymous users */
+            ensurePositiveLong(uid, "uid");
         ensurePositiveLong(changesetId, "changesetId");
         ensureNotNull(user, "user");
Index: trunk/src/org/openstreetmap/josm/gui/history/CoordinateTableCellRenderer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/history/CoordinateTableCellRenderer.java	(revision 2242)
+++ trunk/src/org/openstreetmap/josm/gui/history/CoordinateTableCellRenderer.java	(revision 2242)
@@ -0,0 +1,53 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.history;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.Color;
+import java.awt.Component;
+
+import javax.swing.JLabel;
+import javax.swing.JTable;
+import javax.swing.table.TableCellRenderer;
+
+/**
+ * The {@see TableCellRenderer} for a list of tagsin {@see HistoryBrower}
+ *
+ */
+public class CoordinateTableCellRenderer extends JLabel implements TableCellRenderer {
+
+    public final static Color BGCOLOR_SELECTED = new Color(143,170,255);
+    public final static Color BGCOLOR_DIFFERENCE = new Color(255,197,197);
+
+    public CoordinateTableCellRenderer() {
+        setOpaque(true);
+        setForeground(Color.BLACK);
+    }
+
+    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
+            int row, int column) {
+
+        String key = (String)value;
+        HistoryBrowserModel.CoordinateTableModel model = getCoordinateTableModel(table);
+
+        String text;
+        Color bgColor = Color.WHITE;
+        if(column == 0) // the name column
+            text = row == 0 ? tr("latitude") : tr("longitude");
+        else // the value column
+        {
+            text = (String) model.getValueAt(row, column);
+            if (!model.hasSameValueAsOpposite(row))
+                bgColor = BGCOLOR_DIFFERENCE;
+        }
+        setText(text);
+        setToolTipText(text);
+        setBackground(isSelected ? BGCOLOR_SELECTED : bgColor);
+
+        return this;
+    }
+
+    protected HistoryBrowserModel.CoordinateTableModel getCoordinateTableModel(JTable table) {
+        return (HistoryBrowserModel.CoordinateTableModel) table.getModel();
+    }
+}
Index: trunk/src/org/openstreetmap/josm/gui/history/CoordinateTableColumnModel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/history/CoordinateTableColumnModel.java	(revision 2242)
+++ trunk/src/org/openstreetmap/josm/gui/history/CoordinateTableColumnModel.java	(revision 2242)
@@ -0,0 +1,36 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.history;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import javax.swing.table.DefaultTableColumnModel;
+import javax.swing.table.TableColumn;
+
+/**
+ * The {@see TableColumnModel} for the table with the list of tags
+ *
+ */
+public class CoordinateTableColumnModel extends DefaultTableColumnModel{
+    protected void createColumns() {
+        TableColumn col = null;
+
+        CoordinateTableCellRenderer renderer = new CoordinateTableCellRenderer();
+
+        // column 0 - Name
+        col = new TableColumn(0);
+        col.setHeaderValue(tr("Name"));
+        col.setCellRenderer(renderer);
+        addColumn(col);
+
+        // column 1 - Value
+        col = new TableColumn(1);
+        col.setHeaderValue(tr("Value"));
+        col.setCellRenderer(renderer);
+        addColumn(col);
+
+    }
+
+    public CoordinateTableColumnModel() {
+        createColumns();
+    }
+}
Index: trunk/src/org/openstreetmap/josm/gui/history/CoordinateViewer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/history/CoordinateViewer.java	(revision 2242)
+++ trunk/src/org/openstreetmap/josm/gui/history/CoordinateViewer.java	(revision 2242)
@@ -0,0 +1,145 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.history;
+
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.ListSelectionModel;
+
+/**
+ * CoordinateViewer is a UI component which displays the list of coordinates of two
+ * version of a {@see OsmPrimitive} in a {@see History}.
+ *
+ * <ul>
+ *   <li>on the left, it displays the list of coordinates for the version at {@see PointInTimeType#REFERENCE_POINT_IN_TIME}</li>
+ *   <li>on the right, it displays the list of coordinates for the version at {@see PointInTimeType#CURRENT_POINT_IN_TIME}</li>
+ * </ul>
+ *
+ */
+public class CoordinateViewer extends JPanel{
+
+    private HistoryBrowserModel model;
+    private VersionInfoPanel referenceInfoPanel;
+    private VersionInfoPanel currentInfoPanel;
+    private AdjustmentSynchronizer adjustmentSynchronizer;
+    private SelectionSynchronizer selectionSynchronizer;
+
+    protected JScrollPane embeddInScrollPane(JTable table) {
+        JScrollPane pane = new JScrollPane(table);
+        pane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
+        pane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
+        adjustmentSynchronizer.participateInSynchronizedScrolling(pane.getVerticalScrollBar());
+        return pane;
+    }
+
+    protected JTable buildReferenceCoordinateTable() {
+        JTable table = new JTable(
+                model.getCoordinateTableModel(PointInTimeType.REFERENCE_POINT_IN_TIME),
+                new CoordinateTableColumnModel()
+        );
+        table.setName("table.referencecoordinatetable");
+        table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+        selectionSynchronizer.participateInSynchronizedSelection(table.getSelectionModel());
+        return table;
+    }
+
+    protected JTable buildCurrentCoordinateTable() {
+        JTable table = new JTable(
+                model.getCoordinateTableModel(PointInTimeType.CURRENT_POINT_IN_TIME),
+                new CoordinateTableColumnModel()
+        );
+        table.setName("table.currentcoordinatetable");
+        table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+        selectionSynchronizer.participateInSynchronizedSelection(table.getSelectionModel());
+        return table;
+    }
+
+    protected void build() {
+        setLayout(new GridBagLayout());
+        GridBagConstraints gc = new GridBagConstraints();
+
+        // ---------------------------
+        gc.gridx = 0;
+        gc.gridy = 0;
+        gc.gridwidth = 1;
+        gc.gridheight = 1;
+        gc.weightx = 0.5;
+        gc.weighty = 0.0;
+        gc.insets = new Insets(5,5,5,0);
+        gc.fill = GridBagConstraints.HORIZONTAL;
+        gc.anchor = GridBagConstraints.FIRST_LINE_START;
+        referenceInfoPanel = new VersionInfoPanel(model, PointInTimeType.REFERENCE_POINT_IN_TIME);
+        add(referenceInfoPanel,gc);
+
+        gc.gridx = 1;
+        gc.gridy = 0;
+        gc.gridwidth = 1;
+        gc.gridheight = 1;
+        gc.fill = GridBagConstraints.HORIZONTAL;
+        gc.weightx = 0.5;
+        gc.weighty = 0.0;
+        gc.anchor = GridBagConstraints.FIRST_LINE_START;
+        currentInfoPanel = new VersionInfoPanel(model, PointInTimeType.CURRENT_POINT_IN_TIME);
+        add(currentInfoPanel,gc);
+
+        adjustmentSynchronizer = new AdjustmentSynchronizer();
+        selectionSynchronizer = new SelectionSynchronizer();
+
+        // ---------------------------
+        gc.gridx = 0;
+        gc.gridy = 1;
+        gc.gridwidth = 1;
+        gc.gridheight = 1;
+        gc.weightx = 0.5;
+        gc.weighty = 1.0;
+        gc.fill = GridBagConstraints.BOTH;
+        gc.anchor = GridBagConstraints.NORTHWEST;
+        add(embeddInScrollPane(buildReferenceCoordinateTable()),gc);
+
+        gc.gridx = 1;
+        gc.gridy = 1;
+        gc.gridwidth = 1;
+        gc.gridheight = 1;
+        gc.weightx = 0.5;
+        gc.weighty = 1.0;
+        gc.fill = GridBagConstraints.BOTH;
+        gc.anchor = GridBagConstraints.NORTHWEST;
+        add(embeddInScrollPane(buildCurrentCoordinateTable()),gc);
+    }
+
+    public CoordinateViewer(HistoryBrowserModel model) {
+        setModel(model);
+        build();
+    }
+
+    protected void unregisterAsObserver(HistoryBrowserModel model) {
+        if (currentInfoPanel != null) {
+            model.deleteObserver(currentInfoPanel);
+        }
+        if (referenceInfoPanel != null) {
+            model.deleteObserver(referenceInfoPanel);
+        }
+    }
+    protected void registerAsObserver(HistoryBrowserModel model) {
+        if (currentInfoPanel != null) {
+            model.addObserver(currentInfoPanel);
+        }
+        if (referenceInfoPanel != null) {
+            model.addObserver(referenceInfoPanel);
+        }
+    }
+
+    public void setModel(HistoryBrowserModel model) {
+        if (this.model != null) {
+            unregisterAsObserver(model);
+        }
+        this.model = model;
+        if (this.model != null) {
+            registerAsObserver(model);
+        }
+    }
+}
Index: trunk/src/org/openstreetmap/josm/gui/history/HistoryBrowser.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/history/HistoryBrowser.java	(revision 2241)
+++ trunk/src/org/openstreetmap/josm/gui/history/HistoryBrowser.java	(revision 2242)
@@ -14,8 +14,9 @@
 
 import org.openstreetmap.josm.data.osm.history.History;
+import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
 
 /**
  * HistoryBrowser is an UI component which displays history information about an {@see OsmPrimitive}.
- * 
+ *
  *
  */
@@ -24,8 +25,9 @@
     /** the model */
     private HistoryBrowserModel model;
+    private JTabbedPane dataPane;
 
     /**
      * embedds table in a {@see JScrollPane}
-     * 
+     *
      * @param table the table
      * @return the {@see JScrollPane} with the embedded table
@@ -40,5 +42,5 @@
     /**
      * creates the table which shows the list of versions
-     * 
+     *
      * @return  the panel with the version table
      */
@@ -55,21 +57,25 @@
      * creates the panel which shows information about two different versions
      * of the same {@see OsmPrimitive}.
-     * 
+     *
      * @return the panel
      */
+
     protected JPanel createVersionComparePanel() {
-        JTabbedPane pane = new JTabbedPane();
-        pane.add(new TagInfoViewer(model));
-        pane.setTitleAt(0, tr("Tags"));
+        dataPane = new JTabbedPane();
+        dataPane.add(new TagInfoViewer(model));
+        dataPane.setTitleAt(0, tr("Tags"));
 
-        pane.add(new NodeListViewer(model));
-        pane.setTitleAt(1, tr("Nodes"));
+        dataPane.add(new NodeListViewer(model));
+        dataPane.setTitleAt(1, tr("Nodes"));
 
-        pane.add(new RelationMemberListViewer(model));
-        pane.setTitleAt(2, tr("Members"));
+        dataPane.add(new RelationMemberListViewer(model));
+        dataPane.setTitleAt(2, tr("Members"));
+
+        dataPane.add(new CoordinateViewer(model));
+        dataPane.setTitleAt(3, tr("Coordinate"));
 
         JPanel pnl = new JPanel();
         pnl.setLayout(new BorderLayout());
-        pnl.add(pane, BorderLayout.CENTER);
+        pnl.add(dataPane, BorderLayout.CENTER);
         return pnl;
     }
@@ -116,14 +122,32 @@
     /**
      * populates the browser with the history of a specific {@see OsmPrimitive}
-     * 
+     *
      * @param history the history
      */
     public void populate(History history) {
         model.setHistory(history);
+        OsmPrimitiveType type = history.getType();
+        if(type != null)
+        {
+            if(type == OsmPrimitiveType.NODE)
+            {
+                dataPane.setEnabledAt(1, false);
+                dataPane.setEnabledAt(2, false);
+            }
+            else if(type == OsmPrimitiveType.WAY)
+            {
+                dataPane.setEnabledAt(2, false);
+                dataPane.setEnabledAt(3, false);
+            }
+            else
+            {
+                dataPane.setEnabledAt(3, false);
+            }
+        }
     }
 
     /**
      * replies the {@see History} currently displayed by this browser
-     * 
+     *
      * @return the current history
      */
Index: trunk/src/org/openstreetmap/josm/gui/history/HistoryBrowserModel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/history/HistoryBrowserModel.java	(revision 2241)
+++ trunk/src/org/openstreetmap/josm/gui/history/HistoryBrowserModel.java	(revision 2242)
@@ -12,6 +12,9 @@
 import javax.swing.table.DefaultTableModel;
 
+import org.openstreetmap.josm.data.coor.CoordinateFormat;
+import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
 import org.openstreetmap.josm.data.osm.history.History;
+import org.openstreetmap.josm.data.osm.history.HistoryNode;
 import org.openstreetmap.josm.data.osm.history.HistoryOsmPrimitive;
 import org.openstreetmap.josm.data.osm.history.HistoryRelation;
@@ -20,5 +23,5 @@
 /**
  * This is the model used by the history browser.
- * 
+ *
  * The state this model manages consists of the following elements:
  * <ul>
@@ -40,5 +43,5 @@
  *  members  of the two selected versions (if the current history provides information about a {@see Relation}</li>
  *  </ul>
- * 
+ *
  * @see HistoryBrowser
  */
@@ -59,4 +62,6 @@
     private RelationMemberTableModel currentRelationMemberTableModel;
     private RelationMemberTableModel referenceRelationMemberTableModel;
+    private CoordinateTableModel currentCoordinateTableModel;
+    private CoordinateTableModel referenceCoordinateTableModel;
 
     public HistoryBrowserModel() {
@@ -68,4 +73,6 @@
         currentRelationMemberTableModel = new RelationMemberTableModel(PointInTimeType.CURRENT_POINT_IN_TIME);
         referenceRelationMemberTableModel = new RelationMemberTableModel(PointInTimeType.REFERENCE_POINT_IN_TIME);
+        currentCoordinateTableModel = new CoordinateTableModel(PointInTimeType.CURRENT_POINT_IN_TIME);
+        referenceCoordinateTableModel = new CoordinateTableModel(PointInTimeType.REFERENCE_POINT_IN_TIME);
     }
 
@@ -85,7 +92,7 @@
     /**
      * sets the history to be managed by this model
-     * 
+     *
      * @param history the history
-     * 
+     *
      */
     public void setHistory(History history) {
@@ -109,5 +116,5 @@
      * Replies the table model to be used in a {@see JTable} which
      * shows the list of versions in this history.
-     * 
+     *
      * @return the table model
      */
@@ -121,17 +128,22 @@
     }
 
-    protected void initNodeListTabeModel() {
+    protected void initNodeListTabeModels() {
         currentNodeListTableModel.fireTableDataChanged();
         referenceNodeListTableModel.fireTableDataChanged();
     }
 
-    protected void initMemberListTableModel() {
+    protected void initMemberListTableModels() {
         currentRelationMemberTableModel.fireTableDataChanged();
         referenceRelationMemberTableModel.fireTableDataChanged();
     }
 
+    protected void initCoordinateTableModels() {
+        currentCoordinateTableModel.fireTableDataChanged();
+        referenceCoordinateTableModel.fireTableDataChanged();
+    }
+
     /**
      * replies the tag table model for the respective point in time
-     * 
+     *
      * @param pointInTimeType the type of the point in time (must not be null)
      * @return the tag table model
@@ -169,4 +181,16 @@
         else if (pointInTimeType.equals(PointInTimeType.REFERENCE_POINT_IN_TIME))
             return referenceRelationMemberTableModel;
+
+        // should not happen
+        return null;
+    }
+
+    public CoordinateTableModel getCoordinateTableModel(PointInTimeType pointInTimeType) throws IllegalArgumentException {
+        if (pointInTimeType == null)
+            throw new IllegalArgumentException(tr("Parameter ''{0}'' must not be null.", "pointInTimeType"));
+        if (pointInTimeType.equals(PointInTimeType.CURRENT_POINT_IN_TIME))
+            return currentCoordinateTableModel;
+        else if (pointInTimeType.equals(PointInTimeType.REFERENCE_POINT_IN_TIME))
+            return referenceCoordinateTableModel;
 
         // should not happen
@@ -187,6 +211,7 @@
         this.reference = reference;
         initTagTableModels();
-        initNodeListTabeModel();
-        initMemberListTableModel();
+        initNodeListTabeModels();
+        initMemberListTableModels();
+        initCoordinateTableModels();
         setChanged();
         notifyObservers();
@@ -205,6 +230,7 @@
         this.current = current;
         initTagTableModels();
-        initNodeListTabeModel();
-        initMemberListTableModel();
+        initNodeListTabeModels();
+        initMemberListTableModels();
+        initCoordinateTableModels();
         setChanged();
         notifyObservers();
@@ -213,5 +239,5 @@
     /**
      * Replies the history OSM primitive for the {@see PointInTimeType#CURRENT_POINT_IN_TIME}
-     * 
+     *
      * @return the history OSM primitive for the {@see PointInTimeType#CURRENT_POINT_IN_TIME} (may be null)
      */
@@ -222,5 +248,5 @@
     /**
      * Replies the history OSM primitive for the {@see PointInTimeType#REFERENCE_POINT_IN_TIME}
-     * 
+     *
      * @return the history OSM primitive for the {@see PointInTimeType#REFERENCE_POINT_IN_TIME} (may be null)
      */
@@ -231,5 +257,5 @@
     /**
      * replies the history OSM primitive for a given point in time
-     * 
+     *
      * @param type the type of the point in time (must not be null)
      * @return the respective primitive. Can be null.
@@ -306,5 +332,5 @@
      * The table model for the tags of the version at {@see PointInTimeType#REFERENCE_POINT_IN_TIME}
      * or {@see PointInTimeType#CURRENT_POINT_IN_TIME}
-     * 
+     *
      */
     public class TagTableModel extends DefaultTableModel {
@@ -401,5 +427,5 @@
      * The table model for the nodes of the version at {@see PointInTimeType#REFERENCE_POINT_IN_TIME}
      * or {@see PointInTimeType#CURRENT_POINT_IN_TIME}
-     * 
+     *
      */
     public class NodeListTableModel extends DefaultTableModel {
@@ -493,5 +519,5 @@
      * The table model for the relation members of the version at {@see PointInTimeType#REFERENCE_POINT_IN_TIME}
      * or {@see PointInTimeType#CURRENT_POINT_IN_TIME}
-     * 
+     *
      */
 
@@ -584,3 +610,67 @@
         }
     }
+
+    /**
+     * The table model for the coordinates of the version at {@see PointInTimeType#REFERENCE_POINT_IN_TIME}
+     * or {@see PointInTimeType#CURRENT_POINT_IN_TIME}
+     *
+     */
+    public class CoordinateTableModel extends DefaultTableModel {
+
+        private LatLon currentCoor = null;
+        private LatLon referenceCoor = null;
+        private PointInTimeType pointInTimeType;
+
+        protected CoordinateTableModel(PointInTimeType type) {
+            pointInTimeType = type;
+        }
+
+        @Override
+        public int getRowCount() {
+            if (current != null && current instanceof HistoryNode)
+                currentCoor = ((HistoryNode)current).getCoordinate();
+            else
+                return 0;
+            if (reference != null && reference instanceof HistoryNode)
+                referenceCoor = ((HistoryNode)reference).getCoordinate();
+            return 2;
+        }
+
+        @Override
+        public Object getValueAt(int row, int column) {
+            if(currentCoor == null)
+                return null;
+            else if (pointInTimeType.equals(PointInTimeType.CURRENT_POINT_IN_TIME))
+                return row == 0 ? currentCoor.latToString(CoordinateFormat.getDefaultFormat())
+                : currentCoor.lonToString(CoordinateFormat.getDefaultFormat());
+            else
+                return row == 0 ? referenceCoor.latToString(CoordinateFormat.getDefaultFormat())
+                : referenceCoor.lonToString(CoordinateFormat.getDefaultFormat());
+        }
+
+        @Override
+        public boolean isCellEditable(int row, int column) {
+            return false;
+        }
+
+        public boolean hasSameValueAsOpposite(int row) {
+            if(currentCoor == null)
+                return false;
+            else if(row == 0)
+                return currentCoor.lat() == referenceCoor.lat();
+            return currentCoor.lon() == referenceCoor.lon();
+        }
+
+        public PointInTimeType getPointInTimeType() {
+            return pointInTimeType;
+        }
+
+        public boolean isCurrentPointInTime() {
+            return pointInTimeType.equals(PointInTimeType.CURRENT_POINT_IN_TIME);
+        }
+
+        public boolean isReferencePointInTime() {
+            return pointInTimeType.equals(PointInTimeType.REFERENCE_POINT_IN_TIME);
+        }
+    }
 }
Index: trunk/src/org/openstreetmap/josm/gui/history/TagInfoViewer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/history/TagInfoViewer.java	(revision 2241)
+++ trunk/src/org/openstreetmap/josm/gui/history/TagInfoViewer.java	(revision 2242)
@@ -12,7 +12,7 @@
 
 /**
- * TagInfoViewer is a UI component which displays the  list of tags of two
+ * TagInfoViewer is a UI component which displays the list of tags of two
  * version of a {@see OsmPrimitive} in a {@see History}.
- * 
+ *
  * <ul>
  *   <li>on the left, it displays the list of tags for the version at {@see PointInTimeType#REFERENCE_POINT_IN_TIME}</li>
Index: trunk/src/org/openstreetmap/josm/gui/history/VersionInfoPanel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/history/VersionInfoPanel.java	(revision 2241)
+++ trunk/src/org/openstreetmap/josm/gui/history/VersionInfoPanel.java	(revision 2242)
@@ -21,5 +21,5 @@
  * VersionInfoPanel is an UI component which displays the basic properties of a version
  * of a {@see OsmPrimitive}.
- * 
+ *
  */
 public class VersionInfoPanel extends JPanel implements Observer{
@@ -51,5 +51,5 @@
                 Long.toString(primitive.getVersion()),
                 new SimpleDateFormat().format(primitive.getTimestamp()),
-                primitive.getUser(),
+                primitive.getUser().replace("<", "&lt;").replace(">", "&gt;"),
                 primitive.getChangesetId()
         );
@@ -65,5 +65,5 @@
     /**
      * constructor
-     * 
+     *
      * @param model  the model (must not be null)
      * @param pointInTimeType the point in time this panel visualizes (must not be null)
Index: trunk/src/org/openstreetmap/josm/io/OsmHistoryReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OsmHistoryReader.java	(revision 2241)
+++ trunk/src/org/openstreetmap/josm/io/OsmHistoryReader.java	(revision 2242)
@@ -80,4 +80,21 @@
         }
 
+        protected long getAttributeLong(Attributes attr, String name, long defaultValue) throws SAXException{
+            String v = attr.getValue(name);
+            if (v == null) {
+                return defaultValue;
+            }
+            Long l = 0l;
+            try {
+                l = Long.parseLong(v);
+            } catch(NumberFormatException e) {
+                throwException(tr("Illegal value for mandatory attribute ''{0}'' of type long. Got ''{1}''.", name, v));
+            }
+            if (l < 0) {
+                throwException(tr("Illegal value for mandatory attribute ''{0}'' of type long (>=0). Got ''{1}''.", name, v));
+            }
+            return l;
+        }
+
         protected int getMandatoryAttributeInt(Attributes attr, String name) throws SAXException{
             String v = attr.getValue(name);
@@ -97,4 +114,18 @@
         }
 
+        protected double getMandatoryAttributeDouble(Attributes attr, String name) throws SAXException{
+            String v = attr.getValue(name);
+            if (v == null) {
+                throwException(tr("Missing mandatory attribute ''{0}''.", name));
+            }
+            double d = 0.0;
+            try {
+                d = Double.parseDouble(v);
+            } catch(NumberFormatException e) {
+                throwException(tr("Illegal value for mandatory attribute ''{0}'' of type double. Got ''{1}''.", name, v));
+            }
+            return d;
+        }
+
         protected String getMandatoryAttributeString(Attributes attr, String name) throws SAXException{
             String v = attr.getValue(name);
@@ -102,4 +133,11 @@
                 throwException(tr("Missing mandatory attribute ''{0}''.", name));
             }
+            return v;
+        }
+
+        protected String getAttributeString(Attributes attr, String name, String defaultValue) {
+            String v = attr.getValue(name);
+            if (v == null)
+                v = defaultValue;
             return v;
         }
@@ -119,15 +157,17 @@
         protected  HistoryOsmPrimitive createPrimitive(Attributes atts, OsmPrimitiveType type) throws SAXException {
             long id = getMandatoryAttributeLong(atts,"id");
-            long version = getMandatoryAttributeLong(atts,"version");
-            long changesetId = getMandatoryAttributeLong(atts,"changeset");
-            boolean visible= getMandatoryAttributeBoolean(atts, "visible");
-            long uid = getMandatoryAttributeLong(atts, "uid");
-            String user = getMandatoryAttributeString(atts, "user");
+            long version = getMandatoryAttributeLong(atts, "version");
+            long changesetId = getMandatoryAttributeLong(atts, "changeset");
+            boolean visible = getMandatoryAttributeBoolean(atts, "visible");
+            long uid = getAttributeLong(atts, "uid", -1);
+            String user = getAttributeString(atts, "user", tr("<anonymous>"));
             String v = getMandatoryAttributeString(atts, "timestamp");
             Date timestamp = DateUtils.fromString(v);
             HistoryOsmPrimitive primitive = null;
             if (type.equals(OsmPrimitiveType.NODE)) {
+                double lat = getMandatoryAttributeDouble(atts, "lat");
+                double lon = getMandatoryAttributeDouble(atts, "lon");
                 primitive = new HistoryNode(
-                        id,version,visible,user,uid,changesetId,timestamp
+                        id,version,visible,user,uid,changesetId,timestamp,lat,lon
                 );
             } else if (type.equals(OsmPrimitiveType.WAY)) {
