Index: /Users/mueck/dev/josm/src/org/openstreetmap/josm/actions/DiskAccessAction.java
===================================================================
--- /Users/mueck/dev/josm/src/org/openstreetmap/josm/actions/DiskAccessAction.java	(revision 1632)
+++ /Users/mueck/dev/josm/src/org/openstreetmap/josm/actions/DiskAccessAction.java	(working copy)
@@ -4,7 +4,6 @@
 import static org.openstreetmap.josm.tools.I18n.tr;
 
 import java.io.File;
-
 import javax.swing.JFileChooser;
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.gui.ExtendedDialog;
@@ -9,6 +8,7 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.gui.ExtendedDialog;
 import org.openstreetmap.josm.tools.Shortcut;
+import org.openstreetmap.josm.io.FileImporter;
 
 /**
  * Helper class for all actions that access the disk
@@ -24,12 +24,14 @@
         if (curDir.equals(""))
             curDir = ".";
         JFileChooser fc = new JFileChooser(new File(curDir));
-        if(title != null)
+        if (title != null)
             fc.setDialogTitle(title);
 
         fc.setMultiSelectionEnabled(multiple);
-        for (int i = 0; i < ExtensionFileFilter.filters.length; ++i)
-            fc.addChoosableFileFilter(ExtensionFileFilter.filters[i]);
+        for (FileImporter imExporter: ExtensionFileFilter.importers) {
+            fc.addChoosableFileFilter(imExporter.filter);
+        }
+
         fc.setAcceptAllFileFilterUsed(true);
 
         int answer = open ? fc.showOpenDialog(Main.parent) : fc.showSaveDialog(Main.parent);
Index: /Users/mueck/dev/josm/src/org/openstreetmap/josm/actions/ExtensionFileFilter.java
===================================================================
--- /Users/mueck/dev/josm/src/org/openstreetmap/josm/actions/ExtensionFileFilter.java	(revision 1632)
+++ /Users/mueck/dev/josm/src/org/openstreetmap/josm/actions/ExtensionFileFilter.java	(working copy)
@@ -1,12 +1,17 @@
 // License: GPL. Copyright 2007 by Immanuel Scholz and others
 package org.openstreetmap.josm.actions;
 
-import static org.openstreetmap.josm.tools.I18n.tr;
-
 import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
 
 import javax.swing.filechooser.FileFilter;
 
+import org.openstreetmap.josm.io.FileImporter;
+import org.openstreetmap.josm.io.GpxImporter;
+import org.openstreetmap.josm.io.NMEAImporter;
+import org.openstreetmap.josm.io.OsmImporter;
+
 /**
  * A file filter that filters after the extension. Also includes a list of file
  * filters used in JOSM.
@@ -18,15 +23,8 @@
     private final String description;
     public final String defaultExtension;
 
-    public static final int OSM = 0;
-    public static final int GPX = 1;
-    public static final int NMEA = 2;
-
-    public static ExtensionFileFilter[] filters = {
-        new ExtensionFileFilter("osm,xml", "osm", tr("OSM Server Files")+ " (*.osm *.xml)"),
-        new ExtensionFileFilter("gpx,gpx.gz", "gpx", tr("GPX Files") + " (*.gpx *.gpx.gz)"),
-        new ExtensionFileFilter("nmea,nme,nma,txt", "nmea", tr("NMEA-0183 Files") + " (*.nmea *.nme *.nma *.txt)"),
-    };
+    public static ArrayList<FileImporter> importers = new ArrayList<FileImporter>(Arrays.asList(new OsmImporter(),
+            new GpxImporter(), new NMEAImporter()));
 
     /**
      * Construct an extension file filter by giving the extension to check after.
Index: /Users/mueck/dev/josm/src/org/openstreetmap/josm/actions/OpenFileAction.java
===================================================================
--- /Users/mueck/dev/josm/src/org/openstreetmap/josm/actions/OpenFileAction.java	(revision 1632)
+++ /Users/mueck/dev/josm/src/org/openstreetmap/josm/actions/OpenFileAction.java	(working copy)
@@ -5,12 +5,8 @@
 
 import java.awt.event.ActionEvent;
 import java.awt.event.KeyEvent;
-import java.io.InputStream;
 import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
 import java.io.IOException;
-import java.util.zip.GZIPInputStream;
 
 import javax.swing.JFileChooser;
 import javax.swing.JOptionPane;
@@ -16,19 +12,12 @@
 import javax.swing.JOptionPane;
 
 import org.openstreetmap.josm.Main;
-import org.openstreetmap.josm.data.osm.DataSet;
-import org.openstreetmap.josm.gui.layer.GpxLayer;
-import org.openstreetmap.josm.gui.layer.OsmDataLayer;
-import org.openstreetmap.josm.gui.layer.markerlayer.MarkerLayer;
-import org.openstreetmap.josm.io.GpxReader;
-import org.openstreetmap.josm.io.NmeaReader;
-import org.openstreetmap.josm.io.OsmReader;
-import org.xml.sax.SAXException;
+import org.openstreetmap.josm.io.FileImporter;
 import org.openstreetmap.josm.tools.Shortcut;
 
 /**
- * Open a file chooser dialog and select an file to import. Then call the gpx-import
- * driver. Finally open an internal frame into the main window with the gpx data shown.
+ * Open a file chooser dialog and select an file to import. Then call the gpx-import driver. Finally
+ * open an internal frame into the main window with the gpx data shown.
  *
  * @author imi
  */
