Index: /trunk/src/org/openstreetmap/josm/gui/layer/geoimage/CorrelateGpxWithImages.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/layer/geoimage/CorrelateGpxWithImages.java	(revision 2930)
+++ /trunk/src/org/openstreetmap/josm/gui/layer/geoimage/CorrelateGpxWithImages.java	(revision 2931)
@@ -2,5 +2,4 @@
 // Copyright 2007 by Christian Gallioz (aka khris78)
 // Parts of code from Geotagged plugin (by Rob Neild)
-// and the core JOSM source code (by Immanuel Scholz and others)
 
 package org.openstreetmap.josm.gui.layer.geoimage;
@@ -333,5 +332,5 @@
             imgList = new JList(new AbstractListModel() {
                 public Object getElementAt(int i) {
-                    return yLayer.data.get(i).file.getName();
+                    return yLayer.data.get(i).getFile().getName();
                 }
 
@@ -345,6 +344,6 @@
                 public void valueChanged(ListSelectionEvent arg0) {
                     int index = imgList.getSelectedIndex();
-                    imgDisp.setImage(yLayer.data.get(index).file);
-                    Date date = yLayer.data.get(index).time;
+                    imgDisp.setImage(yLayer.data.get(index).getFile());
+                    Date date = yLayer.data.get(index).getExifTime();
                     if (date != null) {
                         lbExifTime.setText(new SimpleDateFormat("dd/MM/yyyy HH:mm:ss").format(date));
@@ -649,5 +648,6 @@
                     return tr("No gpx selected");
 
-                lastNumMatched = matchGpxTrack(dateImgLst, selGpx.data, (long) (timezone * 3600) + delta);
+                final long offset_ms = ((long) (timezone * 3600) + delta) * 1000; // in milliseconds
+                lastNumMatched = matchGpxTrack(dateImgLst, selGpx.data, offset_ms);
 
                 return trn("<html>Matched <b>{0}</b> of <b>{1}</b> photo to GPX track.</html>",
@@ -746,5 +746,5 @@
                     Main.pref.put("geoimage.showThumbs", yLayer.useThumbs);
 
-                    yLayer.useThumbs = cbShowThumbs.isSelected();//FIXME
+                    yLayer.useThumbs = cbShowThumbs.isSelected();
                     yLayer.loadThumbs();
 
@@ -955,5 +955,5 @@
 
             // Init variables
-            long firstExifDate = imgs.get(0).time.getTime()/1000;
+            long firstExifDate = imgs.get(0).getExifTime().getTime()/1000;
 
             long firstGPXDate = -1;
@@ -1041,9 +1041,9 @@
         ArrayList<ImageEntry> dateImgLst = new ArrayList<ImageEntry>(yLayer.data.size());
         for (ImageEntry e : yLayer.data) {
-            if (e.time == null) {
+            if (e.getExifTime() == null) {
                 continue;
             }
 
-            if (e.exifCoor != null) {
+            if (e.getExifCoor() != null) {
                 if (!exif) {
                     continue;
@@ -1051,5 +1051,5 @@
             }
 
-            if (e.isTagged() && e.exifCoor == null) {
+            if (e.isTagged() && e.getExifCoor() == null) {
                 if (!tagged) {
                     continue;
@@ -1062,5 +1062,5 @@
         Collections.sort(dateImgLst, new Comparator<ImageEntry>() {
             public int compare(ImageEntry arg0, ImageEntry arg1) {
-                return arg0.time.compareTo(arg1.time);
+                return arg0.getExifTime().compareTo(arg1.getExifTime());
             }
         });
@@ -1082,5 +1082,9 @@
     }
 
-    private int matchGpxTrack(ArrayList<ImageEntry> dateImgLst, GpxData selectedGpx, long offset) {
+    /**
+     * Match a list of photos to a gpx track with a given offset.
+     * All images need a exifTime attribute and the List must be sorted according to these times.
+     */
+    private int matchGpxTrack(ArrayList<ImageEntry> images, GpxData selectedGpx, long offset) {
         int ret = 0;
 
@@ -1090,28 +1094,28 @@
             for (GpxTrackSegment segment : trk.getSegments()) {
 
-                long prevDateWp = 0;
+                long prevWpTime = 0;
                 WayPoint prevWp = null;
 
                 for (WayPoint curWp : segment.getWayPoints()) {
 
-                    String curDateWpStr = (String) curWp.attr.get("time");
-                    if (curDateWpStr != null) {
+                    String curWpTimeStr = (String) curWp.attr.get("time");
+                    if (curWpTimeStr != null) {
 
                         try {
-                            long curDateWp = dateParser.parse(curDateWpStr).getTime()/1000 + offset;
-                            ret += matchPoints(dateImgLst, prevWp, prevDateWp, curWp, curDateWp);
+                            long curWpTime = dateParser.parse(curWpTimeStr).getTime() + offset;
+                            ret += matchPoints(images, prevWp, prevWpTime, curWp, curWpTime, offset);
 
                             prevWp = curWp;
-                            prevDateWp = curDateWp;
+                            prevWpTime = curWpTime;
 
                         } catch(ParseException e) {
-                            System.err.println("Error while parsing date \"" + curDateWpStr + '"');
+                            System.err.println("Error while parsing date \"" + curWpTimeStr + '"');
                             e.printStackTrace();
                             prevWp = null;
-                            prevDateWp = 0;
+                            prevWpTime = 0;
                         }
                     } else {
                         prevWp = null;
-                        prevDateWp = 0;
+                        prevWpTime = 0;
                     }
                 }
@@ -1121,13 +1125,13 @@
     }
 
-    private int matchPoints(ArrayList<ImageEntry> dateImgLst, WayPoint prevWp, long prevDateWp,
-            WayPoint curWp, long curDateWp) {
+    private int matchPoints(ArrayList<ImageEntry> images, WayPoint prevWp, long prevWpTime,
+            WayPoint curWp, long curWpTime, long offset) {
         // Time between the track point and the previous one, 5 sec if first point, i.e. photos take
         // 5 sec before the first track point can be assumed to be take at the starting position
-        long interval = prevDateWp > 0 ? ((int)Math.abs(curDateWp - prevDateWp)) : 5;
+        long interval = prevWpTime > 0 ? ((long)Math.abs(curWpTime - prevWpTime)) : 5*1000;
         int ret = 0;
 
         // i is the index of the timewise last photo that has the same or earlier EXIF time
-        int i = getLastIndexOfListBefore(dateImgLst, curDateWp);
+        int i = getLastIndexOfListBefore(images, curWpTime);
 
         // no photos match
@@ -1142,6 +1146,6 @@
             double distance = prevWp.getCoor().greatCircleDistance(curWp.getCoor());
             // This is in km/h, 3.6 * m/s
-            if (curDateWp > prevDateWp) {
-                speed = 3.6 * distance / (curDateWp - prevDateWp);
+            if (curWpTime > prevWpTime) {
+                speed = 3.6 * distance / (curWpTime - prevWpTime);
             }
             try {
@@ -1156,11 +1160,17 @@
         // First trackpoint, then interval is set to five seconds, i.e. photos up to five seconds
         // before the first point will be geotagged with the starting point
-        if(prevDateWp == 0 || curDateWp <= prevDateWp) {
-            while(i >= 0 && (dateImgLst.get(i).time.getTime()/1000) <= curDateWp
-                    && (dateImgLst.get(i).time.getTime()/1000) >= (curDateWp - interval)) {
-                if(dateImgLst.get(i).tmp.getPos() == null) {
-                    dateImgLst.get(i).tmp.setCoor(curWp.getCoor());
-                    dateImgLst.get(i).tmp.setSpeed(speed);
-                    dateImgLst.get(i).tmp.setElevation(curElevation);
+        if(prevWpTime == 0 || curWpTime <= prevWpTime) {
+            while (true) {
+                if (i < 0)
+                    break;
+                final ImageEntry curImg = images.get(i);
+                if (curImg.getExifTime().getTime() > curWpTime
+                    || curImg.getExifTime().getTime() < curWpTime - interval)
+                        break;
+                if(curImg.tmp.getPos() == null) {
+                    curImg.tmp.setPos(curWp.getCoor());
+                    curImg.tmp.setSpeed(speed);
+                    curImg.tmp.setElevation(curElevation);
+                    curImg.tmp.setGpsTime(new Date(curImg.getExifTime().getTime() - offset));
                     ret++;
                 }
@@ -1172,17 +1182,22 @@
         // This code gives a simple linear interpolation of the coordinates between current and
         // previous track point assuming a constant speed in between
-        long imgDate;
-        while(i >= 0 && (imgDate = dateImgLst.get(i).time.getTime()/1000) >= prevDateWp) {
-
-            if(dateImgLst.get(i).tmp.getPos() == null) {
+        while (true) {
+            if (i < 0)
+                break;
+            ImageEntry curImg = images.get(i);
+            long imgTime = curImg.getExifTime().getTime();
+            if (imgTime < prevWpTime)
+                break;
+
+            if(curImg.tmp.getPos() == null) {
                 // The values of timeDiff are between 0 and 1, it is not seconds but a dimensionless
                 // variable
-                double timeDiff = (double)(imgDate - prevDateWp) / interval;
-                dateImgLst.get(i).tmp.setCoor(prevWp.getCoor().interpolate(curWp.getCoor(), timeDiff));
-                dateImgLst.get(i).tmp.setSpeed(speed);
-
+                double timeDiff = (double)(imgTime - prevWpTime) / interval;
+                curImg.tmp.setPos(prevWp.getCoor().interpolate(curWp.getCoor(), timeDiff));
+                curImg.tmp.setSpeed(speed);
                 if (curElevation != null && prevElevation != null) {
-                    dateImgLst.get(i).setElevation(prevElevation + (curElevation - prevElevation) * timeDiff);
-                }
+                    curImg.setElevation(prevElevation + (curElevation - prevElevation) * timeDiff);
+                }
+                curImg.tmp.setGpsTime(new Date(curImg.getExifTime().getTime() - offset));
 
                 ret++;
@@ -1193,13 +1208,13 @@
     }
 
-    private int getLastIndexOfListBefore(ArrayList<ImageEntry> dateImgLst, long searchedDate) {
-        int lstSize= dateImgLst.size();
+    private int getLastIndexOfListBefore(ArrayList<ImageEntry> images, long searchedTime) {
+        int lstSize= images.size();
 
         // No photos or the first photo taken is later than the search period
-        if(lstSize == 0 || searchedDate < dateImgLst.get(0).time.getTime()/1000)
+        if(lstSize == 0 || searchedTime < images.get(0).getExifTime().getTime())
             return -1;
 
         // The search period is later than the last photo
-        if (searchedDate > dateImgLst.get(lstSize - 1).time.getTime() / 1000)
+        if (searchedTime > images.get(lstSize - 1).getExifTime().getTime())
             return lstSize-1;
 
@@ -1210,5 +1225,5 @@
         while (endIndex - startIndex > 1) {
             curIndex= (endIndex + startIndex) / 2;
-            if (searchedDate > dateImgLst.get(curIndex).time.getTime()/1000) {
+            if (searchedTime > images.get(curIndex).getExifTime().getTime()) {
                 startIndex= curIndex;
             } else {
@@ -1216,10 +1231,10 @@
             }
         }
-        if (searchedDate < dateImgLst.get(endIndex).time.getTime()/1000)
+        if (searchedTime < images.get(endIndex).getExifTime().getTime())
             return startIndex;
 
         // This final loop is to check if photos with the exact same EXIF time follows
-        while ((endIndex < (lstSize-1)) && (dateImgLst.get(endIndex).time.getTime()
-                == dateImgLst.get(endIndex + 1).time.getTime())) {
+        while ((endIndex < (lstSize-1)) && (images.get(endIndex).getExifTime().getTime()
+                == images.get(endIndex + 1).getExifTime().getTime())) {
             endIndex++;
         }
Index: /trunk/src/org/openstreetmap/josm/gui/layer/geoimage/GeoImageLayer.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/layer/geoimage/GeoImageLayer.java	(revision 2930)
+++ /trunk/src/org/openstreetmap/josm/gui/layer/geoimage/GeoImageLayer.java	(revision 2931)
@@ -146,9 +146,9 @@
 
                 try {
-                    e.time = ExifReader.readTime(f);
+                    e.setExifTime(ExifReader.readTime(f));
                 } catch (ParseException e1) {
-                    e.time = null;
-                }
-                e.file = f;
+                    e.setExifTime(null);
+                }
+                e.setFile(f);
                 extractExif(e);
                 data.add(e);
@@ -313,4 +313,7 @@
         entries.add(new JSeparator());
         entries.add(correlateItem);
+        if (!menuAdditions.isEmpty()) {
+            entries.add(new JSeparator());
+        }
         for (LayerMenuAddition addition : menuAdditions) {
             entries.add(addition.getComponent(this));
@@ -365,5 +368,5 @@
             for (int i = data.size() - 2; i >= 0; i--) {
                 cur = data.get(i);
-                if (cur.file.equals(prev.file)) {
+                if (cur.getFile().equals(prev.getFile())) {
                     data.remove(i);
                 } else {
@@ -505,11 +508,10 @@
             double lon, lat;
 
-            Metadata metadata = JpegMetadataReader.readMetadata(e.file);
+            Metadata metadata = JpegMetadataReader.readMetadata(e.getFile());
             Directory dir = metadata.getDirectory(GpsDirectory.class);
 
             // longitude
 
-            Rational[] components = dir
-            .getRationalArray(GpsDirectory.TAG_GPS_LONGITUDE);
+            Rational[] components = dir.getRationalArray(GpsDirectory.TAG_GPS_LONGITUDE);
 
             deg = components[0].intValue();
@@ -539,9 +541,9 @@
             // Store values
 
-            e.setCoor(new LatLon(lat, lon));
-            e.exifCoor = e.getPos();
+            e.setExifCoor(new LatLon(lat, lon));
+            e.setPos(e.getExifCoor());
 
         } catch (CompoundException p) {
-            e.exifCoor = null;
+            e.setExifCoor(null);
             e.setPos(null);
         }
@@ -607,5 +609,5 @@
             .setButtonIcons(new String[] {"cancel.png", "dialogs/delete.png"})
             .setContent(new JLabel(tr("<html><h3>Delete the file {0} from disk?<p>The image file will be permanently lost!</h3></html>"
-                    ,toDelete.file.getName()), ImageProvider.get("dialogs/geoimage/deletefromdisk"),SwingConstants.LEFT))
+                    ,toDelete.getFile().getName()), ImageProvider.get("dialogs/geoimage/deletefromdisk"),SwingConstants.LEFT))
                     .toggleEnable("geoimage.deleteimagefromdisk")
                     .setCancelButton(1)
@@ -626,6 +628,6 @@
                 }
 
-                if (toDelete.file.delete()) {
-                    System.out.println("File "+toDelete.file.toString()+" deleted. ");
+                if (toDelete.getFile().delete()) {
+                    System.out.println("File "+toDelete.getFile().toString()+" deleted. ");
                 } else {
                     JOptionPane.showMessageDialog(
Index: /trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ImageEntry.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ImageEntry.java	(revision 2930)
+++ /trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ImageEntry.java	(revision 2931)
@@ -18,8 +18,10 @@
 
 final public class ImageEntry implements Comparable<ImageEntry>, Cloneable {
-    File file;
-    Date time;
-    LatLon exifCoor;
+    private File file;
+    private LatLon exifCoor;
+    private Date exifTime;
+    Image thumbnail;
 
+    /** The following values are computed from the correlation with the gpx track */
     private CachedLatLon pos;
     /** Speed in kilometer per second */
@@ -27,6 +29,6 @@
     /** Elevation (altitude) in meters */
     private Double elevation;
-
-    Image thumbnail;
+    /** The time after correlation with a gpx track */
+    private Date gpsTime;
 
     /**
@@ -40,4 +42,7 @@
     ImageEntry tmp;
 
+    /**
+     * getter methods that refer to the temporary value
+     */
     public CachedLatLon getPos() {
         if (tmp != null)
@@ -55,6 +60,30 @@
         return elevation;
     }
+    public Date getGpsTime() {
+        if (tmp != null)
+            return tmp.gpsTime;
+        return gpsTime;
+    }
+
+    /**
+     * other getter methods
+     */
+    public File getFile() {
+        return file;
+    }
+    public Date getExifTime() {
+        return exifTime;
+    }
+    LatLon getExifCoor() {
+        return exifCoor;
+    }
+    /**
+     * setter methods
+     */
     public void setPos(CachedLatLon pos) {
         this.pos = pos;
+    }
+    public void setPos(LatLon pos) {
+        this.pos = new CachedLatLon(pos);
     }
     public void setSpeed(Double speed) {
@@ -64,7 +93,15 @@
         this.elevation = elevation;
     }
-    
-    public File getFile() {
-        return file;
+    void setFile(File file) {
+        this.file = file;
+    }
+    void setExifTime(Date exifTime) {
+        this.exifTime = exifTime;
+    }
+    void setGpsTime(Date gpsTime) {
+        this.gpsTime = gpsTime;
+    }
+    void setExifCoor(LatLon exifCoor) {
+        this.exifCoor = exifCoor;
     }
 
@@ -80,15 +117,10 @@
     }
 
-    public void setCoor(LatLon latlon)
-    {
-        pos = new CachedLatLon(latlon);
-    }
-
     public int compareTo(ImageEntry image) {
-        if (time != null && image.time != null)
-            return time.compareTo(image.time);
-        else if (time == null && image.time == null)
+        if (exifTime != null && image.exifTime != null)
+            return exifTime.compareTo(image.exifTime);
+        else if (exifTime == null && image.exifTime == null)
             return 0;
-        else if (time == null)
+        else if (exifTime == null)
             return -1;
         else
@@ -96,12 +128,7 @@
     }
 
-    public void applyTmp() {
-        if (tmp != null) {
-            pos = tmp.pos;
-            speed = tmp.speed;
-            elevation = tmp.elevation;
-            tmp = null;
-        }
-    }
+    /**
+     * Make a fresh copy and save it in the temporary variable.
+     */
     public void cleanTmp() {
         tmp = clone();
@@ -110,4 +137,20 @@
     }
 
+    /**
+     * Copy the values from the temporary variable to the main instance.
+     */
+    public void applyTmp() {
+        if (tmp != null) {
+            pos = tmp.pos;
+            speed = tmp.speed;
+            elevation = tmp.elevation;
+            gpsTime = tmp.gpsTime;
+            tmp = null;
+        }
+    }
+
+    /**
+     * If it has been tagged i.e. matched to a gpx track or retrieved lat/lon from exif
+     */
     public boolean isTagged() {
         return pos != null;
@@ -115,5 +158,5 @@
 
     /**
-     * only partial info
+     * String representation. (only partial info)
      */
     @Override
Index: /trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ImageViewerDialog.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ImageViewerDialog.java	(revision 2930)
+++ /trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ImageViewerDialog.java	(revision 2931)
@@ -14,5 +14,4 @@
 import java.awt.GridBagLayout;
 import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
 import java.awt.event.KeyEvent;
 import java.awt.event.WindowEvent;
@@ -238,7 +237,7 @@
 
         if (entry != null) {
-            imgDisplay.setImage(entry.file);
-            setTitle("Geotagged Images" + (entry.file != null ? " - " + entry.file.getName() : ""));
-            StringBuffer osd = new StringBuffer(entry.file != null ? entry.file.getName() : "");
+            imgDisplay.setImage(entry.getFile());
+            setTitle("Geotagged Images" + (entry.getFile() != null ? " - " + entry.getFile().getName() : ""));
+            StringBuffer osd = new StringBuffer(entry.getFile() != null ? entry.getFile().getName() : "");
             if (entry.getElevation() != null) {
                 osd.append(tr("\nAltitude: {0} m", entry.getElevation().longValue()));
@@ -250,4 +249,10 @@
             //    osd.append(tr("\nlat: {0}, lon: {1}", Double.toString(entry.getPos().lat()), Double.toString(entry.getPos().lon())));
             //}
+            //osd.append(tr("\nfile mtime: {0}", Long.toString(entry.getFile().lastModified())));
+            //osd.append(tr("\nImage exif time: {0}", Long.toString(entry.getExifTime().getTime())));
+            //if (entry.getGpsTime() != null) {
+            //    osd.append(tr("\nImage gps time: {0}", Long.toString(entry.getGpsTime().getTime())));
+            //}
+            
             imgDisplay.setOsdText(osd.toString());
         } else {
Index: /trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ThumbsLoader.java
===================================================================
--- /trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ThumbsLoader.java	(revision 2930)
+++ /trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ThumbsLoader.java	(revision 2931)
@@ -72,5 +72,5 @@
 
         private BufferedImage loadThumb(ImageEntry entry) {
-            final String cacheIdent = entry.file.toString()+":"+maxSize;
+            final String cacheIdent = entry.getFile().toString()+":"+maxSize;
 
             if (!cacheOff) {
@@ -82,5 +82,5 @@
             }
 
-            Image img = Toolkit.getDefaultToolkit().createImage(entry.file.getPath());
+            Image img = Toolkit.getDefaultToolkit().createImage(entry.getFile().getPath());
             tracker.addImage(img, 0);
             try {
