Index: trunk/src/org/openstreetmap/josm/data/osm/history/HistoryNode.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/history/HistoryNode.java	(revision 5439)
+++ trunk/src/org/openstreetmap/josm/data/osm/history/HistoryNode.java	(revision 5440)
@@ -15,16 +15,51 @@
  */
 public class HistoryNode extends HistoryOsmPrimitive {
+    
     /** the coordinates. May be null for deleted nodes */
-
     private LatLon coords;
 
-    public HistoryNode(long id, long version, boolean visible, User user, long changesetId, Date timestamp, LatLon coords) {
-        super(id, version, visible, user, changesetId, timestamp);
+    /**
+     * Constructs a new {@code HistoryNode}.
+     * 
+     * @param id the id (> 0 required)
+     * @param version the version (> 0 required)
+     * @param visible whether the node is still visible
+     * @param user the user (! null required)
+     * @param changesetId the changeset id (> 0 required)
+     * @param timestamp the timestamp (! null required)
+     * @param coords the coordinates
+     * @throws IllegalArgumentException if preconditions are violated
+     */
+    public HistoryNode(long id, long version, boolean visible, User user, long changesetId, Date timestamp, LatLon coords) throws IllegalArgumentException {
+        this(id, version, visible, user, changesetId, timestamp, coords, true);
+    }
+
+    /**
+     * Constructs a new {@code HistoryNode} with a configurable checking of historic parameters.
+     * This is needed to build virtual HistoryNodes for modified nodes, which do not have a timestamp and a changeset id.
+     * 
+     * @param id the id (> 0 required)
+     * @param version the version (> 0 required)
+     * @param visible whether the node is still visible
+     * @param user the user (! null required)
+     * @param changesetId the changeset id (> 0 required if {@code checkHistoricParams} is true)
+     * @param timestamp the timestamp (! null required if {@code checkHistoricParams} is true)
+     * @param coords the coordinates
+     * @param checkHistoricParams if true, checks values of {@code changesetId} and {@code timestamp}
+     * @throws IllegalArgumentException if preconditions are violated
+     * @since 5440
+     */
+    public HistoryNode(long id, long version, boolean visible, User user, long changesetId, Date timestamp, LatLon coords, boolean checkHistoricParams) throws IllegalArgumentException {
+        super(id, version, visible, user, changesetId, timestamp, checkHistoricParams);
         setCoords(coords);
     }
 
-    public HistoryNode(Node p) {
-        super(p);
-        setCoords(p.getCoor());
+    /**
+     * Constructs a new {@code HistoryNode} from an existing {@link Node}.
+     * @param n the node
+     */
+    public HistoryNode(Node n) {
+        super(n);
+        setCoords(n.getCoor());
     }
 
@@ -34,8 +69,16 @@
     }
 
+    /**
+     * Replies the coordinates. May be null.
+     * @return the coordinates. May be null.
+     */
     public LatLon getCoords() {
         return coords;
     }
 
+    /**
+     * Sets the coordinates. Can be null.
+     * @param coords the coordinates. Can be null.
+     */
     public void setCoords(LatLon coords) {
         this.coords = coords;
Index: trunk/src/org/openstreetmap/josm/data/osm/history/HistoryOsmPrimitive.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/history/HistoryOsmPrimitive.java	(revision 5439)
+++ trunk/src/org/openstreetmap/josm/data/osm/history/HistoryOsmPrimitive.java	(revision 5440)
@@ -42,38 +42,64 @@
 
     /**
-     * constructor
-     *
-     * @param id the id (>0 required)
+     * Constructs a new {@code HistoryOsmPrimitive}.
+     *
+     * @param id the id (> 0 required)
      * @param version the version (> 0 required)
      * @param visible whether the primitive is still visible
-     * @param user  the user (! null required)
-     * @param uid the user id (> 0 required)
-     * @param changesetId the changeset id (may be null if the changeset isn't known)
+     * @param user the user (! null required)
+     * @param changesetId the changeset id (> 0 required)
      * @param timestamp the timestamp (! null required)
      *
-     * @throws IllegalArgumentException thrown if preconditions are violated
+     * @throws IllegalArgumentException if preconditions are violated
      */
     public HistoryOsmPrimitive(long id, long version, boolean visible, User user, long changesetId, Date timestamp) throws IllegalArgumentException {
+        this(id, version, visible, user, changesetId, timestamp, true);
+    }
+
+    /**
+     * Constructs a new {@code HistoryOsmPrimitive} with a configurable checking of historic parameters.
+     * This is needed to build virtual HistoryOsmPrimitives for modified primitives, which do not have a timestamp and a changeset id.
+     *
+     * @param id the id (> 0 required)
+     * @param version the version (> 0 required)
+     * @param visible whether the primitive is still visible
+     * @param user the user (! null required)
+     * @param changesetId the changeset id (> 0 required if {@code checkHistoricParams} is true)
+     * @param timestamp the timestamp (! null required if {@code checkHistoricParams} is true)
+     * @param checkHistoricParams if true, checks values of {@code changesetId} and {@code timestamp}
+     *
+     * @throws IllegalArgumentException if preconditions are violated
+     * @since 5440
+     */
+    public HistoryOsmPrimitive(long id, long version, boolean visible, User user, long changesetId, Date timestamp, boolean checkHistoricParams) throws IllegalArgumentException {
         ensurePositiveLong(id, "id");
         ensurePositiveLong(version, "version");
         CheckParameterUtil.ensureParameterNotNull(user, "user");
-        CheckParameterUtil.ensureParameterNotNull(timestamp, "timestamp");
+        if (checkHistoricParams) {
+            ensurePositiveLong(changesetId, "changesetId");
+            CheckParameterUtil.ensureParameterNotNull(timestamp, "timestamp");
+        }
         this.id = id;
         this.version = version;
         this.visible = visible;
         this.user = user;
-        // FIXME: restrict to IDs > 0 as soon as OsmPrimitive holds the
-        // changeset id too
         this.changesetId  = changesetId;
         this.timestamp = timestamp;
         tags = new HashMap<String, String>();
     }
-
+    
+    /**
+     * Constructs a new {@code HistoryOsmPrimitive} from an existing {@link OsmPrimitive}.
+     * @param p the primitive
+     */
     public HistoryOsmPrimitive(OsmPrimitive p) {
-        this(p.getId(), p.getVersion(), p.isVisible(),
-                p.getUser(),
-                p.getChangesetId(), p.getTimestamp());
-    }
-
+        this(p.getId(), p.getVersion(), p.isVisible(), p.getUser(), p.getChangesetId(), p.getTimestamp());
+    }
+
+    /**
+     * Replies a new {@link HistoryNode}, {@link HistoryWay} or {@link HistoryRelation} from an existing {@link OsmPrimitive}.
+     * @param p the primitive
+     * @return a new {@code HistoryNode}, {@code HistoryWay} or {@code HistoryRelation} from {@code p}.
+     */
     public static HistoryOsmPrimitive forOsmPrimitive(OsmPrimitive p) {
         if (p instanceof Node) {
@@ -173,4 +199,5 @@
     /**
      * Replies the display name of a primitive formatted by <code>formatter</code>
+     * @param formatter The formatter used to generate a display name
      *
      * @return the display name
Index: trunk/src/org/openstreetmap/josm/data/osm/history/HistoryRelation.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/history/HistoryRelation.java	(revision 5439)
+++ trunk/src/org/openstreetmap/josm/data/osm/history/HistoryRelation.java	(revision 5440)
@@ -30,14 +30,13 @@
      * @param visible whether the primitive is still visible
      * @param user  the user (! null required)
-     * @param uid the user id (> 0 required)
      * @param changesetId the changeset id (> 0 required)
      * @param timestamp the timestamp (! null required)
      *
-     * @throws IllegalArgumentException thrown if preconditions are violated
+     * @throws IllegalArgumentException if preconditions are violated
      */
-    public HistoryRelation(long id, long version, boolean visible, User user, long changesetId,
-            Date timestamp) throws IllegalArgumentException {
+    public HistoryRelation(long id, long version, boolean visible, User user, long changesetId, Date timestamp) throws IllegalArgumentException {
         super(id, version, visible, user, changesetId, timestamp);
     }
+
     /**
      * constructor
@@ -47,5 +46,22 @@
      * @param visible whether the primitive is still visible
      * @param user  the user (! null required)
-     * @param uid the user id (> 0 required)
+     * @param changesetId the changeset id (> 0 required if {@code checkHistoricParams} is true)
+     * @param timestamp the timestamp (! null required if {@code checkHistoricParams} is true)
+     * @param checkHistoricParams If true, checks values of {@code changesetId} and {@code timestamp}
+     *
+     * @throws IllegalArgumentException if preconditions are violated
+     * @since 5440
+     */
+    public HistoryRelation(long id, long version, boolean visible, User user, long changesetId, Date timestamp, boolean checkHistoricParams) throws IllegalArgumentException {
+        super(id, version, visible, user, changesetId, timestamp, checkHistoricParams);
+    }
+
+    /**
+     * constructor
+     *
+     * @param id the id (>0 required)
+     * @param version the version (> 0 required)
+     * @param visible whether the primitive is still visible
+     * @param user  the user (! null required)
      * @param changesetId the changeset id (> 0 required)
      * @param timestamp the timestamp (! null required)
@@ -62,6 +78,10 @@
     }
 
-    public HistoryRelation(Relation p) {
-        super(p);
+    /**
+     * Constructs a new {@code HistoryRelation} from an existing {@link Relation}.
+     * @param r the relation
+     */
+    public HistoryRelation(Relation r) {
+        super(r);
     }
 
Index: trunk/src/org/openstreetmap/josm/data/osm/history/HistoryWay.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/history/HistoryWay.java	(revision 5439)
+++ trunk/src/org/openstreetmap/josm/data/osm/history/HistoryWay.java	(revision 5440)
@@ -12,4 +12,5 @@
 import org.openstreetmap.josm.data.osm.User;
 import org.openstreetmap.josm.data.osm.Way;
+import org.openstreetmap.josm.tools.CheckParameterUtil;
 
 /**
@@ -22,15 +23,61 @@
     private ArrayList<Long> nodeIds = new ArrayList<Long>();
 
-    public HistoryWay(long id, long version, boolean visible, User user, long changesetId, Date timestamp) {
+    /**
+     * Constructs a new {@code HistoryWay}.
+     * 
+     * @param id the id (> 0 required)
+     * @param version the version (> 0 required)
+     * @param visible whether the node is still visible
+     * @param user the user (! null required)
+     * @param changesetId the changeset id (> 0 required if {@code checkHistoricParams} is true)
+     * @param timestamp the timestamp (! null required if {@code checkHistoricParams} is true)
+     * @throws IllegalArgumentException if preconditions are violated
+     */
+    public HistoryWay(long id, long version, boolean visible, User user, long changesetId, Date timestamp) throws IllegalArgumentException {
         super(id, version, visible, user, changesetId, timestamp);
     }
 
-    public HistoryWay(long id, long version, boolean visible, User user, long changesetId, Date timestamp, ArrayList<Long> nodeIdList) {
+    /**
+     * Constructs a new {@code HistoryWay} with a configurable checking of historic parameters.
+     * This is needed to build virtual HistoryWays for modified ways, which do not have a timestamp and a changeset id.
+     * 
+     * @param id the id (> 0 required)
+     * @param version the version (> 0 required)
+     * @param visible whether the node is still visible
+     * @param user the user (! null required)
+     * @param changesetId the changeset id (> 0 required if {@code checkHistoricParams} is true)
+     * @param timestamp the timestamp (! null required if {@code checkHistoricParams} is true)
+     * @param checkHistoricParams if true, checks values of {@code changesetId} and {@code timestamp}
+     * @throws IllegalArgumentException if preconditions are violated
+     * @since 5440
+     */
+    public HistoryWay(long id, long version, boolean visible, User user, long changesetId, Date timestamp, boolean checkHistoricParams) throws IllegalArgumentException {
+        super(id, version, visible, user, changesetId, timestamp, checkHistoricParams);
+    }
+
+    /**
+     * Constructs a new {@code HistoryWay} with a given list of node ids.
+     * 
+     * @param id the id (> 0 required)
+     * @param version the version (> 0 required)
+     * @param visible whether the node is still visible
+     * @param user the user (! null required)
+     * @param changesetId the changeset id (> 0 required if {@code checkHistoricParams} is true)
+     * @param timestamp the timestamp (! null required if {@code checkHistoricParams} is true)
+     * @param nodeIdList the node ids (! null required)
+     * @throws IllegalArgumentException if preconditions are violated
+     */
+    public HistoryWay(long id, long version, boolean visible, User user, long changesetId, Date timestamp, ArrayList<Long> nodeIdList) throws IllegalArgumentException {
         this(id, version, visible, user, changesetId, timestamp);
+        CheckParameterUtil.ensureParameterNotNull(nodeIdList, "nodeIdList");
         this.nodeIds.addAll(nodeIdList);
     }
 
-    public HistoryWay(Way p) {
-        super(p);
+    /**
+     * Constructs a new {@code HistoryWay} from an existing {@link Way}.
+     * @param w the way
+     */
+    public HistoryWay(Way w) {
+        super(w);
     }
 
Index: trunk/src/org/openstreetmap/josm/gui/history/HistoryBrowser.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/history/HistoryBrowser.java	(revision 5439)
+++ trunk/src/org/openstreetmap/josm/gui/history/HistoryBrowser.java	(revision 5440)
@@ -13,4 +13,5 @@
 import javax.swing.JTable;
 
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
 import org.openstreetmap.josm.data.osm.history.History;
Index: trunk/src/org/openstreetmap/josm/gui/history/HistoryBrowserModel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/history/HistoryBrowserModel.java	(revision 5439)
+++ trunk/src/org/openstreetmap/josm/gui/history/HistoryBrowserModel.java	(revision 5440)
@@ -20,4 +20,5 @@
 import org.openstreetmap.josm.data.osm.RelationMemberData;
 import org.openstreetmap.josm.data.osm.User;
+import org.openstreetmap.josm.data.osm.UserInfo;
 import org.openstreetmap.josm.data.osm.Way;
 import org.openstreetmap.josm.data.osm.event.AbstractDatasetChangedEvent;
@@ -36,4 +37,5 @@
 import org.openstreetmap.josm.data.osm.history.HistoryWay;
 import org.openstreetmap.josm.data.osm.visitor.AbstractVisitor;
+import org.openstreetmap.josm.gui.JosmUserIdentityManager;
 import org.openstreetmap.josm.gui.MapView;
 import org.openstreetmap.josm.gui.MapView.LayerChangeListener;
@@ -437,5 +439,5 @@
             case 4: {
                     HistoryOsmPrimitive p = getPrimitive(row);
-                    if (p != null)
+                    if (p != null && p.getTimestamp() != null)
                         return DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT).format(p.getTimestamp());
                     return null;
@@ -877,10 +879,10 @@
 
         public void visit(Node n) {
-            clone = new HistoryNode(n.getId(), n.getVersion(), n.isVisible(), n.getUser(), 0, n.getTimestamp(), n.getCoor());
+            clone = new HistoryNode(n.getId(), n.getVersion(), n.isVisible(), getCurrentUser(), 0, null, n.getCoor(), false);
             clone.setTags(n.getKeys());
         }
 
         public void visit(Relation r) {
-            clone = new HistoryRelation(r.getId(), r.getVersion(), r.isVisible(), r.getUser(), 0, r.getTimestamp());
+            clone = new HistoryRelation(r.getId(), r.getVersion(), r.isVisible(), getCurrentUser(), 0, null, false);
             clone.setTags(r.getKeys());
             HistoryRelation hr = (HistoryRelation)clone;
@@ -891,5 +893,5 @@
 
         public void visit(Way w) {
-            clone = new HistoryWay(w.getId(), w.getVersion(), w.isVisible(), w.getUser(), 0, w.getTimestamp());
+            clone = new HistoryWay(w.getId(), w.getVersion(), w.isVisible(), getCurrentUser(), 0, null, false);
             clone.setTags(w.getKeys());
             for (Node n: w.getNodes()) {
@@ -898,4 +900,9 @@
         }
 
+        private User getCurrentUser() {
+            UserInfo info = JosmUserIdentityManager.getInstance().getUserInfo();
+            return info == null ? User.getAnonymous() : User.createOsmUser(info.getId(), info.getDisplayName());
+        }
+
         public HistoryOsmPrimitive build(OsmPrimitive primitive) {
             primitive.visit(this);
Index: trunk/src/org/openstreetmap/josm/gui/history/VersionInfoPanel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/history/VersionInfoPanel.java	(revision 5439)
+++ trunk/src/org/openstreetmap/josm/gui/history/VersionInfoPanel.java	(revision 5440)
@@ -20,9 +20,10 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.actions.AbstractInfoAction;
+import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.User;
 import org.openstreetmap.josm.data.osm.history.HistoryOsmPrimitive;
 import org.openstreetmap.josm.gui.JMultilineLabel;
+import org.openstreetmap.josm.gui.JosmUserIdentityManager;
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
-import org.openstreetmap.josm.io.auth.CredentialsManager;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
 import org.openstreetmap.josm.tools.UrlLabel;
@@ -153,7 +154,8 @@
             lblUser.setDescription(username);
         } else {
-            String user = CredentialsManager.getInstance().getUsername();
+            String user = JosmUserIdentityManager.getInstance().getUserName();
             if (user == null) {
                 lblUser.setDescription(tr("anonymous"));
+                lblUser.setUrl(null);
             } else {
                 try {
Index: trunk/src/org/openstreetmap/josm/gui/history/VersionTableColumnModel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/history/VersionTableColumnModel.java	(revision 5439)
+++ trunk/src/org/openstreetmap/josm/gui/history/VersionTableColumnModel.java	(revision 5440)
@@ -7,4 +7,5 @@
 import javax.swing.table.DefaultTableColumnModel;
 import javax.swing.table.TableColumn;
+import javax.swing.table.TableColumnModel;
 
 /**
@@ -58,4 +59,7 @@
     }
 
+    /**
+     * Creates a new {@code VersionTableColumnModel}.
+     */
     public VersionTableColumnModel() {
         createColumns();
Index: trunk/src/org/openstreetmap/josm/tools/UrlLabel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/UrlLabel.java	(revision 5439)
+++ trunk/src/org/openstreetmap/josm/tools/UrlLabel.java	(revision 5440)
@@ -49,8 +49,11 @@
         if (url != null) {
             setText("<html><a href=\""+url+"\">"+description+"</a></html>");
+            setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
+            setToolTipText(String.format("<html>%s<br/>%s</html>", url, tr("Right click = copy to clipboard")));
         } else {
             setText("<html>" + description + "</html>");
+            setCursor(null);
+            setToolTipText(null);
         }
-        setToolTipText(String.format("<html>%s<br/>%s</html>",url, tr("Right click = copy to clipboard")));
     }
 
