Index: trunk/src/org/openstreetmap/josm/data/coor/Coordinate.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/coor/Coordinate.java	(revision 6905)
+++ trunk/src/org/openstreetmap/josm/data/coor/Coordinate.java	(revision 6906)
@@ -113,8 +113,7 @@
     }
 
-    @Override
-    public int hashCode() {
+    protected final int computeHashCode(int init) {
         final int prime = 31;
-        int result = 1;
+        int result = init;
         long temp;
         temp = java.lang.Double.doubleToLongBits(x);
@@ -123,4 +122,9 @@
         result = prime * result + (int) (temp ^ (temp >>> 32));
         return result;
+    }
+
+    @Override
+    public int hashCode() {
+        return computeHashCode(1);
     }
 
Index: trunk/src/org/openstreetmap/josm/data/coor/LatLon.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/coor/LatLon.java	(revision 6905)
+++ trunk/src/org/openstreetmap/josm/data/coor/LatLon.java	(revision 6906)
@@ -410,12 +410,5 @@
     @Override
     public int hashCode() {
-        final int prime = 31;
-        int result = super.hashCode();
-        long temp;
-        temp = java.lang.Double.doubleToLongBits(x);
-        result = prime * result + (int) (temp ^ (temp >>> 32));
-        temp = java.lang.Double.doubleToLongBits(y);
-        result = prime * result + (int) (temp ^ (temp >>> 32));
-        return result;
+        return computeHashCode(super.hashCode());
     }
 
Index: trunk/src/org/openstreetmap/josm/gui/oauth/TestAccessTokenTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/oauth/TestAccessTokenTask.java	(revision 6905)
+++ trunk/src/org/openstreetmap/josm/gui/oauth/TestAccessTokenTask.java	(revision 6906)
@@ -25,5 +25,4 @@
 import org.openstreetmap.josm.gui.help.HelpUtil;
 import org.openstreetmap.josm.io.OsmApiException;
-import org.openstreetmap.josm.io.OsmDataParsingException;
 import org.openstreetmap.josm.io.OsmServerUserInfoReader;
 import org.openstreetmap.josm.io.OsmTransferException;
@@ -31,4 +30,5 @@
 import org.openstreetmap.josm.tools.CheckParameterUtil;
 import org.openstreetmap.josm.tools.Utils;
+import org.openstreetmap.josm.tools.XmlParsingException;
 import org.w3c.dom.Document;
 import org.xml.sax.SAXException;
@@ -98,5 +98,5 @@
     }
 
