Index: /applications/editors/josm/plugins/agpifoj/src/org/openstreetmap/josm/plugins/agpifoj/AgpifojLayer.java
===================================================================
--- /applications/editors/josm/plugins/agpifoj/src/org/openstreetmap/josm/plugins/agpifoj/AgpifojLayer.java	(revision 12746)
+++ /applications/editors/josm/plugins/agpifoj/src/org/openstreetmap/josm/plugins/agpifoj/AgpifojLayer.java	(revision 12747)
@@ -18,7 +18,7 @@
 import java.text.ParseException;
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.Date;
+import java.util.HashSet;
 import java.util.List;
 
@@ -82,17 +82,35 @@
     }
 
+    /** Loads a set of images, while displaying a dialog that indicates what the plugin is currently doing.
+     * In facts, this object is instantiated with a list of files. These files may be JPEG files or 
+     * directories. In case of directories, they are scanned to find all the images they contain. 
+     * Then all the images that have be found are loaded as ImageEntry instances. 
+     */
     private static final class Loader extends PleaseWaitRunnable {
 
         private boolean cancelled = false;
         private AgpifojLayer layer;
-        private final Collection<File> files;
-
-        public Loader(Collection<File> files) {
+        private final File[] selection;
+        private HashSet<String> loadedDirectories = new HashSet<String>();
+        
+        public Loader(File[] selection) {
             super(tr("Extracting GPS locations from EXIF"));
-            this.files = files;
+            this.selection = selection;
         }
 
         @Override protected void realRun() throws IOException {
 
+            Main.pleaseWaitDlg.currentAction.setText(tr("Starting directory scan"));
+            List<File> files = new ArrayList<File>();
+            try {
+                addRecursiveFiles(files, selection);
+            } catch(NullPointerException npe) {
+                errorMessage += tr("One of the selected files was null !!!");
+            }
+            
+            if (cancelled) {
+                return;
+            }
+            
             Main.pleaseWaitDlg.currentAction.setText(tr("Read photos..."));
 
@@ -128,4 +146,56 @@
             }
             layer = new AgpifojLayer(data);
+            files.clear();
+        }
+
+        private void addRecursiveFiles(List<File> files, File[] sel) { 
+            boolean nullFile = false;
+            
+            for (File f : sel) {
+                
+                if(cancelled) {
+                    break;
+                }
+                
+                if (f == null) {
+                    nullFile = true;
+                    
+                } else if (f.isDirectory()) {
+                    String canonical = null;
+                    try {
+                        canonical = f.getCanonicalPath();
+                    } catch (IOException e) {
+                        e.printStackTrace();
+                        errorMessage += tr("Unable to get canonical path for directory {0}\n", 
+                                           f.getAbsolutePath());
+                    }
+                    
+                    if (canonical == null || loadedDirectories.contains(canonical)) {
+                        continue;
+                    } else {
+                        loadedDirectories.add(canonical);
+                    }
+                    
+                    File[] children = f.listFiles(AgpifojPlugin.JPEG_FILE_FILTER);
+                    if (children != null) {
+                        Main.pleaseWaitDlg.currentAction.setText(tr("Scanning directory {0}", f.getPath()));
+                        try {
+                            addRecursiveFiles(files, children);
+                        } catch(NullPointerException npe) {
+                            npe.printStackTrace();
+                            errorMessage += tr("Found null file in directory {0}\n", f.getPath());
+                        }
+                    } else {
+                        errorMessage += tr("Error while getting files from directory {0}\n", f.getPath());
+                    }
+                    
+                } else {
+                      files.add(f);
+                }
+            }
+            
+            if (nullFile) {
+                throw new NullPointerException();
+            }
         }
 
@@ -134,5 +204,5 @@
                 Main.main.addLayer(layer);
                 layer.hook_up_mouse_events(); // Main.map.mapView should exist
-                                              // now. Can add mouse lisener
+                                              // now. Can add mouse listener
 
                 if (! cancelled && layer.data.size() > 0) {
@@ -155,5 +225,5 @@
     }
 
-    public static void create(Collection<File> files) {
+    public static void create(File[] files) {
         Loader loader = new Loader(files);
         Main.worker.execute(loader);
Index: /applications/editors/josm/plugins/agpifoj/src/org/openstreetmap/josm/plugins/agpifoj/AgpifojPlugin.java
===================================================================
--- /applications/editors/josm/plugins/agpifoj/src/org/openstreetmap/josm/plugins/agpifoj/AgpifojPlugin.java	(revision 12746)
+++ /applications/editors/josm/plugins/agpifoj/src/org/openstreetmap/josm/plugins/agpifoj/AgpifojPlugin.java	(revision 12747)
@@ -7,5 +7,4 @@
 import static org.openstreetmap.josm.tools.I18n.tr;
 
-import java.awt.BorderLayout;
 import java.awt.event.ActionEvent;
 import java.io.File;
@@ -14,20 +13,33 @@
 
 import javax.swing.JFileChooser;
-import javax.swing.JMenu;
-import javax.swing.JMenuBar;
-import javax.swing.JMenuItem;
-import javax.swing.JToggleButton;
-import javax.swing.JToolBar;
-import javax.swing.filechooser.FileFilter;
 
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.actions.JosmAction;
 import org.openstreetmap.josm.gui.IconToggleButton;
+import org.openstreetmap.josm.gui.MainMenu;
 import org.openstreetmap.josm.gui.MapFrame;
-import org.openstreetmap.josm.gui.MainMenu;
 import org.openstreetmap.josm.gui.layer.Layer;
 import org.openstreetmap.josm.plugins.Plugin;
 
 public class AgpifojPlugin extends Plugin {
+    
+    static class JpegFileFilter extends javax.swing.filechooser.FileFilter 
+                                        implements java.io.FileFilter {
+        
+        @Override public boolean accept(File f) {
+            if (f.isDirectory()) {
+                return true;
+            } else {
+                String name = f.getName().toLowerCase();
+                return name.endsWith(".jpg") || name.endsWith(".jpeg");
+            }
+        }
+
+        @Override public String getDescription() {
+            return tr("JPEG images (*.jpg)");
+        }
+    };
+    
+    static final JpegFileFilter JPEG_FILE_FILTER = new JpegFileFilter();
     
     private class Action extends JosmAction {
@@ -46,15 +58,5 @@
             fc.setMultiSelectionEnabled(true);
             fc.setAcceptAllFileFilterUsed(false);
-            fc.setFileFilter(
-                    new FileFilter() {
-                        @Override public boolean accept(File f) {
-                            return f.isDirectory()
-                                    || f.getName().toLowerCase().endsWith(".jpg");
-                        }
-
-                        @Override public String getDescription() {
-                            return tr("JPEG images (*.jpg)");
-                        }
-                    });
+            fc.setFileFilter(JPEG_FILE_FILTER);
             
             fc.showOpenDialog(Main.parent);
@@ -65,22 +67,10 @@
             }
             
-            List<File> files = new ArrayList<File>();
-            addRecursiveFiles(files, sel);
             Main.pref.put("tagimages.lastdirectory", fc.getCurrentDirectory().getPath());
             
-            AgpifojLayer.create(files);
-        }
-
-        private void addRecursiveFiles(List<File> files, File[] sel) {
-            for (File f : sel) {
-                if (f.isDirectory()) {
-                    addRecursiveFiles(files, f.listFiles());
-                } else if (f.getName().toLowerCase().endsWith(".jpg")) {
-                    files.add(f);
-                }
-            }
+            AgpifojLayer.create(sel);
         }
     }
-
+    
     public AgpifojPlugin() {
         MainMenu.add(Main.main.menu.fileMenu, new Action());
@@ -88,5 +78,5 @@
 
     /**
-     * Called after Main.mapFrame is initalized. (After the first data is loaded).
+     * Called after Main.mapFrame is initialized. (After the first data is loaded).
      * You can use this callback to tweak the newFrame to your needs, as example install
      * an alternative Painter.
@@ -109,5 +99,3 @@
         }
     }
-
-
 }
Index: /applications/editors/josm/plugins/agpifoj/src/org/openstreetmap/josm/plugins/agpifoj/CorrelateGpxWithImages.java
===================================================================
--- /applications/editors/josm/plugins/agpifoj/src/org/openstreetmap/josm/plugins/agpifoj/CorrelateGpxWithImages.java	(revision 12746)
+++ /applications/editors/josm/plugins/agpifoj/src/org/openstreetmap/josm/plugins/agpifoj/CorrelateGpxWithImages.java	(revision 12747)
@@ -334,14 +334,5 @@
                     fc.setMultiSelectionEnabled(false);
                     fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
-                    fc.setFileFilter(new FileFilter(){
-                        @Override public boolean accept(File f) {
-                            return (f.isDirectory()
-                                    || f .getName().toLowerCase().endsWith(".jpg") 
-                                    || f.getName().toLowerCase().endsWith(".jpeg"));
-                        }
-                        @Override public String getDescription() {
-                            return tr("JPEG images (*.jpg)");
-                        }
-                    });
+                    fc.setFileFilter(AgpifojPlugin.JPEG_FILE_FILTER);
                     fc.showOpenDialog(Main.parent);
                     File sel = fc.getSelectedFile();
