Index: trunk/src/org/openstreetmap/josm/actions/OpenFileAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/OpenFileAction.java	(revision 2850)
+++ trunk/src/org/openstreetmap/josm/actions/OpenFileAction.java	(revision 2851)
@@ -23,5 +23,4 @@
 import org.openstreetmap.josm.io.AllFormatsImporter;
 import org.openstreetmap.josm.io.FileImporter;
-import org.openstreetmap.josm.io.IllegalDataException;
 import org.openstreetmap.josm.io.OsmTransferException;
 import org.openstreetmap.josm.tools.MultiMap;
@@ -110,5 +109,5 @@
                 chosenImporter = null;
             }
-            getProgressMonitor().setTicks(files.size());
+            getProgressMonitor().setTicksCount(files.size());
 
             if (chosenImporter != null) { // The importer was expicitely chosen, so use it.
@@ -132,15 +131,14 @@
             else {    // find apropriate importer
                 MultiMap<FileImporter, File> map = new MultiMap<FileImporter, File>();
-                while (! files.isEmpty()) {
-                    File f = files.get(0);
-                    for (FileImporter importer : ExtensionFileFilter.importers) {
-                        if (importer.acceptFile(f)) {
-                            map.add(importer, f);
-                            files.remove(f);
+                FILES:
+                    for (File f: files) {
+                        for (FileImporter importer : ExtensionFileFilter.importers) {
+                            if (importer.acceptFile(f)) {
+                                map.add(importer, f);
+                                continue FILES;
+                            }
                         }
+                        throw new RuntimeException(); // no importer found
                     }
-                    if (files.contains(f))
-                        throw new RuntimeException(); // no importer found
-                }
                 List<FileImporter> ims = new ArrayList<FileImporter>(map.keySet());
                 Collections.sort(ims);
@@ -165,12 +163,10 @@
                 }
                 getProgressMonitor().indeterminateSubTask(msg);
-                importer.importDataHandleExceptions(files);
-                getProgressMonitor().worked(files.size());
+                importer.importDataHandleExceptions(files, getProgressMonitor().createSubTaskMonitor(files.size(), false));
             } else {
                 for (File f : files) {
                     if (cancelled) return;
                     getProgressMonitor().indeterminateSubTask(tr("Opening file ''{0}'' ...", f.getAbsolutePath()));
-                    importer.importDataHandleExceptions(f);
-                    getProgressMonitor().worked(1);
+                    importer.importDataHandleExceptions(f, getProgressMonitor().createSubTaskMonitor(1, false));
                 }
             }
Index: trunk/src/org/openstreetmap/josm/gui/layer/GpxLayer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/GpxLayer.java	(revision 2850)
+++ trunk/src/org/openstreetmap/josm/gui/layer/GpxLayer.java	(revision 2851)
@@ -66,4 +66,5 @@
 import org.openstreetmap.josm.gui.layer.markerlayer.AudioMarker;
 import org.openstreetmap.josm.gui.layer.markerlayer.MarkerLayer;
+import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
 import org.openstreetmap.josm.gui.progress.PleaseWaitProgressMonitor;
 import org.openstreetmap.josm.io.JpgImporter;
@@ -284,12 +285,10 @@
                     MarkerLayer ml = new MarkerLayer(new GpxData(), tr("Audio markers from {0}", getName()) + names,
                             getAssociatedFile(), me);
-                    if (sel != null) {
-                        double firstStartTime = sel[0].lastModified() / 1000.0 /* ms -> seconds */
-                        - AudioUtil.getCalibratedDuration(sel[0]);
-
-                        Markers m = new Markers();
-                        for (int i = 0; i < sel.length; i++) {
-                            importAudio(sel[i], ml, firstStartTime, m);
-                        }
+                    double firstStartTime = sel[0].lastModified() / 1000.0 /* ms -> seconds */
+                    - AudioUtil.getCalibratedDuration(sel[0]);
+
+                    Markers m = new Markers();
+                    for (int i = 0; i < sel.length; i++) {
+                        importAudio(sel[i], ml, firstStartTime, m);
                     }
                     Main.main.addLayer(ml);
@@ -334,5 +333,5 @@
                     return;
                 addRecursiveFiles(files, sel);
-                importer.importDataHandleExceptions(files);
+                importer.importDataHandleExceptions(files, NullProgressMonitor.INSTANCE);
             }
 
@@ -526,5 +525,5 @@
          ****************************************************************/
         if ((computeCacheMaxLineLengthUsed != maxLineLength) || (!neutralColor.equals(computeCacheColorUsed))
-                        || (computeCacheColored != colored) || (computeCacheColorTracksTune != colorTracksTune)) {
+                || (computeCacheColored != colored) || (computeCacheColorTracksTune != colorTracksTune)) {
             // System.out.println("(re-)computing gpx line styles, reason: CCIS=" +
             // computeCacheInSync + " CCMLLU=" + (computeCacheMaxLineLengthUsed != maxLineLength) +
Index: trunk/src/org/openstreetmap/josm/io/FileImporter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/FileImporter.java	(revision 2850)
+++ trunk/src/org/openstreetmap/josm/io/FileImporter.java	(revision 2851)
@@ -12,8 +12,9 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.actions.ExtensionFileFilter;
+import org.openstreetmap.josm.gui.progress.ProgressMonitor;
 
 public abstract class FileImporter implements Comparable<FileImporter> {
 
-    public ExtensionFileFilter filter;
+    public final ExtensionFileFilter filter;
 
     public FileImporter(ExtensionFileFilter filter) {
@@ -34,6 +35,7 @@
     /**
      * Needs to be implemented if isBatchImporter() returns false.
+     * @throws IllegalDataException
      */
-    public void importData(File file) throws IOException, IllegalDataException {
+    public void importData(File file, ProgressMonitor progressMonitor) throws IOException, IllegalDataException {
         throw new IOException(tr("Could not import ''{0}''.", file.getName()));
     }
@@ -41,6 +43,7 @@
     /**
      * Needs to be implemented if isBatchImporter() returns true.
+     * @throws IllegalDataException
      */
-    public void importData(List<File> files) throws IOException, IllegalDataException {
+    public void importData(List<File> files, ProgressMonitor progressMonitor) throws IOException, IllegalDataException {
         throw new IOException(tr("Could not import files."));
     }
@@ -49,8 +52,8 @@
      * Wrapper to give meaningful output if things go wrong.
      */
-    public void importDataHandleExceptions(File f) {
+    public void importDataHandleExceptions(File f, ProgressMonitor progressMonitor) {
         try {
             System.out.println("Open file: " + f.getAbsolutePath() + " (" + f.length() + " bytes)");
-            importData(f);
+            importData(f, progressMonitor);
         } catch (Exception e) {
             e.printStackTrace();
@@ -63,8 +66,8 @@
         }
     }
-    public void importDataHandleExceptions(List<File> files) {
+    public void importDataHandleExceptions(List<File> files, ProgressMonitor progressMonitor) {
         try {
             System.out.println("Open "+files.size()+" files");
-            importData(files);
+            importData(files, progressMonitor);
         } catch (Exception e) {
             e.printStackTrace();
@@ -90,3 +93,4 @@
         return (new Double(this.getPriority())).compareTo(other.getPriority());
     }
+
 }
Index: trunk/src/org/openstreetmap/josm/io/GpxImporter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/GpxImporter.java	(revision 2850)
+++ trunk/src/org/openstreetmap/josm/io/GpxImporter.java	(revision 2851)
@@ -18,4 +18,5 @@
 import org.openstreetmap.josm.gui.layer.GpxLayer;
 import org.openstreetmap.josm.gui.layer.markerlayer.MarkerLayer;
+import org.openstreetmap.josm.gui.progress.ProgressMonitor;
 import org.xml.sax.SAXException;
 
@@ -26,5 +27,5 @@
     }
 
-    @Override public void importData(final File file) throws IOException {
+    @Override public void importData(final File file, ProgressMonitor progressMonitor) throws IOException {
         final String fn = file.getName();
 
Index: trunk/src/org/openstreetmap/josm/io/IllegalDataException.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/IllegalDataException.java	(revision 2850)
+++ trunk/src/org/openstreetmap/josm/io/IllegalDataException.java	(revision 2851)
@@ -6,20 +6,16 @@
     public IllegalDataException() {
         super();
-        // TODO Auto-generated constructor stub
     }
 
     public IllegalDataException(String message, Throwable cause) {
         super(message, cause);
-        // TODO Auto-generated constructor stub
     }
 
     public IllegalDataException(String message) {
         super(message);
-        // TODO Auto-generated constructor stub
     }
 
     public IllegalDataException(Throwable cause) {
         super(cause);
-        // TODO Auto-generated constructor stub
     }
 
Index: trunk/src/org/openstreetmap/josm/io/JpgImporter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/JpgImporter.java	(revision 2850)
+++ trunk/src/org/openstreetmap/josm/io/JpgImporter.java	(revision 2851)
@@ -6,11 +6,14 @@
 import java.io.File;
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.LinkedList;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 import org.openstreetmap.josm.actions.ExtensionFileFilter;
 import org.openstreetmap.josm.gui.layer.GpxLayer;
 import org.openstreetmap.josm.gui.layer.geoimage.GeoImageLayer;
+import org.openstreetmap.josm.gui.progress.ProgressMonitor;
 
 public class JpgImporter extends FileImporter {
@@ -32,20 +35,49 @@
 
     @Override
-    public void importData(List<File> sel) throws IOException, IllegalDataException {
-        if (sel == null || sel.size() == 0)
-            return;
-        LinkedList<File> files = new LinkedList<File>();
-        addRecursiveFiles(files, sel);
-        if(files.isEmpty()) throw new IOException(tr("No image files found."));
-        GeoImageLayer.create(files, gpx);
+    public void importData(List<File> sel, ProgressMonitor progressMonitor) throws IOException, IllegalDataException {
+        progressMonitor.beginTask(tr("Looking for image files"), 1);
+        try {
+            List<File> files = new ArrayList<File>();
+            Set<String> visitedDirs = new HashSet<String>();
+            addRecursiveFiles(files, visitedDirs, sel, progressMonitor.createSubTaskMonitor(1, true));
+
+            if (progressMonitor.isCancelled())
+                return;
+
+            if (files.isEmpty())
+                throw new IOException(tr("No image files found."));
+
+            GeoImageLayer.create(files, gpx);
+        } finally {
+            progressMonitor.finishTask();
+        }
     }
 
-    private void addRecursiveFiles(LinkedList<File> files, List<File> sel) {
-        for (File f : sel) {
-            if (f.isDirectory()) {
-                addRecursiveFiles(files, Arrays.asList(f.listFiles()));
-            } else if (f.getName().toLowerCase().endsWith(".jpg")) {
-                files.add(f);
+    private void addRecursiveFiles(List<File> files, Set<String> visitedDirs, List<File> sel, ProgressMonitor progressMonitor) throws IOException {
+
+        if (progressMonitor.isCancelled())
+            return;
+
+        progressMonitor.beginTask(null, sel.size());
+        try {
+            for (File f : sel) {
+                if (f.isDirectory()) {
+                    if (visitedDirs.add(f.getCanonicalPath())) { // Do not loop over symlinks
+                        File[] dirFiles = f.listFiles(); // Can be null for some strange directories (like lost+found)
+                        if (dirFiles != null) {
+                            addRecursiveFiles(files, visitedDirs, Arrays.asList(dirFiles), progressMonitor.createSubTaskMonitor(1, true));
+                        }
+                    } else {
+                        progressMonitor.worked(1);
+                    }
+                } else {
+                    if (f.getName().toLowerCase().endsWith(".jpg")) {
+                        files.add(f);
+                    }
+                    progressMonitor.worked(1);
+                }
             }
+        } finally {
+            progressMonitor.finishTask();
         }
     }
Index: trunk/src/org/openstreetmap/josm/io/NMEAImporter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/NMEAImporter.java	(revision 2850)
+++ trunk/src/org/openstreetmap/josm/io/NMEAImporter.java	(revision 2851)
@@ -14,4 +14,5 @@
 import org.openstreetmap.josm.gui.layer.GpxLayer;
 import org.openstreetmap.josm.gui.layer.markerlayer.MarkerLayer;
+import org.openstreetmap.josm.gui.progress.ProgressMonitor;
 
 public class NMEAImporter extends FileImporter {
@@ -23,5 +24,5 @@
     }
 
-    @Override public void importData(File file) throws IOException {
+    @Override public void importData(File file, ProgressMonitor progressMonitor) throws IOException {
         String fn = file.getName();
         NmeaReader r = new NmeaReader(new FileInputStream(file), file.getAbsoluteFile().getParentFile());
Index: trunk/src/org/openstreetmap/josm/io/OsmBzip2Importer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OsmBzip2Importer.java	(revision 2850)
+++ trunk/src/org/openstreetmap/josm/io/OsmBzip2Importer.java	(revision 2851)
@@ -11,4 +11,5 @@
 import org.apache.tools.bzip2.CBZip2InputStream;
 import org.openstreetmap.josm.actions.ExtensionFileFilter;
+import org.openstreetmap.josm.gui.progress.ProgressMonitor;
 
 public class OsmBzip2Importer extends OsmImporter {
@@ -20,5 +21,5 @@
 
     @Override
-    public void importData(File file) throws IOException, IllegalDataException {
+    public void importData(File file, ProgressMonitor progressMonitor) throws IOException, IllegalDataException {
         BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
         int b = bis.read();
Index: trunk/src/org/openstreetmap/josm/io/OsmGzipImporter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OsmGzipImporter.java	(revision 2850)
+++ trunk/src/org/openstreetmap/josm/io/OsmGzipImporter.java	(revision 2851)
@@ -10,4 +10,5 @@
 
 import org.openstreetmap.josm.actions.ExtensionFileFilter;
+import org.openstreetmap.josm.gui.progress.ProgressMonitor;
 
 public class OsmGzipImporter extends OsmImporter {
@@ -18,5 +19,5 @@
 
     @Override
-    public void importData(File file) throws IOException, IllegalDataException {
+    public void importData(File file, ProgressMonitor progressMonitor) throws IOException, IllegalDataException {
         GZIPInputStream in = new GZIPInputStream(new FileInputStream(file));
         importData(in, file);
Index: trunk/src/org/openstreetmap/josm/io/OsmImporter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OsmImporter.java	(revision 2850)
+++ trunk/src/org/openstreetmap/josm/io/OsmImporter.java	(revision 2851)
@@ -17,4 +17,5 @@
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
 import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
+import org.openstreetmap.josm.gui.progress.ProgressMonitor;
 
 public class OsmImporter extends FileImporter {
@@ -28,5 +29,5 @@
     }
 
-    @Override public void importData(File file) throws IOException, IllegalDataException {
+    @Override public void importData(File file, ProgressMonitor progressMonitor) throws IOException, IllegalDataException {
         try {
             FileInputStream in = new FileInputStream(file);