-    protected UserInfo getUserDetails() throws OsmOAuthAuthorizationException, OsmDataParsingException,OsmTransferException {
+    protected UserInfo getUserDetails() throws OsmOAuthAuthorizationException, XmlParsingException, OsmTransferException {
         boolean authenticatorEnabled = true;
         try {
@@ -124,7 +124,7 @@
             return OsmServerUserInfoReader.buildFromXML(d);
         } catch(SAXException e) {
-            throw new OsmDataParsingException(e);
+            throw new XmlParsingException(e);
         } catch(ParserConfigurationException e){
-            throw new OsmDataParsingException(e);
+            throw new XmlParsingException(e);
         } catch(MalformedURLException e) {
             throw new OsmTransferException(e);
Index: trunk/src/org/openstreetmap/josm/gui/preferences/plugin/PluginPreferencesModel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/plugin/PluginPreferencesModel.java	(revision 6905)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/plugin/PluginPreferencesModel.java	(revision 6906)
@@ -71,4 +71,8 @@
             availablePlugins.addAll(available);
         }
+        availablePluginsModified();
+    }
+
+    protected final void availablePluginsModified() {
         sort();
         filterDisplayedPlugins(filterExpression);
@@ -86,5 +90,5 @@
     }
 
-    protected  void updateAvailablePlugin(PluginInformation other) {
+    protected void updateAvailablePlugin(PluginInformation other) {
         if (other == null) return;
         PluginInformation pi = getPluginInformation(other.name);
@@ -106,17 +110,5 @@
             updateAvailablePlugin(other);
         }
-        sort();
-        filterDisplayedPlugins(filterExpression);
-        Set<String> activePlugins = new HashSet<String>();
-        activePlugins.addAll(Main.pref.getCollection("plugins", activePlugins));
-        for (PluginInformation pi: availablePlugins) {
-            if (selectedPluginsMap.get(pi) == null) {
-                if (activePlugins.contains(pi.name)) {
-                    selectedPluginsMap.put(pi, true);
-                }
-            }
-        }
-        clearChanged();
-        notifyObservers();
+        availablePluginsModified();
     }
 
Index: trunk/src/org/openstreetmap/josm/io/DiffResultProcessor.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/DiffResultProcessor.java	(revision 6905)
+++ trunk/src/org/openstreetmap/josm/io/DiffResultProcessor.java	(revision 6906)
@@ -24,4 +24,5 @@
 import org.openstreetmap.josm.gui.progress.ProgressMonitor;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
+import org.openstreetmap.josm.tools.XmlParsingException;
 import org.xml.sax.Attributes;
 import org.xml.sax.InputSource;
@@ -71,9 +72,9 @@
      * @param diffUploadResponse the response. Must not be null.
      * @param progressMonitor a progress monitor. Defaults to {@link NullProgressMonitor#INSTANCE} if null
-     * @throws IllegalArgumentException thrown if diffUploadRequest is null
-     * @throws OsmDataParsingException thrown if the diffUploadRequest can't be parsed successfully
+     * @throws IllegalArgumentException if diffUploadRequest is null
+     * @throws XmlParsingException if the diffUploadRequest can't be parsed successfully
      *
      */
-    public  void parse(String diffUploadResponse, ProgressMonitor progressMonitor) throws OsmDataParsingException {
+    public  void parse(String diffUploadResponse, ProgressMonitor progressMonitor) throws XmlParsingException {
         if (progressMonitor == null) {
             progressMonitor = NullProgressMonitor.INSTANCE;
@@ -85,11 +86,11 @@
             SAXParserFactory.newInstance().newSAXParser().parse(inputSource, new Parser());
         } catch(IOException e) {
-            throw new OsmDataParsingException(e);
+            throw new XmlParsingException(e);
         } catch(ParserConfigurationException e) {
-            throw new OsmDataParsingException(e);
-        } catch(OsmDataParsingException e) {
+            throw new XmlParsingException(e);
+        } catch(XmlParsingException e) {
             throw e;
         } catch(SAXException e) {
-            throw new OsmDataParsingException(e);
+            throw new XmlParsingException(e);
         } finally {
             progressMonitor.finishTask();
@@ -147,6 +148,6 @@
         }
 
-        protected void throwException(String msg) throws OsmDataParsingException{
-            throw new OsmDataParsingException(msg).rememberLocation(locator);
+        protected void throwException(String msg) throws XmlParsingException {
+            throw new XmlParsingException(msg).rememberLocation(locator);
         }
 
@@ -173,5 +174,5 @@
                 }
             } catch (NumberFormatException e) {
-                throw new OsmDataParsingException(e).rememberLocation(locator);
+                throw new XmlParsingException(e).rememberLocation(locator);
             }
         }
Index: trunk/src/org/openstreetmap/josm/io/OsmApi.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OsmApi.java	(revision 6905)
+++ trunk/src/org/openstreetmap/josm/io/OsmApi.java	(revision 6906)
@@ -39,4 +39,5 @@
 import org.openstreetmap.josm.tools.CheckParameterUtil;
 import org.openstreetmap.josm.tools.Utils;
+import org.openstreetmap.josm.tools.XmlParsingException;
 import org.xml.sax.Attributes;
 import org.xml.sax.InputSource;
@@ -535,5 +536,5 @@
         } catch(OsmTransferException e) {
             throw e;
-        } catch(OsmDataParsingException e) {
+        } catch(XmlParsingException e) {
             throw new OsmTransferException(e);
         } finally {
Index: trunk/src/org/openstreetmap/josm/io/OsmChangesetContentParser.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OsmChangesetContentParser.java	(revision 6905)
+++ trunk/src/org/openstreetmap/josm/io/OsmChangesetContentParser.java	(revision 6906)
@@ -19,4 +19,5 @@
 import org.openstreetmap.josm.tools.CheckParameterUtil;
 import org.openstreetmap.josm.tools.Utils;
+import org.openstreetmap.josm.tools.XmlParsingException;
 import org.xml.sax.Attributes;
 import org.xml.sax.InputSource;
@@ -38,10 +39,10 @@
         private ChangesetDataSet.ChangesetModificationType currentModificationType;
 
-        protected void throwException(String message) throws OsmDataParsingException {
-            throw new OsmDataParsingException(message).rememberLocation(locator);
+        protected void throwException(String message) throws XmlParsingException {
+            throw new XmlParsingException(message).rememberLocation(locator);
         }
 
-        protected void throwException(Exception e) throws OsmDataParsingException {
-            throw new OsmDataParsingException(e).rememberLocation(locator);
+        protected void throwException(Exception e) throws XmlParsingException {
+            throw new XmlParsingException(e).rememberLocation(locator);
         }
 
@@ -128,8 +129,8 @@
      * @param progressMonitor the progress monitor. Set to {@link NullProgressMonitor#INSTANCE} if null
      * @return the parsed data
-     * @throws OsmDataParsingException thrown if something went wrong. Check for chained
+     * @throws XmlParsingException if something went wrong. Check for chained
      * exceptions.
      */
-    public ChangesetDataSet parse(ProgressMonitor progressMonitor) throws OsmDataParsingException {
+    public ChangesetDataSet parse(ProgressMonitor progressMonitor) throws XmlParsingException {
         if (progressMonitor == null) {
             progressMonitor = NullProgressMonitor.INSTANCE;
@@ -139,12 +140,12 @@
             progressMonitor.indeterminateSubTask(tr("Parsing changeset content ..."));
             SAXParserFactory.newInstance().newSAXParser().parse(source, new Parser());
-        } catch(OsmDataParsingException e){
+        } catch(XmlParsingException e) {
             throw e;
         } catch (ParserConfigurationException e) {
-            throw new OsmDataParsingException(e);
+            throw new XmlParsingException(e);
         } catch(SAXException e) {
-            throw new OsmDataParsingException(e);
+            throw new XmlParsingException(e);
         } catch(IOException e) {
-            throw new OsmDataParsingException(e);
+            throw new XmlParsingException(e);
         } finally {
             progressMonitor.finishTask();
@@ -157,8 +158,8 @@
      *
      * @return the parsed data
-     * @throws OsmDataParsingException thrown if something went wrong. Check for chained
+     * @throws XmlParsingException if something went wrong. Check for chained
      * exceptions.
      */
-    public ChangesetDataSet parse() throws OsmDataParsingException {
+    public ChangesetDataSet parse() throws XmlParsingException {
         return parse(null);
     }
Index: trunk/src/org/openstreetmap/josm/io/OsmChangesetParser.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OsmChangesetParser.java	(revision 6905)
+++ trunk/src/org/openstreetmap/josm/io/OsmChangesetParser.java	(revision 6906)
@@ -19,4 +19,5 @@
 import org.openstreetmap.josm.tools.DateUtils;
 import org.openstreetmap.josm.tools.Utils;
+import org.openstreetmap.josm.tools.XmlParsingException;
 import org.xml.sax.Attributes;
 import org.xml.sax.InputSource;
@@ -46,4 +47,8 @@
     }
 
+    /**
+     * Returns the parsed changesets.
+     * @return the parsed changesets
+     */
     public List<Changeset> getChangesets() {
         return changesets;
@@ -58,13 +63,12 @@
         }
 
-        protected void throwException(String msg) throws OsmDataParsingException{
-            throw new OsmDataParsingException(msg).rememberLocation(locator);
-        }
-        /**
-         * The current changeset
-         */
+        protected void throwException(String msg) throws XmlParsingException {
+            throw new XmlParsingException(msg).rememberLocation(locator);
+        }
+
+        /** The current changeset */
         private Changeset current = null;
 
-        protected void parseChangesetAttributes(Changeset cs, Attributes atts) throws OsmDataParsingException {
+        protected void parseChangesetAttributes(Changeset cs, Attributes atts) throws XmlParsingException {
             // -- id
             String value = atts.getValue("id");
@@ -186,5 +190,5 @@
         }
 
-        protected User createUser(String uid, String name) throws OsmDataParsingException {
+        protected User createUser(String uid, String name) throws XmlParsingException {
             if (uid == null) {
                 if (name == null)
Index: trunk/src/org/openstreetmap/josm/io/OsmDataParsingException.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OsmDataParsingException.java	(revision 6905)
+++ 	(revision )
@@ -1,55 +1,0 @@
-// License: GPL. For details, see LICENSE file.
-package org.openstreetmap.josm.io;
-
-import static org.openstreetmap.josm.tools.I18n.tr;
-
-import org.xml.sax.Locator;
-import org.xml.sax.SAXException;
-
-public class OsmDataParsingException extends SAXException {
-    private int columnNumber;
-    private int lineNumber;
-
-    public OsmDataParsingException() {
-        super();
-    }
-
-    public OsmDataParsingException(Exception e) {
-        super(e);
-    }
-
-    public OsmDataParsingException(String message, Exception e) {
-        super(message, e);
-    }
-
-    public OsmDataParsingException(String message) {
-        super(message);
-    }
-
-    public OsmDataParsingException rememberLocation(Locator locator) {
-        if (locator == null) return this;
-        this.columnNumber = locator.getColumnNumber();
-        this.lineNumber = locator.getLineNumber();
-        return this;
-    }
-
-    @Override
-    public String getMessage() {
-        String msg = super.getMessage();
-        if (lineNumber == 0 && columnNumber == 0)
-            return msg;
-        if (msg == null) {
-            msg = getClass().getName();
-        }
-        msg = msg + " " + tr("(at line {0}, column {1})", lineNumber, columnNumber);
-        return msg;
-    }
-
-    public int getColumnNumber() {
-        return columnNumber;
-    }
-
-    public int getLineNumber() {
-        return lineNumber;
-    }
-}
Index: trunk/src/org/openstreetmap/josm/io/OsmServerChangesetReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OsmServerChangesetReader.java	(revision 6905)
+++ trunk/src/org/openstreetmap/josm/io/OsmServerChangesetReader.java	(revision 6906)
@@ -18,4 +18,5 @@
 import org.openstreetmap.josm.gui.progress.ProgressMonitor;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
+import org.openstreetmap.josm.tools.XmlParsingException;
 
 /**
@@ -182,5 +183,5 @@
             OsmChangesetContentParser parser = new OsmChangesetContentParser(in);
             return parser.parse(monitor.createSubTaskMonitor(1, true));
-        } catch(OsmDataParsingException e) {
+        } catch(XmlParsingException e) {
             throw new OsmTransferException(e);
         } finally {
Index: trunk/src/org/openstreetmap/josm/io/OsmServerUserInfoReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OsmServerUserInfoReader.java	(revision 6905)
+++ trunk/src/org/openstreetmap/josm/io/OsmServerUserInfoReader.java	(revision 6906)
@@ -19,4 +19,5 @@
 import org.openstreetmap.josm.gui.progress.ProgressMonitor;
 import org.openstreetmap.josm.tools.DateUtils;
+import org.openstreetmap.josm.tools.XmlParsingException;
 import org.w3c.dom.Document;
 import org.w3c.dom.Node;
@@ -33,7 +34,7 @@
      * @param document The XML contents
      * @return The user info
-     * @throws OsmDataParsingException if parsing goes wrong
+     * @throws XmlParsingException if parsing goes wrong
      */
-    public static UserInfo buildFromXML(Document document) throws OsmDataParsingException {
+    public static UserInfo buildFromXML(Document document) throws XmlParsingException {
         try {
             XPathFactory factory = XPathFactory.newInstance();
@@ -42,14 +43,14 @@
             Node xmlNode = (Node)xpath.compile("/osm/user[1]").evaluate(document, XPathConstants.NODE);
             if ( xmlNode== null)
-                throw new OsmDataParsingException(tr("XML tag <user> is missing."));
+                throw new XmlParsingException(tr("XML tag <user> is missing."));
 
             // -- id
             String v = getAttribute(xmlNode, "id");
             if (v == null)
-                throw new OsmDataParsingException(tr("Missing attribute ''{0}'' on XML tag ''{1}''.", "id", "user"));
+                throw new XmlParsingException(tr("Missing attribute ''{0}'' on XML tag ''{1}''.", "id", "user"));
             try {
                 userInfo.setId(Integer.parseInt(v));
             } catch(NumberFormatException e) {
-                throw new OsmDataParsingException(tr("Illegal value for attribute ''{0}'' on XML tag ''{1}''. Got {2}.", "id", "user", v));
+                throw new XmlParsingException(tr("Illegal value for attribute ''{0}'' on XML tag ''{1}''. Got {2}.", "id", "user", v));
             }
             // -- display name
@@ -71,30 +72,30 @@
                 v = getAttribute(xmlNode, "lat");
                 if (v == null)
-                    throw new OsmDataParsingException(tr("Missing attribute ''{0}'' on XML tag ''{1}''.", "lat", "home"));
+                    throw new XmlParsingException(tr("Missing attribute ''{0}'' on XML tag ''{1}''.", "lat", "home"));
                 double lat;
                 try {
                     lat = Double.parseDouble(v);
                 } catch(NumberFormatException e) {
-                    throw new OsmDataParsingException(tr("Illegal value for attribute ''{0}'' on XML tag ''{1}''. Got {2}.", "lat", "home", v));
+                    throw new XmlParsingException(tr("Illegal value for attribute ''{0}'' on XML tag ''{1}''. Got {2}.", "lat", "home", v));
                 }
 
                 v = getAttribute(xmlNode, "lon");
                 if (v == null)
-                    throw new OsmDataParsingException(tr("Missing attribute ''{0}'' on XML tag ''{1}''.", "lon", "home"));
+                    throw new XmlParsingException(tr("Missing attribute ''{0}'' on XML tag ''{1}''.", "lon", "home"));
                 double lon;
                 try {
                     lon = Double.parseDouble(v);
                 } catch(NumberFormatException e) {
-                    throw new OsmDataParsingException(tr("Illegal value for attribute ''{0}'' on XML tag ''{1}''. Got {2}.", "lon", "home", v));
+                    throw new XmlParsingException(tr("Illegal value for attribute ''{0}'' on XML tag ''{1}''. Got {2}.", "lon", "home", v));
                 }
 
                 v = getAttribute(xmlNode, "zoom");
                 if (v == null)
-                    throw new OsmDataParsingException(tr("Missing attribute ''{0}'' on XML tag ''{1}''.", "zoom", "home"));
+                    throw new XmlParsingException(tr("Missing attribute ''{0}'' on XML tag ''{1}''.", "zoom", "home"));
                 int zoom;
                 try {
                     zoom = Integer.parseInt(v);
                 } catch(NumberFormatException e) {
-                    throw new OsmDataParsingException(tr("Illegal value for attribute ''{0}'' on XML tag ''{1}''. Got {2}.", "zoom", "home", v));
+                    throw new XmlParsingException(tr("Illegal value for attribute ''{0}'' on XML tag ''{1}''. Got {2}.", "zoom", "home", v));
                 }
                 userInfo.setHome(new LatLon(lat,lon));
@@ -117,9 +118,9 @@
                 v = getAttribute(xmlNode, "unread");
                 if (v == null)
-                    throw new OsmDataParsingException(tr("Missing attribute ''{0}'' on XML tag ''{1}''.", "unread", "received"));
+                    throw new XmlParsingException(tr("Missing attribute ''{0}'' on XML tag ''{1}''.", "unread", "received"));
                 try {
                     userInfo.setUnreadMessages(Integer.parseInt(v));
                 } catch(NumberFormatException e) {
-                    throw new OsmDataParsingException(tr("Illegal value for attribute ''{0}'' on XML tag ''{1}''. Got {2}.", "unread", "received", v), e);
+                    throw new XmlParsingException(tr("Illegal value for attribute ''{0}'' on XML tag ''{1}''. Got {2}.", "unread", "received", v), e);
                 }
             }
@@ -127,5 +128,5 @@
             return userInfo;
         } catch(XPathException e) {
-            throw new OsmDataParsingException(e);
+            throw new XmlParsingException(e);
         }
     }
Index: trunk/src/org/openstreetmap/josm/plugins/ReadLocalPluginInformationTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/plugins/ReadLocalPluginInformationTask.java	(revision 6905)
+++ trunk/src/org/openstreetmap/josm/plugins/ReadLocalPluginInformationTask.java	(revision 6906)
@@ -40,4 +40,7 @@
     private boolean canceled;
 
+    /**
+     * Constructs a new {@code ReadLocalPluginInformationTask}.
+     */
     public ReadLocalPluginInformationTask() {
         super(tr("Reading local plugin information.."), false);
@@ -72,13 +75,17 @@
     }
 
-    protected void scanSiteCacheFiles(ProgressMonitor monitor, File pluginsDirectory) {
-        File[] siteCacheFiles = pluginsDirectory.listFiles(
+    private File[] listFiles(File pluginsDirectory, final String regex) {
+        return pluginsDirectory.listFiles(
                 new FilenameFilter() {
                     @Override
                     public boolean accept(File dir, String name) {
-                        return name.matches("^([0-9]+-)?site.*\\.txt$");
+                        return name.matches(regex);
                     }
                 }
         );
+    }
+
+    protected void scanSiteCacheFiles(ProgressMonitor monitor, File pluginsDirectory) {
+        File[] siteCacheFiles = listFiles(pluginsDirectory, "^([0-9]+-)?site.*\\.txt$");
         if (siteCacheFiles == null || siteCacheFiles.length == 0)
             return;
@@ -97,14 +104,6 @@
         }
     }
-
     protected void scanIconCacheFiles(ProgressMonitor monitor, File pluginsDirectory) {
-        File[] siteCacheFiles = pluginsDirectory.listFiles(
-                new FilenameFilter() {
-                    @Override
-                    public boolean accept(File dir, String name) {
-                        return name.matches("^([0-9]+-)?site.*plugin-icons\\.zip$");
-                    }
-                }
-        );
+        File[] siteCacheFiles = listFiles(pluginsDirectory, "^([0-9]+-)?site.*plugin-icons\\.zip$");
         if (siteCacheFiles == null || siteCacheFiles.length == 0)
             return;
Index: trunk/src/org/openstreetmap/josm/tools/XmlObjectParser.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/XmlObjectParser.java	(revision 6905)
+++ trunk/src/org/openstreetmap/josm/tools/XmlObjectParser.java	(revision 6906)
@@ -43,55 +43,4 @@
  */
 public class XmlObjectParser implements Iterable<Object> {
-    public static class PresetParsingException extends SAXException {
-        private int columnNumber;
-        private int lineNumber;
-
-        /**
-         * Constructs a new {@code PresetParsingException}.
-         */
-        public PresetParsingException() {
-            super();
-        }
-
-        public PresetParsingException(Exception e) {
-            super(e);
-        }
-
-        public PresetParsingException(String message, Exception e) {
-            super(message, e);
-        }
-
-        public PresetParsingException(String message) {
-            super(message);
-        }
-
-        public PresetParsingException rememberLocation(Locator locator) {
-            if (locator == null) return this;
-            this.columnNumber = locator.getColumnNumber();
-            this.lineNumber = locator.getLineNumber();
-            return this;
-        }
-
-        @Override
-        public String getMessage() {
-            String msg = super.getMessage();
-            if (lineNumber == 0 && columnNumber == 0)
-                return msg;
-            if (msg == null) {
-                msg = getClass().getName();
-            }
-            msg = msg + " " + tr("(at line {0}, column {1})", lineNumber, columnNumber);
-            return msg;
-        }
-
-        public int getColumnNumber() {
-            return columnNumber;
-        }
-
-        public int getLineNumber() {
-            return lineNumber;
-        }
-    }
-
     public static final String lang = LanguageInfo.getLanguageCodeXML();
 
@@ -127,9 +76,10 @@
         }
 
-        protected void throwException(Exception e) throws PresetParsingException{
-            throw new PresetParsingException(e).rememberLocation(locator);
-        }
-
-        @Override public void startElement(String ns, String lname, String qname, Attributes a) throws SAXException {
+        protected void throwException(Exception e) throws XmlParsingException {
+            throw new XmlParsingException(e).rememberLocation(locator);
+        }
+
+        @Override
+        public void startElement(String ns, String lname, String qname, Attributes a) throws SAXException {
             if (mapping.containsKey(qname)) {
                 Class<?> klass = mapping.get(qname).klass;
@@ -150,5 +100,7 @@
             }
         }
-        @Override public void endElement(String ns, String lname, String qname) throws SAXException {
+
+        @Override
+        public void endElement(String ns, String lname, String qname) throws SAXException {
             if (mapping.containsKey(qname) && !mapping.get(qname).onStart) {
                 report();
@@ -158,5 +110,7 @@
             }
         }
-        @Override public void characters(char[] ch, int start, int length) {
+
+        @Override
+        public void characters(char[] ch, int start, int length) {
             characters.append(ch, start, length);
         }
@@ -281,4 +235,7 @@
     private Iterator<Object> queueIterator = null;
 
+    /**
+     * Constructs a new {@code XmlObjectParser}.
+     */
     public XmlObjectParser() {
         parser = new Parser();
Index: trunk/src/org/openstreetmap/josm/tools/XmlParsingException.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/XmlParsingException.java	(revision 6906)
+++ trunk/src/org/openstreetmap/josm/tools/XmlParsingException.java	(revision 6906)
@@ -0,0 +1,82 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.tools;
+
+import static org.openstreetmap.josm.tools.I18n.tr;
+
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+
+/**
+ * An exception thrown during XML parsing, with known line and column.
+ * @since 6906
+ */
+public class XmlParsingException extends SAXException {
+    private int columnNumber;
+    private int lineNumber;
+
+    /**
+     * Constructs a new {@code XmlParsingException}.
+     * @param e The cause
+     */
+    public XmlParsingException(Exception e) {
+        super(e);
+    }
+
+    /**
+     * Constructs a new {@code XmlParsingException}.
+     * @param message The error message
+     * @param e The cause
+     */
+    public XmlParsingException(String message, Exception e) {
+        super(message, e);
+    }
+
+    /**
+     * Constructs a new {@code XmlParsingException}.
+     * @param message The error message
+     */
+    public XmlParsingException(String message) {
+        super(message);
+    }
+
+    /**
+     * Sets the location (line/column) where the exception occured.
+     * @param locator object giving the location (line/column) where the exception occured
+     * @return {@code this}
+     */
+    public XmlParsingException rememberLocation(Locator locator) {
+        if (locator != null) {
+            this.columnNumber = locator.getColumnNumber();
+            this.lineNumber = locator.getLineNumber();
+        }
+        return this;
+    }
+
+    @Override
+    public String getMessage() {
+        String msg = super.getMessage();
+        if (lineNumber == 0 && columnNumber == 0)
+            return msg;
+        if (msg == null) {
+            msg = getClass().getName();
+        }
+        msg = msg + " " + tr("(at line {0}, column {1})", lineNumber, columnNumber);
+        return msg;
+    }
+
+    /**
+     * Returns the column number where the exception occured.
+     * @return the column number where the exception occured
+     */
+    public int getColumnNumber() {
+        return columnNumber;
+    }
+
+    /**
+     * Returns the line number where the exception occured.
+     * @return the line number where the exception occured
+     */
+    public int getLineNumber() {
+        return lineNumber;
+    }
+}