@@ -57,126 +47,14 @@
     public void openFile(File file) {
         try {
             System.out.println("Open file: " + file.getAbsolutePath() + " (" + file.length() + " bytes)");
-            if (asGpxData(file.getName()))
-                openFileAsGpx(file);
-            else if (asNmeaData(file.getName()))
-                openFileAsNmea(file);
-            else
-                openAsData(file);
-        } catch (SAXException x) {
-            x.printStackTrace();
-            JOptionPane.showMessageDialog(Main.parent, tr("Error while parsing {0}",file.getName())+": "+x.getMessage());
+            for (FileImporter importer : ExtensionFileFilter.importers)
+                if (importer.acceptFile(file))
+                    importer.importData(file);
         } catch (IOException x) {
             x.printStackTrace();
-            JOptionPane.showMessageDialog(Main.parent, tr("Could not read \"{0}\"",file.getName())+"\n"+x.getMessage());
-        }
-    }
-
-    private void openAsData(File file) throws SAXException, IOException, FileNotFoundException {
-        String fn = file.getName();
-        if (ExtensionFileFilter.filters[ExtensionFileFilter.OSM].acceptName(fn)) {
-            OsmReader osm = OsmReader.parseDataSetOsm(new FileInputStream(file), null, Main.pleaseWaitDlg);
-            DataSet dataSet = osm.getDs();
-            OsmDataLayer layer = new OsmDataLayer(dataSet, file.getName(), file);
-            Main.main.addLayer(layer);
-            layer.fireDataChange();
-            if (osm.getParseNotes().length() != 0) {
-                /* display at most five lines */
-                String notes = osm.getParseNotes();
-                int j = 0;
-                for (int i = 0; i < 5; i++) {
-                    j = notes.indexOf('\n', j + 1);
-                }
-                j = j >= 0 ? j : notes.length();
-                JOptionPane.showMessageDialog(Main.parent, notes.substring(0, j));
-            }
-        }
-        else
-            JOptionPane.showMessageDialog(Main.parent, fn+": "+tr("Unknown file extension: {0}", fn.substring(file.getName().lastIndexOf('.')+1)));
-    }
-
-    private void openFileAsGpx(File file) throws SAXException, IOException, FileNotFoundException {
-        String fn = file.getName();
-        if (ExtensionFileFilter.filters[ExtensionFileFilter.GPX].acceptName(fn)) {
-            GpxReader r = null;
-            InputStream is;
-            if (file.getName().endsWith(".gpx.gz")) {
-                is = new GZIPInputStream(new FileInputStream(file));
-            } else {
-                is = new FileInputStream(file);
-            }
-            // Workaround for SAX BOM bug
-            // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6206835
-            if(!((is.read()==0xef)&&(is.read()==0xbb)&&(is.read()==0xbf))) {
-                is.close();
-                if (file.getName().endsWith(".gpx.gz")) {
-                    is = new GZIPInputStream(new FileInputStream(file));
-                } else {
-                    is = new FileInputStream(file);
-                }
-            }
-            r = new GpxReader(is,file.getAbsoluteFile().getParentFile());
-            r.data.storageFile = file;
-            GpxLayer gpxLayer = new GpxLayer(r.data, fn, true);
-            Main.main.addLayer(gpxLayer);
-            if (Main.pref.getBoolean("marker.makeautomarkers", true)) {
-                MarkerLayer ml = new MarkerLayer(r.data, tr("Markers from {0}", fn), file, gpxLayer);
-                if (ml.data.size() > 0) {
-                    Main.main.addLayer(ml);
-                }
-            }
-
-        } else {
-            throw new IllegalStateException();
-        }
-    }
-
-    private void showNmeaInfobox(boolean success, NmeaReader r) {
-        String msg = tr("Coordinates imported: ") + r.getNumberOfCoordinates() + "\n" +
-        tr("Malformed sentences: ") + r.getParserMalformed() + "\n" +
-        tr("Checksum errors: ") + r.getParserChecksumErrors() + "\n";
-        if(!success) // don't scare the user unneccessarily
-            msg += tr("Unknown sentences: ") + r.getParserUnknown() + "\n";
-        msg += tr("Zero coordinates: ") + r.getParserZeroCoordinates();
-        if(success) {
-            JOptionPane.showMessageDialog(
-                Main.parent, msg,
-                tr("NMEA import success"),JOptionPane.INFORMATION_MESSAGE);
-        } else {
-            JOptionPane.showMessageDialog(
-                Main.parent, msg,
-                tr("NMEA import faliure!"),JOptionPane.ERROR_MESSAGE);
-        }
-    }
-
-    private void openFileAsNmea(File file) throws IOException, FileNotFoundException {
-        String fn = file.getName();
-        if (ExtensionFileFilter.filters[ExtensionFileFilter.NMEA].acceptName(fn)) {
-            NmeaReader r = new NmeaReader(new FileInputStream(file), file.getAbsoluteFile().getParentFile());
-            if(r.getNumberOfCoordinates()>0) {
-                r.data.storageFile = file;
-                GpxLayer gpxLayer = new GpxLayer(r.data, fn, true);
-                Main.main.addLayer(gpxLayer);
-                if (Main.pref.getBoolean("marker.makeautomarkers", true)) {
-                    MarkerLayer ml = new MarkerLayer(r.data, tr("Markers from {0}", fn), file, gpxLayer);
-                    if (ml.data.size() > 0) {
-                        Main.main.addLayer(ml);
-                    }
-                }
-            }
-            showNmeaInfobox(r.getNumberOfCoordinates()>0, r);
-        } else {
-            throw new IllegalStateException();
+            JOptionPane.showMessageDialog(Main.parent, tr("Could not read \"{0}\"", file.getName()) + "\n"
+                    + x.getMessage());
         }
     }
 
-    private boolean asGpxData(String fn) {
-        return ExtensionFileFilter.filters[ExtensionFileFilter.GPX].acceptName(fn);
-    }
-
-    private boolean asNmeaData(String fn) {
-        return ExtensionFileFilter.filters[ExtensionFileFilter.NMEA].acceptName(fn);
-    }
-
-
 }
Index: /Users/mueck/dev/josm/src/org/openstreetmap/josm/actions/SaveActionBase.java
===================================================================
--- /Users/mueck/dev/josm/src/org/openstreetmap/josm/actions/SaveActionBase.java	(revision 1632)
+++ /Users/mueck/dev/josm/src/org/openstreetmap/josm/actions/SaveActionBase.java	(working copy)
@@ -21,7 +21,9 @@
 import org.openstreetmap.josm.gui.layer.GpxLayer;
 import org.openstreetmap.josm.gui.layer.Layer;
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
+import org.openstreetmap.josm.io.GpxImporter;
 import org.openstreetmap.josm.io.GpxWriter;
+import org.openstreetmap.josm.io.OsmImporter;
 import org.openstreetmap.josm.io.OsmWriter;
 import org.openstreetmap.josm.tools.Shortcut;
 
@@ -149,9 +147,11 @@
     public static void save(File file, OsmDataLayer layer) {
         File tmpFile = null;
         try {
-            if (ExtensionFileFilter.filters[ExtensionFileFilter.GPX].acceptName(file.getPath())) {
+            GpxImporter gpxImExporter = new GpxImporter();
+            OsmImporter osmImExporter = new OsmImporter();
+            if (gpxImExporter.acceptFile(file))
                 GpxExportAction.exportGpx(file, layer);
-            } else if (ExtensionFileFilter.filters[ExtensionFileFilter.OSM].acceptName(file.getPath())) {
+            else if (osmImExporter.acceptFile(file)) {
                 // use a tmp file because if something errors out in the
                 // process of writing the file, we might just end up with
                 // a truncated file.  That can destroy lots of work.
@@ -193,7 +192,8 @@
     public static void save(File file, GpxLayer layer) {
         File tmpFile = null;
         try {
-            if (ExtensionFileFilter.filters[ExtensionFileFilter.GPX].acceptName(file.getPath())) {
+            GpxImporter gpxImExporter = new GpxImporter();
+            if (gpxImExporter.acceptFile(file)) {
 
                 // use a tmp file because if something errors out in the
                 // process of writing the file, we might just end up with
Index: /Users/mueck/dev/josm/src/org/openstreetmap/josm/io/FileImporter.java
===================================================================
--- /Users/mueck/dev/josm/src/org/openstreetmap/josm/io/FileImporter.java	(revision 0)
+++ /Users/mueck/dev/josm/src/org/openstreetmap/josm/io/FileImporter.java	(revision 0)
@@ -0,0 +1,27 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.io;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.openstreetmap.josm.actions.ExtensionFileFilter;
+
+public abstract class FileImporter {
+
+    public ExtensionFileFilter filter;
+
+    public FileImporter(ExtensionFileFilter filter) {
+        this.filter = filter;
+    }
+
+    public boolean acceptFile(File pathname) {
+        return filter.acceptName(pathname.getName());
+    }
+
+    public void importData(File file) throws IOException {
+        throw new IOException(tr("Could not read \"{0}\"", file.getName()));
+    }
+
+}
Index: /Users/mueck/dev/josm/src/org/openstreetmap/josm/io/GpxImporter.java
===================================================================
--- /Users/mueck/dev/josm/src/org/openstreetmap/josm/io/GpxImporter.java	(revision 0)
+++ /Users/mueck/dev/josm/src/org/openstreetmap/josm/io/GpxImporter.java	(revision 0)
@@ -0,0 +1,59 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.io;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.zip.GZIPInputStream;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.actions.ExtensionFileFilter;
+import org.openstreetmap.josm.gui.layer.GpxLayer;
+import org.openstreetmap.josm.gui.layer.markerlayer.MarkerLayer;
+import org.xml.sax.SAXException;
+
+public class GpxImporter extends FileImporter {
+
+    public GpxImporter() {
+        super(new ExtensionFileFilter("gpx,gpx.gz", "gpx", tr("GPX Files") + " (*.gpx *.gpx.gz)"));
+    }
+
+    @Override public void importData(File file) throws IOException {
+        String fn = file.getName();
+
+        try {
+            GpxReader r = null;
+            InputStream is;
+            if (file.getName().endsWith(".gpx.gz"))
+                is = new GZIPInputStream(new FileInputStream(file));
+            else
+                is = new FileInputStream(file);
+            // Workaround for SAX BOM bug
+            // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6206835
+            if (!((is.read() == 0xef) && (is.read() == 0xbb) && (is.read() == 0xbf))) {
+                is.close();
+                if (file.getName().endsWith(".gpx.gz"))
+                    is = new GZIPInputStream(new FileInputStream(file));
+                else
+                    is = new FileInputStream(file);
+            }
+            r = new GpxReader(is, file.getAbsoluteFile().getParentFile());
+            r.data.storageFile = file;
+            GpxLayer gpxLayer = new GpxLayer(r.data, fn, true);
+            Main.main.addLayer(gpxLayer);
+            if (Main.pref.getBoolean("marker.makeautomarkers", true)) {
+                MarkerLayer ml = new MarkerLayer(r.data, tr("Markers from {0}", fn), file, gpxLayer);
+                if (ml.data.size() > 0)
+                    Main.main.addLayer(ml);
+            }
+        } catch (SAXException e) {
+            e.printStackTrace();
+            throw new IOException(tr("Could not read \"{0}\"", file.getName()));
+        }
+
+    }
+
+}
Index: /Users/mueck/dev/josm/src/org/openstreetmap/josm/io/NMEAImporter.java
===================================================================
--- /Users/mueck/dev/josm/src/org/openstreetmap/josm/io/NMEAImporter.java	(revision 0)
+++ /Users/mueck/dev/josm/src/org/openstreetmap/josm/io/NMEAImporter.java	(revision 0)
@@ -0,0 +1,55 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.io;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+
+import javax.swing.JOptionPane;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.actions.ExtensionFileFilter;
+import org.openstreetmap.josm.gui.layer.GpxLayer;
+import org.openstreetmap.josm.gui.layer.markerlayer.MarkerLayer;
+
+public class NMEAImporter extends FileImporter {
+
+    public NMEAImporter() {
+        super(
+                new ExtensionFileFilter("nmea,nme,nma,txt", "nmea", tr("NMEA-0183 Files")
+                        + " (*.nmea *.nme *.nma *.txt)"));
+    }
+
+    @Override public void importData(File file) throws IOException {
+        String fn = file.getName();
+        NmeaReader r = new NmeaReader(new FileInputStream(file), file.getAbsoluteFile().getParentFile());
+        if (r.getNumberOfCoordinates() > 0) {
+            r.data.storageFile = file;
+            GpxLayer gpxLayer = new GpxLayer(r.data, fn, true);
+            Main.main.addLayer(gpxLayer);
+            if (Main.pref.getBoolean("marker.makeautomarkers", true)) {
+                MarkerLayer ml = new MarkerLayer(r.data, tr("Markers from {0}", fn), file, gpxLayer);
+                if (ml.data.size() > 0) {
+                    Main.main.addLayer(ml);
+                }
+            }
+        }
+        showNmeaInfobox(r.getNumberOfCoordinates() > 0, r);
+    }
+
+    private void showNmeaInfobox(boolean success, NmeaReader r) {
+        String msg = tr("Coordinates imported: ") + r.getNumberOfCoordinates() + "\n" + tr("Malformed sentences: ")
+                + r.getParserMalformed() + "\n" + tr("Checksum errors: ") + r.getParserChecksumErrors() + "\n";
+        if (!success) // don't scare the user unneccessarily
+            msg += tr("Unknown sentences: ") + r.getParserUnknown() + "\n";
+        msg += tr("Zero coordinates: ") + r.getParserZeroCoordinates();
+        if (success) {
+            JOptionPane.showMessageDialog(Main.parent, msg, tr("NMEA import success"), JOptionPane.INFORMATION_MESSAGE);
+        } else {
+            JOptionPane.showMessageDialog(Main.parent, msg, tr("NMEA import faliure!"), JOptionPane.ERROR_MESSAGE);
+        }
+    }
+
+}
Index: /Users/mueck/dev/josm/src/org/openstreetmap/josm/io/OsmImporter.java
===================================================================
--- /Users/mueck/dev/josm/src/org/openstreetmap/josm/io/OsmImporter.java	(revision 0)
+++ /Users/mueck/dev/josm/src/org/openstreetmap/josm/io/OsmImporter.java	(revision 0)
@@ -0,0 +1,53 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.io;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import java.awt.HeadlessException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+import javax.swing.JOptionPane;
+
+import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.actions.ExtensionFileFilter;
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.gui.layer.OsmDataLayer;
+import org.xml.sax.SAXException;
+
+public class OsmImporter extends FileImporter {
+
+    public OsmImporter() {
+        super(new ExtensionFileFilter("osm,xml", "osm", tr("OSM Server Files") + " (*.osm *.xml)"));
+    }
+
+    @Override public void importData(File file) throws IOException {
+        try {
+            OsmReader osm = OsmReader.parseDataSetOsm(new FileInputStream(file), null, Main.pleaseWaitDlg);
+            DataSet dataSet = osm.getDs();
+            OsmDataLayer layer = new OsmDataLayer(dataSet, file.getName(), file);
+            Main.main.addLayer(layer);
+            layer.fireDataChange();
+            if (osm.getParseNotes().length() != 0) {
+                /* display at most five lines */
+                String notes = osm.getParseNotes();
+                int j = 0;
+                for (int i = 0; i < 5; i++)
+                    j = notes.indexOf('\n', j + 1);
+                j = j >= 0 ? j : notes.length();
+                JOptionPane.showMessageDialog(Main.parent, notes.substring(0, j));
+            }
+        } catch (HeadlessException e) {
+            e.printStackTrace();
+            throw new IOException(tr("Could not read \"{0}\"", file.getName()));
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+            throw new IOException(tr("Could not read \"{0}\"", file.getName()));
+        } catch (SAXException e) {
+            e.printStackTrace();
+            throw new IOException(tr("Could not read \"{0}\"", file.getName()));
+        }
+    }
+}
